aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/shaders/SkPictureShader.cpp
diff options
context:
space:
mode:
authorGravatar Stan Iliev <stani@google.com>2017-05-25 22:07:16 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-05-25 22:30:19 +0000
commitd8872be505c5c9c48072fe62c244e53e9b7334f1 (patch)
treeef6ae54d394f1bf0794393c42129811b93d0f6be /src/shaders/SkPictureShader.cpp
parent5b474d36238e38642add8d4b54cb9ac80935262b (diff)
Revert "Relocate shaders to own dir"
This reverts commit fabe0b26d05624ce7374f6ca89bd66df6142534e. Reason for revert: Last android roll failed with "external/skia/src/effects/SkGaussianEdgeShader.h:11:10: fatal error: 'SkShaderBase.h' file not found" Original change's description: > Relocate shaders to own dir > > Consolidate all shader impls under src/shaders/. > > Change-Id: I450e37541214704c1ad9e379d9d753b7cc62fac3 > Reviewed-on: https://skia-review.googlesource.com/17927 > Commit-Queue: Florin Malita <fmalita@chromium.org> > Reviewed-by: Herb Derby <herb@google.com> > TBR=mtklein@google.com,herb@google.com,fmalita@chromium.org,reed@google.com No-Presubmit: true No-Tree-Checks: true No-Try: true Change-Id: Idbb2b75053969df1dad9d8ce0217cd39189b9ddb Reviewed-on: https://skia-review.googlesource.com/18020 Reviewed-by: Stan Iliev <stani@google.com> Commit-Queue: Stan Iliev <stani@google.com>
Diffstat (limited to 'src/shaders/SkPictureShader.cpp')
-rw-r--r--src/shaders/SkPictureShader.cpp364
1 files changed, 0 insertions, 364 deletions
diff --git a/src/shaders/SkPictureShader.cpp b/src/shaders/SkPictureShader.cpp
deleted file mode 100644
index d6ee941251..0000000000
--- a/src/shaders/SkPictureShader.cpp
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkPictureShader.h"
-
-#include "SkArenaAlloc.h"
-#include "SkBitmap.h"
-#include "SkBitmapProcShader.h"
-#include "SkCanvas.h"
-#include "SkColorSpaceXformCanvas.h"
-#include "SkImage.h"
-#include "SkImageShader.h"
-#include "SkMatrixUtils.h"
-#include "SkPicture.h"
-#include "SkPictureImageGenerator.h"
-#include "SkReadBuffer.h"
-#include "SkResourceCache.h"
-
-#if SK_SUPPORT_GPU
-#include "GrContext.h"
-#include "GrCaps.h"
-#include "GrFragmentProcessor.h"
-#endif
-
-namespace {
-static unsigned gBitmapSkaderKeyNamespaceLabel;
-
-struct BitmapShaderKey : public SkResourceCache::Key {
-public:
- BitmapShaderKey(sk_sp<SkColorSpace> colorSpace,
- uint32_t pictureID,
- const SkRect& tile,
- SkShader::TileMode tmx,
- SkShader::TileMode tmy,
- const SkSize& scale,
- const SkMatrix& localMatrix,
- SkTransferFunctionBehavior blendBehavior)
- : fColorSpace(std::move(colorSpace))
- , fPictureID(pictureID)
- , fTile(tile)
- , fTmx(tmx)
- , fTmy(tmy)
- , fScale(scale)
- , fBlendBehavior(blendBehavior) {
-
- for (int i = 0; i < 9; ++i) {
- fLocalMatrixStorage[i] = localMatrix[i];
- }
-
- static const size_t keySize = sizeof(fColorSpace) +
- sizeof(fPictureID) +
- sizeof(fTile) +
- sizeof(fTmx) + sizeof(fTmy) +
- sizeof(fScale) +
- sizeof(fLocalMatrixStorage) +
- sizeof(fBlendBehavior);
- // This better be packed.
- SkASSERT(sizeof(uint32_t) * (&fEndOfStruct - (uint32_t*)&fColorSpace) == keySize);
- this->init(&gBitmapSkaderKeyNamespaceLabel, 0, keySize);
- }
-
-private:
- sk_sp<SkColorSpace> fColorSpace;
- uint32_t fPictureID;
- SkRect fTile;
- SkShader::TileMode fTmx, fTmy;
- SkSize fScale;
- SkScalar fLocalMatrixStorage[9];
- SkTransferFunctionBehavior fBlendBehavior;
-
- SkDEBUGCODE(uint32_t fEndOfStruct;)
-};
-
-struct BitmapShaderRec : public SkResourceCache::Rec {
- BitmapShaderRec(const BitmapShaderKey& key, SkShader* tileShader)
- : fKey(key)
- , fShader(SkRef(tileShader)) {}
-
- BitmapShaderKey fKey;
- sk_sp<SkShader> fShader;
- size_t fBitmapBytes;
-
- const Key& getKey() const override { return fKey; }
- size_t bytesUsed() const override {
- // Just the record overhead -- the actual pixels are accounted by SkImageCacherator.
- return sizeof(fKey) + sizeof(SkImageShader);
- }
- const char* getCategory() const override { return "bitmap-shader"; }
- SkDiscardableMemory* diagnostic_only_getDiscardable() const override { return nullptr; }
-
- static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextShader) {
- const BitmapShaderRec& rec = static_cast<const BitmapShaderRec&>(baseRec);
- sk_sp<SkShader>* result = reinterpret_cast<sk_sp<SkShader>*>(contextShader);
-
- *result = rec.fShader;
-
- // The bitmap shader is backed by an image generator, thus it can always re-generate its
- // pixels if discarded.
- return true;
- }
-};
-
-} // namespace
-
-SkPictureShader::SkPictureShader(sk_sp<SkPicture> picture, TileMode tmx, TileMode tmy,
- const SkMatrix* localMatrix, const SkRect* tile,
- sk_sp<SkColorSpace> colorSpace)
- : INHERITED(localMatrix)
- , fPicture(std::move(picture))
- , fTile(tile ? *tile : fPicture->cullRect())
- , fTmx(tmx)
- , fTmy(tmy)
- , fColorSpace(std::move(colorSpace))
-{}
-
-sk_sp<SkShader> SkPictureShader::Make(sk_sp<SkPicture> picture, TileMode tmx, TileMode tmy,
- const SkMatrix* localMatrix, const SkRect* tile) {
- if (!picture || picture->cullRect().isEmpty() || (tile && tile->isEmpty())) {
- return SkShader::MakeEmptyShader();
- }
- return sk_sp<SkShader>(new SkPictureShader(std::move(picture), tmx, tmy, localMatrix, tile,
- nullptr));
-}
-
-sk_sp<SkFlattenable> SkPictureShader::CreateProc(SkReadBuffer& buffer) {
- SkMatrix lm;
- buffer.readMatrix(&lm);
- TileMode mx = (TileMode)buffer.read32();
- TileMode my = (TileMode)buffer.read32();
- SkRect tile;
- buffer.readRect(&tile);
-
- sk_sp<SkPicture> picture;
-
- if (buffer.isCrossProcess() && SkPicture::PictureIOSecurityPrecautionsEnabled()) {
- if (buffer.isVersionLT(SkReadBuffer::kPictureShaderHasPictureBool_Version)) {
- // Older code blindly serialized pictures. We don't trust them.
- buffer.validate(false);
- return nullptr;
- }
- // Newer code won't serialize pictures in disallow-cross-process-picture mode.
- // Assert that they didn't serialize anything except a false here.
- buffer.validate(!buffer.readBool());
- } else {
- // Old code always serialized the picture. New code writes a 'true' first if it did.
- if (buffer.isVersionLT(SkReadBuffer::kPictureShaderHasPictureBool_Version) ||
- buffer.readBool()) {
- picture = SkPicture::MakeFromBuffer(buffer);
- }
- }
- return SkPictureShader::Make(picture, mx, my, &lm, &tile);
-}
-
-void SkPictureShader::flatten(SkWriteBuffer& buffer) const {
- buffer.writeMatrix(this->getLocalMatrix());
- buffer.write32(fTmx);
- buffer.write32(fTmy);
- buffer.writeRect(fTile);
-
- // The deserialization code won't trust that our serialized picture is safe to deserialize.
- // So write a 'false' telling it that we're not serializing a picture.
- if (buffer.isCrossProcess() && SkPicture::PictureIOSecurityPrecautionsEnabled()) {
- buffer.writeBool(false);
- } else {
- buffer.writeBool(true);
- fPicture->flatten(buffer);
- }
-}
-
-sk_sp<SkShader> SkPictureShader::refBitmapShader(const SkMatrix& viewMatrix, const SkMatrix* localM,
- SkColorSpace* dstColorSpace,
- const int maxTextureSize) const {
- SkASSERT(fPicture && !fPicture->cullRect().isEmpty());
-
- SkMatrix m;
- m.setConcat(viewMatrix, this->getLocalMatrix());
- if (localM) {
- m.preConcat(*localM);
- }
-
- // Use a rotation-invariant scale
- SkPoint scale;
- //
- // TODO: replace this with decomposeScale() -- but beware LayoutTest rebaselines!
- //
- if (!SkDecomposeUpper2x2(m, nullptr, &scale, nullptr)) {
- // Decomposition failed, use an approximation.
- scale.set(SkScalarSqrt(m.getScaleX() * m.getScaleX() + m.getSkewX() * m.getSkewX()),
- SkScalarSqrt(m.getScaleY() * m.getScaleY() + m.getSkewY() * m.getSkewY()));
- }
- SkSize scaledSize = SkSize::Make(SkScalarAbs(scale.x() * fTile.width()),
- SkScalarAbs(scale.y() * fTile.height()));
-
- // Clamp the tile size to about 4M pixels
- static const SkScalar kMaxTileArea = 2048 * 2048;
- SkScalar tileArea = scaledSize.width() * scaledSize.height();
- if (tileArea > kMaxTileArea) {
- SkScalar clampScale = SkScalarSqrt(kMaxTileArea / tileArea);
- scaledSize.set(scaledSize.width() * clampScale,
- scaledSize.height() * clampScale);
- }
-#if SK_SUPPORT_GPU
- // Scale down the tile size if larger than maxTextureSize for GPU Path or it should fail on create texture
- if (maxTextureSize) {
- if (scaledSize.width() > maxTextureSize || scaledSize.height() > maxTextureSize) {
- SkScalar downScale = maxTextureSize / SkMaxScalar(scaledSize.width(), scaledSize.height());
- scaledSize.set(SkScalarFloorToScalar(scaledSize.width() * downScale),
- SkScalarFloorToScalar(scaledSize.height() * downScale));
- }
- }
-#endif
-
-#ifdef SK_SUPPORT_LEGACY_PICTURESHADER_ROUNDING
- const SkISize tileSize = scaledSize.toRound();
-#else
- const SkISize tileSize = scaledSize.toCeil();
-#endif
- if (tileSize.isEmpty()) {
- return SkShader::MakeEmptyShader();
- }
-
- // The actual scale, compensating for rounding & clamping.
- const SkSize tileScale = SkSize::Make(SkIntToScalar(tileSize.width()) / fTile.width(),
- SkIntToScalar(tileSize.height()) / fTile.height());
-
- // |fColorSpace| will only be set when using an SkColorSpaceXformCanvas to do pre-draw xforms.
- // This canvas is strictly for legacy mode. A non-null |dstColorSpace| indicates that we
- // should perform color correct rendering and xform at draw time.
- SkASSERT(!fColorSpace || !dstColorSpace);
- sk_sp<SkColorSpace> keyCS = dstColorSpace ? sk_ref_sp(dstColorSpace) : fColorSpace;
- SkTransferFunctionBehavior blendBehavior = dstColorSpace ? SkTransferFunctionBehavior::kRespect
- : SkTransferFunctionBehavior::kIgnore;
-
- sk_sp<SkShader> tileShader;
- BitmapShaderKey key(std::move(keyCS),
- fPicture->uniqueID(),
- fTile,
- fTmx,
- fTmy,
- tileScale,
- this->getLocalMatrix(),
- blendBehavior);
-
- if (!SkResourceCache::Find(key, BitmapShaderRec::Visitor, &tileShader)) {
- SkMatrix tileMatrix;
- tileMatrix.setRectToRect(fTile, SkRect::MakeIWH(tileSize.width(), tileSize.height()),
- SkMatrix::kFill_ScaleToFit);
-
- sk_sp<SkImage> tileImage = SkImage::MakeFromGenerator(
- SkPictureImageGenerator::Make(tileSize, fPicture, &tileMatrix, nullptr,
- SkImage::BitDepth::kU8, sk_ref_sp(dstColorSpace)));
- if (!tileImage) {
- return nullptr;
- }
-
- if (fColorSpace) {
- tileImage = tileImage->makeColorSpace(fColorSpace, SkTransferFunctionBehavior::kIgnore);
- }
-
- SkMatrix shaderMatrix = this->getLocalMatrix();
- shaderMatrix.preScale(1 / tileScale.width(), 1 / tileScale.height());
- tileShader = tileImage->makeShader(fTmx, fTmy, &shaderMatrix);
-
- SkResourceCache::Add(new BitmapShaderRec(key, tileShader.get()));
- }
-
- return tileShader;
-}
-
-bool SkPictureShader::onAppendStages(SkRasterPipeline* p, SkColorSpace* cs, SkArenaAlloc* alloc,
- const SkMatrix& ctm, const SkPaint& paint,
- const SkMatrix* localMatrix) const {
- // Keep bitmapShader alive by using alloc instead of stack memory
- auto& bitmapShader = *alloc->make<sk_sp<SkShader>>();
- bitmapShader = this->refBitmapShader(ctm, localMatrix, cs);
- return bitmapShader && as_SB(bitmapShader)->appendStages(p, cs, alloc, ctm, paint);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-SkShaderBase::Context* SkPictureShader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc)
-const {
- sk_sp<SkShader> bitmapShader(this->refBitmapShader(*rec.fMatrix, rec.fLocalMatrix,
- rec.fDstColorSpace));
- if (!bitmapShader) {
- return nullptr;
- }
-
- PictureShaderContext* ctx =
- alloc->make<PictureShaderContext>(*this, rec, std::move(bitmapShader), alloc);
- if (nullptr == ctx->fBitmapShaderContext) {
- ctx = nullptr;
- }
- return ctx;
-}
-
-sk_sp<SkShader> SkPictureShader::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
- return sk_sp<SkPictureShader>(new SkPictureShader(fPicture, fTmx, fTmy, &this->getLocalMatrix(),
- &fTile, xformer->dst()));
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-SkPictureShader::PictureShaderContext::PictureShaderContext(
- const SkPictureShader& shader, const ContextRec& rec, sk_sp<SkShader> bitmapShader,
- SkArenaAlloc* alloc)
- : INHERITED(shader, rec)
- , fBitmapShader(std::move(bitmapShader))
-{
- fBitmapShaderContext = as_SB(fBitmapShader)->makeContext(rec, alloc);
- //if fBitmapShaderContext is null, we are invalid
-}
-
-uint32_t SkPictureShader::PictureShaderContext::getFlags() const {
- SkASSERT(fBitmapShaderContext);
- return fBitmapShaderContext->getFlags();
-}
-
-SkShaderBase::Context::ShadeProc SkPictureShader::PictureShaderContext::asAShadeProc(void** ctx) {
- SkASSERT(fBitmapShaderContext);
- return fBitmapShaderContext->asAShadeProc(ctx);
-}
-
-void SkPictureShader::PictureShaderContext::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
- SkASSERT(fBitmapShaderContext);
- fBitmapShaderContext->shadeSpan(x, y, dstC, count);
-}
-
-#ifndef SK_IGNORE_TO_STRING
-void SkPictureShader::toString(SkString* str) const {
- static const char* gTileModeName[SkShader::kTileModeCount] = {
- "clamp", "repeat", "mirror"
- };
-
- str->appendf("PictureShader: [%f:%f:%f:%f] ",
- fPicture->cullRect().fLeft,
- fPicture->cullRect().fTop,
- fPicture->cullRect().fRight,
- fPicture->cullRect().fBottom);
-
- str->appendf("(%s, %s)", gTileModeName[fTmx], gTileModeName[fTmy]);
-
- this->INHERITED::toString(str);
-}
-#endif
-
-#if SK_SUPPORT_GPU
-sk_sp<GrFragmentProcessor> SkPictureShader::asFragmentProcessor(const AsFPArgs& args) const {
- int maxTextureSize = 0;
- if (args.fContext) {
- maxTextureSize = args.fContext->caps()->maxTextureSize();
- }
- sk_sp<SkShader> bitmapShader(this->refBitmapShader(*args.fViewMatrix, args.fLocalMatrix,
- args.fDstColorSpace, maxTextureSize));
- if (!bitmapShader) {
- return nullptr;
- }
- return as_SB(bitmapShader)->asFragmentProcessor(SkShaderBase::AsFPArgs(
- args.fContext, args.fViewMatrix, nullptr, args.fFilterQuality, args.fDstColorSpace));
-}
-#endif