LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkComposeShader.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 105 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             :  */
       7             : 
       8             : #include "SkArenaAlloc.h"
       9             : #include "SkComposeShader.h"
      10             : #include "SkColorFilter.h"
      11             : #include "SkColorPriv.h"
      12             : #include "SkColorShader.h"
      13             : #include "SkReadBuffer.h"
      14             : #include "SkWriteBuffer.h"
      15             : #include "SkString.h"
      16             : 
      17           0 : sk_sp<SkShader> SkShader::MakeComposeShader(sk_sp<SkShader> dst, sk_sp<SkShader> src,
      18             :                                             SkBlendMode mode) {
      19           0 :     if (!src || !dst) {
      20           0 :         return nullptr;
      21             :     }
      22           0 :     if (SkBlendMode::kSrc == mode) {
      23           0 :         return src;
      24             :     }
      25           0 :     if (SkBlendMode::kDst == mode) {
      26           0 :         return dst;
      27             :     }
      28           0 :     return sk_sp<SkShader>(new SkComposeShader(std::move(dst), std::move(src), mode));
      29             : }
      30             : 
      31             : ///////////////////////////////////////////////////////////////////////////////
      32             : 
      33             : class SkAutoAlphaRestore {
      34             : public:
      35             :     SkAutoAlphaRestore(SkPaint* paint, uint8_t newAlpha) {
      36             :         fAlpha = paint->getAlpha();
      37             :         fPaint = paint;
      38             :         paint->setAlpha(newAlpha);
      39             :     }
      40             : 
      41             :     ~SkAutoAlphaRestore() {
      42             :         fPaint->setAlpha(fAlpha);
      43             :     }
      44             : private:
      45             :     SkPaint*    fPaint;
      46             :     uint8_t     fAlpha;
      47             : };
      48             : #define SkAutoAlphaRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoAlphaRestore)
      49             : 
      50           0 : sk_sp<SkFlattenable> SkComposeShader::CreateProc(SkReadBuffer& buffer) {
      51           0 :     sk_sp<SkShader> shaderA(buffer.readShader());
      52           0 :     sk_sp<SkShader> shaderB(buffer.readShader());
      53             :     SkBlendMode mode;
      54           0 :     if (buffer.isVersionLT(SkReadBuffer::kXfermodeToBlendMode2_Version)) {
      55           0 :         sk_sp<SkXfermode> xfer = buffer.readXfermode();
      56           0 :         mode = xfer ? xfer->blend() : SkBlendMode::kSrcOver;
      57             :     } else {
      58           0 :         mode = (SkBlendMode)buffer.read32();
      59             :     }
      60           0 :     if (!shaderA || !shaderB) {
      61           0 :         return nullptr;
      62             :     }
      63           0 :     return sk_make_sp<SkComposeShader>(std::move(shaderA), std::move(shaderB), mode);
      64             : }
      65             : 
      66           0 : void SkComposeShader::flatten(SkWriteBuffer& buffer) const {
      67           0 :     buffer.writeFlattenable(fShaderA.get());
      68           0 :     buffer.writeFlattenable(fShaderB.get());
      69           0 :     buffer.write32((int)fMode);
      70           0 : }
      71             : 
      72           0 : SkShader::Context* SkComposeShader::onMakeContext(
      73             :     const ContextRec& rec, SkArenaAlloc* alloc) const
      74             : {
      75             :     // we preconcat our localMatrix (if any) with the device matrix
      76             :     // before calling our sub-shaders
      77             :     SkMatrix tmpM;
      78           0 :     tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix());
      79             : 
      80             :     // Our sub-shaders need to see opaque, so by combining them we don't double-alphatize the
      81             :     // result. ComposeShader itself will respect the alpha, and post-apply it after calling the
      82             :     // sub-shaders.
      83           0 :     SkPaint opaquePaint(*rec.fPaint);
      84           0 :     opaquePaint.setAlpha(0xFF);
      85             : 
      86           0 :     ContextRec newRec(rec);
      87           0 :     newRec.fMatrix = &tmpM;
      88           0 :     newRec.fPaint = &opaquePaint;
      89             : 
      90           0 :     SkShader::Context* contextA = fShaderA->makeContext(newRec, alloc);
      91           0 :     SkShader::Context* contextB = fShaderB->makeContext(newRec, alloc);
      92           0 :     if (!contextA || !contextB) {
      93           0 :         return nullptr;
      94             :     }
      95             : 
      96           0 :     return alloc->make<ComposeShaderContext>(*this, rec, contextA, contextB);
      97             : }
      98             : 
      99           0 : SkComposeShader::ComposeShaderContext::ComposeShaderContext(
     100             :         const SkComposeShader& shader, const ContextRec& rec,
     101           0 :         SkShader::Context* contextA, SkShader::Context* contextB)
     102             :     : INHERITED(shader, rec)
     103             :     , fShaderContextA(contextA)
     104           0 :     , fShaderContextB(contextB) {}
     105             : 
     106           0 : bool SkComposeShader::asACompose(ComposeRec* rec) const {
     107           0 :     if (rec) {
     108           0 :         rec->fShaderA   = fShaderA.get();
     109           0 :         rec->fShaderB   = fShaderB.get();
     110           0 :         rec->fBlendMode = fMode;
     111             :     }
     112           0 :     return true;
     113             : }
     114             : 
     115             : 
     116             : // larger is better (fewer times we have to loop), but we shouldn't
     117             : // take up too much stack-space (each element is 4 bytes)
     118             : #define TMP_COLOR_COUNT     64
     119             : 
     120           0 : void SkComposeShader::ComposeShaderContext::shadeSpan(int x, int y, SkPMColor result[], int count) {
     121           0 :     SkShader::Context* shaderContextA = fShaderContextA;
     122           0 :     SkShader::Context* shaderContextB = fShaderContextB;
     123           0 :     SkBlendMode        mode = static_cast<const SkComposeShader&>(fShader).fMode;
     124           0 :     unsigned           scale = SkAlpha255To256(this->getPaintAlpha());
     125             : 
     126             :     SkPMColor   tmp[TMP_COLOR_COUNT];
     127             : 
     128           0 :     SkXfermode* xfer = SkXfermode::Peek(mode);
     129           0 :     if (nullptr == xfer) {   // implied SRC_OVER
     130             :         // TODO: when we have a good test-case, should use SkBlitRow::Proc32
     131             :         // for these loops
     132           0 :         do {
     133           0 :             int n = count;
     134           0 :             if (n > TMP_COLOR_COUNT) {
     135           0 :                 n = TMP_COLOR_COUNT;
     136             :             }
     137             : 
     138           0 :             shaderContextA->shadeSpan(x, y, result, n);
     139           0 :             shaderContextB->shadeSpan(x, y, tmp, n);
     140             : 
     141           0 :             if (256 == scale) {
     142           0 :                 for (int i = 0; i < n; i++) {
     143           0 :                     result[i] = SkPMSrcOver(tmp[i], result[i]);
     144             :                 }
     145             :             } else {
     146           0 :                 for (int i = 0; i < n; i++) {
     147           0 :                     result[i] = SkAlphaMulQ(SkPMSrcOver(tmp[i], result[i]),
     148             :                                             scale);
     149             :                 }
     150             :             }
     151             : 
     152           0 :             result += n;
     153           0 :             x += n;
     154           0 :             count -= n;
     155           0 :         } while (count > 0);
     156             :     } else {    // use mode for the composition
     157           0 :         do {
     158           0 :             int n = count;
     159           0 :             if (n > TMP_COLOR_COUNT) {
     160           0 :                 n = TMP_COLOR_COUNT;
     161             :             }
     162             : 
     163           0 :             shaderContextA->shadeSpan(x, y, result, n);
     164           0 :             shaderContextB->shadeSpan(x, y, tmp, n);
     165           0 :             xfer->xfer32(result, tmp, n, nullptr);
     166             : 
     167           0 :             if (256 != scale) {
     168           0 :                 for (int i = 0; i < n; i++) {
     169           0 :                     result[i] = SkAlphaMulQ(result[i], scale);
     170             :                 }
     171             :             }
     172             : 
     173           0 :             result += n;
     174           0 :             x += n;
     175           0 :             count -= n;
     176           0 :         } while (count > 0);
     177             :     }
     178           0 : }
     179             : 
     180             : #if SK_SUPPORT_GPU
     181             : 
     182             : #include "effects/GrConstColorProcessor.h"
     183             : #include "effects/GrXfermodeFragmentProcessor.h"
     184             : 
     185             : /////////////////////////////////////////////////////////////////////
     186             : 
     187           0 : sk_sp<GrFragmentProcessor> SkComposeShader::asFragmentProcessor(const AsFPArgs& args) const {
     188           0 :     switch (fMode) {
     189             :         case SkBlendMode::kClear:
     190             :             return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(),
     191           0 :                                                GrConstColorProcessor::kIgnore_InputMode);
     192             :             break;
     193             :         case SkBlendMode::kSrc:
     194           0 :             return fShaderB->asFragmentProcessor(args);
     195             :             break;
     196             :         case SkBlendMode::kDst:
     197           0 :             return fShaderA->asFragmentProcessor(args);
     198             :             break;
     199             :         default:
     200           0 :             sk_sp<GrFragmentProcessor> fpA(fShaderA->asFragmentProcessor(args));
     201           0 :             if (!fpA) {
     202           0 :                 return nullptr;
     203             :             }
     204           0 :             sk_sp<GrFragmentProcessor> fpB(fShaderB->asFragmentProcessor(args));
     205           0 :             if (!fpB) {
     206           0 :                 return nullptr;
     207             :             }
     208           0 :             return GrXfermodeFragmentProcessor::MakeFromTwoProcessors(std::move(fpB),
     209           0 :                                                                       std::move(fpA), fMode);
     210             :     }
     211             : }
     212             : #endif
     213             : 
     214             : #ifndef SK_IGNORE_TO_STRING
     215           0 : void SkComposeShader::toString(SkString* str) const {
     216           0 :     str->append("SkComposeShader: (");
     217             : 
     218           0 :     str->append("ShaderA: ");
     219           0 :     fShaderA->toString(str);
     220           0 :     str->append(" ShaderB: ");
     221           0 :     fShaderB->toString(str);
     222           0 :     if (SkBlendMode::kSrcOver != fMode) {
     223           0 :         str->appendf(" Xfermode: %s", SkXfermode::ModeName(fMode));
     224             :     }
     225             : 
     226           0 :     this->INHERITED::toString(str);
     227             : 
     228           0 :     str->append(")");
     229           0 : }
     230             : #endif

Generated by: LCOV version 1.13