LCOV - code coverage report
Current view: top level - gfx/2d - DrawTarget.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 107 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "2D.h"
       7             : #include "Logging.h"
       8             : #include "PathHelpers.h"
       9             : 
      10             : #include "DrawTargetCapture.h"
      11             : 
      12             : #ifdef BUILD_ARM_NEON
      13             : #include "mozilla/arm.h"
      14             : #include "LuminanceNEON.h"
      15             : #endif
      16             : 
      17             : namespace mozilla {
      18             : namespace gfx {
      19             : 
      20             : /**
      21             :  * Byte offsets of channels in a native packed gfxColor or cairo image surface.
      22             :  */
      23             : #ifdef IS_BIG_ENDIAN
      24             : #define GFX_ARGB32_OFFSET_A 0
      25             : #define GFX_ARGB32_OFFSET_R 1
      26             : #define GFX_ARGB32_OFFSET_G 2
      27             : #define GFX_ARGB32_OFFSET_B 3
      28             : #else
      29             : #define GFX_ARGB32_OFFSET_A 3
      30             : #define GFX_ARGB32_OFFSET_R 2
      31             : #define GFX_ARGB32_OFFSET_G 1
      32             : #define GFX_ARGB32_OFFSET_B 0
      33             : #endif
      34             : 
      35             : // c = n / 255
      36             : // c <= 0.04045 ? c / 12.92 : pow((c + 0.055) / 1.055, 2.4)) * 255 + 0.5
      37             : static const uint8_t gsRGBToLinearRGBMap[256] = {
      38             :   0,   0,   0,   0,   0,   0,   0,   1,
      39             :   1,   1,   1,   1,   1,   1,   1,   1,
      40             :   1,   1,   2,   2,   2,   2,   2,   2,
      41             :   2,   2,   3,   3,   3,   3,   3,   3,
      42             :   4,   4,   4,   4,   4,   5,   5,   5,
      43             :   5,   6,   6,   6,   6,   7,   7,   7,
      44             :   8,   8,   8,   8,   9,   9,   9,  10,
      45             :  10,  10,  11,  11,  12,  12,  12,  13,
      46             :  13,  13,  14,  14,  15,  15,  16,  16,
      47             :  17,  17,  17,  18,  18,  19,  19,  20,
      48             :  20,  21,  22,  22,  23,  23,  24,  24,
      49             :  25,  25,  26,  27,  27,  28,  29,  29,
      50             :  30,  30,  31,  32,  32,  33,  34,  35,
      51             :  35,  36,  37,  37,  38,  39,  40,  41,
      52             :  41,  42,  43,  44,  45,  45,  46,  47,
      53             :  48,  49,  50,  51,  51,  52,  53,  54,
      54             :  55,  56,  57,  58,  59,  60,  61,  62,
      55             :  63,  64,  65,  66,  67,  68,  69,  70,
      56             :  71,  72,  73,  74,  76,  77,  78,  79,
      57             :  80,  81,  82,  84,  85,  86,  87,  88,
      58             :  90,  91,  92,  93,  95,  96,  97,  99,
      59             : 100, 101, 103, 104, 105, 107, 108, 109,
      60             : 111, 112, 114, 115, 116, 118, 119, 121,
      61             : 122, 124, 125, 127, 128, 130, 131, 133,
      62             : 134, 136, 138, 139, 141, 142, 144, 146,
      63             : 147, 149, 151, 152, 154, 156, 157, 159,
      64             : 161, 163, 164, 166, 168, 170, 171, 173,
      65             : 175, 177, 179, 181, 183, 184, 186, 188,
      66             : 190, 192, 194, 196, 198, 200, 202, 204,
      67             : 206, 208, 210, 212, 214, 216, 218, 220,
      68             : 222, 224, 226, 229, 231, 233, 235, 237,
      69             : 239, 242, 244, 246, 248, 250, 253, 255
      70             : };
      71             : 
      72             : static void
      73           0 : ComputesRGBLuminanceMask(const uint8_t *aSourceData,
      74             :                          int32_t aSourceStride,
      75             :                          uint8_t *aDestData,
      76             :                          int32_t aDestStride,
      77             :                          const IntSize &aSize,
      78             :                          float aOpacity)
      79             : {
      80             : #ifdef BUILD_ARM_NEON
      81             :   if (mozilla::supports_neon()) {
      82             :     ComputesRGBLuminanceMask_NEON(aSourceData, aSourceStride,
      83             :                                   aDestData, aDestStride,
      84             :                                   aSize, aOpacity);
      85             :     return;
      86             :   }
      87             : #endif
      88             : 
      89           0 :   int32_t redFactor = 55 * aOpacity; // 255 * 0.2125 * opacity
      90           0 :   int32_t greenFactor = 183 * aOpacity; // 255 * 0.7154 * opacity
      91           0 :   int32_t blueFactor = 18 * aOpacity; // 255 * 0.0721
      92           0 :   int32_t sourceOffset = aSourceStride - 4 * aSize.width;
      93           0 :   const uint8_t *sourcePixel = aSourceData;
      94           0 :   int32_t destOffset = aDestStride - aSize.width;
      95           0 :   uint8_t *destPixel = aDestData;
      96             : 
      97           0 :   for (int32_t y = 0; y < aSize.height; y++) {
      98           0 :     for (int32_t x = 0; x < aSize.width; x++) {
      99           0 :       uint8_t a = sourcePixel[GFX_ARGB32_OFFSET_A];
     100             : 
     101           0 :       if (a) {
     102           0 :         *destPixel = (redFactor * sourcePixel[GFX_ARGB32_OFFSET_R] +
     103           0 :                       greenFactor * sourcePixel[GFX_ARGB32_OFFSET_G] +
     104           0 :                       blueFactor * sourcePixel[GFX_ARGB32_OFFSET_B]) >> 8;
     105             :       } else {
     106           0 :         *destPixel = 0;
     107             :       }
     108           0 :       sourcePixel += 4;
     109           0 :       destPixel++;
     110             :     }
     111           0 :     sourcePixel += sourceOffset;
     112           0 :     destPixel += destOffset;
     113             :   }
     114           0 : }
     115             : 
     116             : static void
     117           0 : ComputeLinearRGBLuminanceMask(const uint8_t *aSourceData,
     118             :                               int32_t aSourceStride,
     119             :                               uint8_t *aDestData,
     120             :                               int32_t aDestStride,
     121             :                               const IntSize &aSize,
     122             :                               float aOpacity)
     123             : {
     124           0 :   int32_t redFactor = 55 * aOpacity; // 255 * 0.2125 * opacity
     125           0 :   int32_t greenFactor = 183 * aOpacity; // 255 * 0.7154 * opacity
     126           0 :   int32_t blueFactor = 18 * aOpacity; // 255 * 0.0721
     127           0 :   int32_t sourceOffset = aSourceStride - 4 * aSize.width;
     128           0 :   const uint8_t *sourcePixel = aSourceData;
     129           0 :   int32_t destOffset = aDestStride - aSize.width;
     130           0 :   uint8_t *destPixel = aDestData;
     131             : 
     132           0 :   for (int32_t y = 0; y < aSize.height; y++) {
     133           0 :     for (int32_t x = 0; x < aSize.width; x++) {
     134           0 :       uint8_t a = sourcePixel[GFX_ARGB32_OFFSET_A];
     135             : 
     136             :       // unpremultiply
     137           0 :       if (a) {
     138           0 :         if (a == 255) {
     139             :           /* sRGB -> linearRGB -> intensity */
     140           0 :           *destPixel =
     141             :             static_cast<uint8_t>
     142           0 :                        ((gsRGBToLinearRGBMap[sourcePixel[GFX_ARGB32_OFFSET_R]] *
     143           0 :                          redFactor +
     144           0 :                          gsRGBToLinearRGBMap[sourcePixel[GFX_ARGB32_OFFSET_G]] *
     145           0 :                          greenFactor +
     146           0 :                          gsRGBToLinearRGBMap[sourcePixel[GFX_ARGB32_OFFSET_B]] *
     147           0 :                          blueFactor) >> 8);
     148             :         } else {
     149             :           uint8_t tempPixel[4];
     150           0 :           tempPixel[GFX_ARGB32_OFFSET_B] =
     151           0 :             (255 * sourcePixel[GFX_ARGB32_OFFSET_B]) / a;
     152           0 :           tempPixel[GFX_ARGB32_OFFSET_G] =
     153           0 :             (255 * sourcePixel[GFX_ARGB32_OFFSET_G]) / a;
     154           0 :           tempPixel[GFX_ARGB32_OFFSET_R] =
     155           0 :             (255 * sourcePixel[GFX_ARGB32_OFFSET_R]) / a;
     156             : 
     157             :           /* sRGB -> linearRGB -> intensity */
     158           0 :           *destPixel =
     159           0 :             static_cast<uint8_t>
     160           0 :                        (((gsRGBToLinearRGBMap[tempPixel[GFX_ARGB32_OFFSET_R]] *
     161           0 :                           redFactor +
     162           0 :                           gsRGBToLinearRGBMap[tempPixel[GFX_ARGB32_OFFSET_G]] *
     163           0 :                           greenFactor +
     164           0 :                           gsRGBToLinearRGBMap[tempPixel[GFX_ARGB32_OFFSET_B]] *
     165           0 :                           blueFactor) >> 8) * (a / 255.0f));
     166             :         }
     167             :       } else {
     168           0 :         *destPixel = 0;
     169             :       }
     170           0 :       sourcePixel += 4;
     171           0 :       destPixel++;
     172             :     }
     173           0 :     sourcePixel += sourceOffset;
     174           0 :     destPixel += destOffset;
     175             :   }
     176           0 : }
     177             : 
     178             : already_AddRefed<DrawTargetCapture>
     179           0 : DrawTarget::CreateCaptureDT(const IntSize& aSize)
     180             : {
     181           0 :   RefPtr<DrawTargetCaptureImpl> dt = new DrawTargetCaptureImpl();
     182             : 
     183           0 :   if (!dt->Init(aSize, this)) {
     184           0 :     gfxWarning() << "Failed to initialize Capture DrawTarget!";
     185           0 :     return nullptr;
     186             :   }
     187             : 
     188           0 :   return dt.forget();
     189             : }
     190             : 
     191             : void
     192           0 : DrawTarget::DrawCapturedDT(DrawTargetCapture *aCaptureDT,
     193             :                            const Matrix& aTransform)
     194             : {
     195           0 :   if (aTransform.HasNonIntegerTranslation()) {
     196           0 :     gfxWarning() << "Non integer translations are not supported for DrawCaptureDT at this time!";
     197           0 :     return;
     198             :   }
     199           0 :   static_cast<DrawTargetCaptureImpl*>(aCaptureDT)->ReplayToDrawTarget(this, aTransform);
     200             : }
     201             : 
     202             : void
     203           0 : DrawTarget::PushDeviceSpaceClipRects(const IntRect* aRects, uint32_t aCount)
     204             : {
     205           0 :   Matrix oldTransform = GetTransform();
     206           0 :   SetTransform(Matrix());
     207             : 
     208           0 :   RefPtr<PathBuilder> pathBuilder = CreatePathBuilder();
     209           0 :   for (uint32_t i = 0; i < aCount; i++) {
     210           0 :     AppendRectToPath(pathBuilder, Rect(aRects[i]));
     211             :   }
     212           0 :   RefPtr<Path> path = pathBuilder->Finish();
     213           0 :   PushClip(path);
     214             : 
     215           0 :   SetTransform(oldTransform);
     216           0 : }
     217             : 
     218             : void
     219           0 : DrawTarget::StrokeGlyphs(ScaledFont* aFont,
     220             :                          const GlyphBuffer& aBuffer,
     221             :                          const Pattern& aPattern,
     222             :                          const StrokeOptions& aStrokeOptions,
     223             :                          const DrawOptions& aOptions,
     224             :                          const GlyphRenderingOptions* aRenderingOptions)
     225             : {
     226           0 :   RefPtr<Path> path = aFont->GetPathForGlyphs(aBuffer, this);
     227           0 :   Stroke(path, aPattern, aStrokeOptions, aOptions);
     228           0 : }
     229             : 
     230             : already_AddRefed<SourceSurface>
     231           0 : DrawTarget::IntoLuminanceSource(LuminanceType aMaskType, float aOpacity)
     232             : {
     233           0 :   RefPtr<SourceSurface> surface = Snapshot();
     234           0 :   IntSize size = surface->GetSize();
     235             : 
     236           0 :   RefPtr<DataSourceSurface> maskSurface = surface->GetDataSurface();
     237             :   DataSourceSurface::MappedSurface map;
     238           0 :   if (!maskSurface->Map(DataSourceSurface::MapType::READ, &map)) {
     239           0 :     return nullptr;
     240             :   }
     241             : 
     242             :   // Create alpha channel mask for output
     243             :   RefPtr<DataSourceSurface> destMaskSurface =
     244           0 :     Factory::CreateDataSourceSurface(size, SurfaceFormat::A8);
     245           0 :   if (!destMaskSurface) {
     246           0 :     return nullptr;
     247             :   }
     248             :   DataSourceSurface::MappedSurface destMap;
     249           0 :   if (!destMaskSurface->Map(DataSourceSurface::MapType::WRITE, &destMap)) {
     250           0 :     return nullptr;
     251             :   }
     252             : 
     253           0 :   switch (aMaskType) {
     254             :     case LuminanceType::LUMINANCE:
     255             :     {
     256           0 :       ComputesRGBLuminanceMask(map.mData, map.mStride,
     257             :                                destMap.mData, destMap.mStride,
     258           0 :                                size, aOpacity);
     259           0 :       break;
     260             :     }
     261             :     case LuminanceType::LINEARRGB:
     262             :     {
     263           0 :       ComputeLinearRGBLuminanceMask(map.mData, map.mStride,
     264             :                                     destMap.mData, destMap.mStride,
     265           0 :                                     size, aOpacity);
     266           0 :       break;
     267             :     }
     268             :   }
     269             : 
     270           0 :   maskSurface->Unmap();
     271           0 :   destMaskSurface->Unmap();
     272             : 
     273           0 :   return destMaskSurface.forget();
     274             : }
     275             : 
     276             : } // namespace gfx
     277             : } // namespace mozilla

Generated by: LCOV version 1.13