gfx/skia/trunk/src/core/SkShader.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /*
     2  * Copyright 2006 The Android Open Source Project
     3  *
     4  * Use of this source code is governed by a BSD-style license that can be
     5  * found in the LICENSE file.
     6  */
     8 #include "SkBitmapProcShader.h"
     9 #include "SkReadBuffer.h"
    10 #include "SkMallocPixelRef.h"
    11 #include "SkPaint.h"
    12 #include "SkScalar.h"
    13 #include "SkShader.h"
    14 #include "SkWriteBuffer.h"
    16 SkShader::SkShader() {
    17     fLocalMatrix.reset();
    18     SkDEBUGCODE(fInSetContext = false;)
    19 }
    21 SkShader::SkShader(SkReadBuffer& buffer)
    22         : INHERITED(buffer) {
    23     if (buffer.readBool()) {
    24         buffer.readMatrix(&fLocalMatrix);
    25     } else {
    26         fLocalMatrix.reset();
    27     }
    29     SkDEBUGCODE(fInSetContext = false;)
    30 }
    32 SkShader::~SkShader() {
    33     SkASSERT(!fInSetContext);
    34 }
    36 void SkShader::flatten(SkWriteBuffer& buffer) const {
    37     this->INHERITED::flatten(buffer);
    38     bool hasLocalM = this->hasLocalMatrix();
    39     buffer.writeBool(hasLocalM);
    40     if (hasLocalM) {
    41         buffer.writeMatrix(fLocalMatrix);
    42     }
    43 }
    45 bool SkShader::setContext(const SkBitmap& device,
    46                           const SkPaint& paint,
    47                           const SkMatrix& matrix) {
    48     SkASSERT(!this->setContextHasBeenCalled());
    50     const SkMatrix* m = &matrix;
    51     SkMatrix        total;
    53     fPaintAlpha = paint.getAlpha();
    54     if (this->hasLocalMatrix()) {
    55         total.setConcat(matrix, this->getLocalMatrix());
    56         m = &total;
    57     }
    58     if (m->invert(&fTotalInverse)) {
    59         fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse);
    60         SkDEBUGCODE(fInSetContext = true;)
    61         return true;
    62     }
    63     return false;
    64 }
    66 void SkShader::endContext() {
    67     SkASSERT(fInSetContext);
    68     SkDEBUGCODE(fInSetContext = false;)
    69 }
    71 SkShader::ShadeProc SkShader::asAShadeProc(void** ctx) {
    72     return NULL;
    73 }
    75 #include "SkColorPriv.h"
    77 void SkShader::shadeSpan16(int x, int y, uint16_t span16[], int count) {
    78     SkASSERT(span16);
    79     SkASSERT(count > 0);
    80     SkASSERT(this->canCallShadeSpan16());
    82     // basically, if we get here, the subclass screwed up
    83     SkDEBUGFAIL("kHasSpan16 flag is set, but shadeSpan16() not implemented");
    84 }
    86 #define kTempColorQuadCount 6   // balance between speed (larger) and saving stack-space
    87 #define kTempColorCount     (kTempColorQuadCount << 2)
    89 #ifdef SK_CPU_BENDIAN
    90     #define SkU32BitShiftToByteOffset(shift)    (3 - ((shift) >> 3))
    91 #else
    92     #define SkU32BitShiftToByteOffset(shift)    ((shift) >> 3)
    93 #endif
    95 void SkShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
    96     SkASSERT(count > 0);
    98     SkPMColor   colors[kTempColorCount];
   100     while ((count -= kTempColorCount) >= 0) {
   101         this->shadeSpan(x, y, colors, kTempColorCount);
   102         x += kTempColorCount;
   104         const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
   105         int quads = kTempColorQuadCount;
   106         do {
   107             U8CPU a0 = srcA[0];
   108             U8CPU a1 = srcA[4];
   109             U8CPU a2 = srcA[8];
   110             U8CPU a3 = srcA[12];
   111             srcA += 4*4;
   112             *alpha++ = SkToU8(a0);
   113             *alpha++ = SkToU8(a1);
   114             *alpha++ = SkToU8(a2);
   115             *alpha++ = SkToU8(a3);
   116         } while (--quads != 0);
   117     }
   118     SkASSERT(count < 0);
   119     SkASSERT(count + kTempColorCount >= 0);
   120     if (count += kTempColorCount) {
   121         this->shadeSpan(x, y, colors, count);
   123         const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
   124         do {
   125             *alpha++ = *srcA;
   126             srcA += 4;
   127         } while (--count != 0);
   128     }
   129 #if 0
   130     do {
   131         int n = count;
   132         if (n > kTempColorCount)
   133             n = kTempColorCount;
   134         SkASSERT(n > 0);
   136         this->shadeSpan(x, y, colors, n);
   137         x += n;
   138         count -= n;
   140         const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
   141         do {
   142             *alpha++ = *srcA;
   143             srcA += 4;
   144         } while (--n != 0);
   145     } while (count > 0);
   146 #endif
   147 }
   149 SkShader::MatrixClass SkShader::ComputeMatrixClass(const SkMatrix& mat) {
   150     MatrixClass mc = kLinear_MatrixClass;
   152     if (mat.hasPerspective()) {
   153         if (mat.fixedStepInX(0, NULL, NULL)) {
   154             mc = kFixedStepInX_MatrixClass;
   155         } else {
   156             mc = kPerspective_MatrixClass;
   157         }
   158     }
   159     return mc;
   160 }
   162 //////////////////////////////////////////////////////////////////////////////
   164 SkShader::BitmapType SkShader::asABitmap(SkBitmap*, SkMatrix*,
   165                                          TileMode*) const {
   166     return kNone_BitmapType;
   167 }
   169 SkShader::GradientType SkShader::asAGradient(GradientInfo* info) const {
   170     return kNone_GradientType;
   171 }
   173 GrEffectRef* SkShader::asNewEffect(GrContext*, const SkPaint&) const {
   174     return NULL;
   175 }
   177 SkShader* SkShader::CreateBitmapShader(const SkBitmap& src,
   178                                        TileMode tmx, TileMode tmy) {
   179     return ::CreateBitmapShader(src, tmx, tmy, NULL);
   180 }
   182 #ifndef SK_IGNORE_TO_STRING
   183 void SkShader::toString(SkString* str) const {
   184     if (this->hasLocalMatrix()) {
   185         str->append(" ");
   186         this->getLocalMatrix().toString(str);
   187     }
   188 }
   189 #endif
   191 //////////////////////////////////////////////////////////////////////////////
   193 #include "SkColorShader.h"
   194 #include "SkUtils.h"
   196 SkColorShader::SkColorShader() {
   197     fFlags = 0;
   198     fInheritColor = true;
   199 }
   201 SkColorShader::SkColorShader(SkColor c) {
   202     fFlags = 0;
   203     fColor = c;
   204     fInheritColor = false;
   205 }
   207 SkColorShader::~SkColorShader() {}
   209 bool SkColorShader::isOpaque() const {
   210     if (fInheritColor) {
   211         return true; // using paint's alpha
   212     }
   213     return SkColorGetA(fColor) == 255;
   214 }
   216 SkColorShader::SkColorShader(SkReadBuffer& b) : INHERITED(b) {
   217     fFlags = 0; // computed in setContext
   219     fInheritColor = b.readBool();
   220     if (fInheritColor) {
   221         return;
   222     }
   223     fColor = b.readColor();
   224 }
   226 void SkColorShader::flatten(SkWriteBuffer& buffer) const {
   227     this->INHERITED::flatten(buffer);
   228     buffer.writeBool(fInheritColor);
   229     if (fInheritColor) {
   230         return;
   231     }
   232     buffer.writeColor(fColor);
   233 }
   235 uint32_t SkColorShader::getFlags() {
   236     return fFlags;
   237 }
   239 uint8_t SkColorShader::getSpan16Alpha() const {
   240     return SkGetPackedA32(fPMColor);
   241 }
   243 bool SkColorShader::setContext(const SkBitmap& device, const SkPaint& paint,
   244                                const SkMatrix& matrix) {
   245     if (!this->INHERITED::setContext(device, paint, matrix)) {
   246         return false;
   247     }
   249     unsigned a;
   251     if (fInheritColor) {
   252         fColor = paint.getColor();
   253         a = SkColorGetA(fColor);
   254     } else {
   255         a = SkAlphaMul(SkColorGetA(fColor), SkAlpha255To256(paint.getAlpha()));
   256     }
   258     unsigned r = SkColorGetR(fColor);
   259     unsigned g = SkColorGetG(fColor);
   260     unsigned b = SkColorGetB(fColor);
   262     // we want this before we apply any alpha
   263     fColor16 = SkPack888ToRGB16(r, g, b);
   265     if (a != 255) {
   266         r = SkMulDiv255Round(r, a);
   267         g = SkMulDiv255Round(g, a);
   268         b = SkMulDiv255Round(b, a);
   269     }
   270     fPMColor = SkPackARGB32(a, r, g, b);
   272     fFlags = kConstInY32_Flag;
   273     if (255 == a) {
   274         fFlags |= kOpaqueAlpha_Flag;
   275         if (paint.isDither() == false) {
   276             fFlags |= kHasSpan16_Flag;
   277         }
   278     }
   280     return true;
   281 }
   283 void SkColorShader::shadeSpan(int x, int y, SkPMColor span[], int count) {
   284     sk_memset32(span, fPMColor, count);
   285 }
   287 void SkColorShader::shadeSpan16(int x, int y, uint16_t span[], int count) {
   288     sk_memset16(span, fColor16, count);
   289 }
   291 void SkColorShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
   292     memset(alpha, SkGetPackedA32(fPMColor), count);
   293 }
   295 // if we had a asAColor method, that would be more efficient...
   296 SkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix,
   297                                               TileMode modes[]) const {
   298     return kNone_BitmapType;
   299 }
   301 SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const {
   302     if (info) {
   303         if (info->fColors && info->fColorCount >= 1) {
   304             info->fColors[0] = fColor;
   305         }
   306         info->fColorCount = 1;
   307         info->fTileMode = SkShader::kRepeat_TileMode;
   308     }
   309     return kColor_GradientType;
   310 }
   312 #ifndef SK_IGNORE_TO_STRING
   313 void SkColorShader::toString(SkString* str) const {
   314     str->append("SkColorShader: (");
   316     if (fInheritColor) {
   317         str->append("Color: inherited from paint");
   318     } else {
   319         str->append("Color: ");
   320         str->appendHex(fColor);
   321     }
   323     this->INHERITED::toString(str);
   325     str->append(")");
   326 }
   327 #endif
   329 ///////////////////////////////////////////////////////////////////////////////
   331 #include "SkEmptyShader.h"
   333 uint32_t SkEmptyShader::getFlags() { return 0; }
   334 uint8_t SkEmptyShader::getSpan16Alpha() const { return 0; }
   336 bool SkEmptyShader::setContext(const SkBitmap&, const SkPaint&,
   337                                const SkMatrix&) { return false; }
   339 void SkEmptyShader::shadeSpan(int x, int y, SkPMColor span[], int count) {
   340     SkDEBUGFAIL("should never get called, since setContext() returned false");
   341 }
   343 void SkEmptyShader::shadeSpan16(int x, int y, uint16_t span[], int count) {
   344     SkDEBUGFAIL("should never get called, since setContext() returned false");
   345 }
   347 void SkEmptyShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
   348     SkDEBUGFAIL("should never get called, since setContext() returned false");
   349 }
   351 #ifndef SK_IGNORE_TO_STRING
   352 void SkEmptyShader::toString(SkString* str) const {
   353     str->append("SkEmptyShader: (");
   355     this->INHERITED::toString(str);
   357     str->append(")");
   358 }
   359 #endif

mercurial