diff options
author | 2015-09-10 14:33:38 -0700 | |
---|---|---|
committer | 2015-09-10 14:33:38 -0700 | |
commit | 85d9178832f4a64c9d80ffb14cb9dab4fe0fa54a (patch) | |
tree | 809af195b135b0118ce2e6b9f060bdf2f5dfbfbc /src/image | |
parent | e70afc9f48d00828ee6b707899a8ff542b0e8b98 (diff) |
Use SkImageCacherator in SkImages
Possible follow-up changes to consider
1. Roll SkImage_Raster and _Gpu into _Generator, where the generator (or cacherator) is backed by a pre-existing texture or raster.
2. Evolve SkImageUsageType into a verb requiring stretching, and have the caller (common code) digest the caps() and usage, so that subclasses are just told what to do (stretch or not)
3. Common code/utility to convert an unstretched texture into a stretch one (and cache it) if the generator can only make an unstretched one.
BUG=skia:
Review URL: https://codereview.chromium.org/1282363002
Diffstat (limited to 'src/image')
-rw-r--r-- | src/image/SkImage.cpp | 2 | ||||
-rw-r--r-- | src/image/SkImage_Base.h | 5 | ||||
-rw-r--r-- | src/image/SkImage_Generator.cpp | 95 | ||||
-rw-r--r-- | src/image/SkImage_Gpu.cpp | 5 | ||||
-rw-r--r-- | src/image/SkImage_Gpu.h | 4 | ||||
-rw-r--r-- | src/image/SkImage_Raster.cpp | 25 |
6 files changed, 121 insertions, 15 deletions
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp index 5a67c84caf..4315ad7e87 100644 --- a/src/image/SkImage.cpp +++ b/src/image/SkImage.cpp @@ -158,7 +158,7 @@ SkImage* SkImage::newImage(int newWidth, int newHeight, const SkIRect* subset, #if SK_SUPPORT_GPU GrTexture* SkImage::getTexture() const { - return as_IB(this)->getTexture(); + return as_IB(this)->peekTexture(); } bool SkImage::isTextureBacked() const { return SkToBool(as_IB(this)->getTexture()); } diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h index 01b39be383..8c9a73ba36 100644 --- a/src/image/SkImage_Base.h +++ b/src/image/SkImage_Base.h @@ -54,7 +54,7 @@ public: virtual void onPreroll(GrContext*) const {} - virtual GrTexture* getTexture() const { return nullptr; } + virtual GrTexture* peekTexture() const { return nullptr; } // return a read-only copy of the pixels. We promise to not modify them, // but only inspect them (or encode them). @@ -73,6 +73,9 @@ public: virtual bool onIsLazyGenerated() const { return false; } + // Caller must call unref when they are done. + virtual GrTexture* asTextureRef(GrContext*, SkImageUsageType) const { return nullptr; } + private: const SkSurfaceProps fProps; diff --git a/src/image/SkImage_Generator.cpp b/src/image/SkImage_Generator.cpp new file mode 100644 index 0000000000..731881c059 --- /dev/null +++ b/src/image/SkImage_Generator.cpp @@ -0,0 +1,95 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkImage_Base.h" +#include "SkBitmap.h" +#include "SkData.h" +#include "SkImageCacherator.h" +#include "SkImagePriv.h" +#include "SkPixelRef.h" +#include "SkSurface.h" + +class SkImage_Generator : public SkImage_Base { +public: + SkImage_Generator(SkImageCacherator* cache) + : INHERITED(cache->info().width(), cache->info().height(), kNeedNewImageUniqueID, NULL) + , fCache(cache) // take ownership + {} + + SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) const override; + bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY) const override; + const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const override; + SkData* onRefEncoded() const override; + bool isOpaque() const override { return fCache->info().isOpaque(); } + + bool getROPixels(SkBitmap*) const override; + GrTexture* asTextureRef(GrContext*, SkImageUsageType) const override; + + SkShader* onNewShader(SkShader::TileMode, + SkShader::TileMode, + const SkMatrix* localMatrix) const override; + + bool onIsLazyGenerated() const override { return true; } + +private: + SkAutoTDelete<SkImageCacherator> fCache; + + typedef SkImage_Base INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////// + +SkShader* SkImage_Generator::onNewShader(SkShader::TileMode tileX, SkShader::TileMode tileY, + const SkMatrix* localMatrix) const { + // TODO: need a native Shader that takes Cacherator (or this image) so we can natively return + // textures as output from the shader. + SkBitmap bm; + if (this->getROPixels(&bm)) { + return SkShader::CreateBitmapShader(bm, tileX, tileY, localMatrix); + } + return nullptr; +} + +SkSurface* SkImage_Generator::onNewSurface(const SkImageInfo& info, + const SkSurfaceProps& props) const { + return SkSurface::NewRaster(info, &props); +} + +bool SkImage_Generator::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB, + int srcX, int srcY) const { + SkBitmap bm; + if (this->getROPixels(&bm)) { + return bm.readPixels(dstInfo, dstPixels, dstRB, srcX, srcY); + } + return false; +} + +const void* SkImage_Generator::onPeekPixels(SkImageInfo* infoPtr, size_t* rowBytesPtr) const { + return NULL; +} + +SkData* SkImage_Generator::onRefEncoded() const { + return fCache->refEncoded(); +} + +bool SkImage_Generator::getROPixels(SkBitmap* bitmap) const { + return fCache->lockAsBitmap(bitmap); +} + +GrTexture* SkImage_Generator::asTextureRef(GrContext* ctx, SkImageUsageType usage) const { + return fCache->lockAsTexture(ctx, usage); +} + +#ifndef SK_SUPPORT_LEGACY_NEWFROMGENERATOR +SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator, const SkIRect* subset) { + SkImageCacherator* cache = SkImageCacherator::NewFromGenerator(generator, subset); + if (!cache) { + return nullptr; + } + return SkNEW_ARGS(SkImage_Generator, (cache)); +} +#endif diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index fdcb87136d..163e62e02d 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -79,6 +79,11 @@ bool SkImage_Gpu::getROPixels(SkBitmap* dst) const { return true; } +GrTexture* SkImage_Gpu::asTextureRef(GrContext* ctx, SkImageUsageType usage) const { + fTexture->ref(); + return fTexture; +} + bool SkImage_Gpu::isOpaque() const { return GrPixelConfigIsOpaque(fTexture->config()) || fAlphaType == kOpaque_SkAlphaType; } diff --git a/src/image/SkImage_Gpu.h b/src/image/SkImage_Gpu.h index 9481690714..d168fb6853 100644 --- a/src/image/SkImage_Gpu.h +++ b/src/image/SkImage_Gpu.h @@ -37,7 +37,9 @@ public: } bool getROPixels(SkBitmap*) const override; - GrTexture* getTexture() const override { return fTexture; } + GrTexture* asTextureRef(GrContext* ctx, SkImageUsageType usage) const override; + + GrTexture* peekTexture() const override { return fTexture; } SkShader* onNewShader(SkShader::TileMode, SkShader::TileMode, const SkMatrix* localMatrix) const override; diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp index 8afe7fd13a..5025dfa8c4 100644 --- a/src/image/SkImage_Raster.cpp +++ b/src/image/SkImage_Raster.cpp @@ -231,18 +231,6 @@ SkImage* SkImage::NewFromRaster(const SkImageInfo& info, const void* pixels, siz return new SkImage_Raster(info, data, rowBytes, ctable, nullptr); } -SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator, const SkIRect* subset) { - SkBitmap bitmap; - if (!SkInstallDiscardablePixelRef(generator, subset, &bitmap, nullptr)) { - return nullptr; - } - if (0 == bitmap.width() || 0 == bitmap.height()) { - return nullptr; - } - - return new SkImage_Raster(bitmap, nullptr); -} - SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr, const SkIPoint& pixelRefOrigin, size_t rowBytes, const SkSurfaceProps* props) { @@ -301,3 +289,16 @@ bool SkImage_Raster::onAsLegacyBitmap(SkBitmap* bitmap, LegacyBitmapMode mode) c } return this->INHERITED::onAsLegacyBitmap(bitmap, mode); } + +#ifdef SK_SUPPORT_LEGACY_NEWFROMGENERATOR +SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator, const SkIRect* subset) { + SkBitmap bitmap; + if (!SkInstallDiscardablePixelRef(generator, subset, &bitmap, nullptr)) { + return nullptr; + } + if (0 == bitmap.width() || 0 == bitmap.height()) { + return nullptr; + } + return new SkImage_Raster(bitmap, nullptr); +} +#endif |