Index: src/core/SkSpecialImage.cpp |
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..50945f88906e2606904ed6ce9adf5ed26773f290 |
--- /dev/null |
+++ b/src/core/SkSpecialImage.cpp |
@@ -0,0 +1,201 @@ |
+/* |
+ * Copyright 2016 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file |
+ */ |
+ |
+#include "SkCanvas.h" |
+#include "SkSpecialImage.h" |
+#include "SkSpecialSurface.h" |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+class SkSpecialImage_Base : public SkSpecialImage { |
bsalomon
2016/01/13 21:39:17
Wondering why the SpecialImage_Base/SpecialImage d
robertphillips
2016/01/14 14:43:59
Mainly b.c. it was based on SkImage, which has it,
|
+public: |
+ SkSpecialImage_Base(int width, int height) : INHERITED(width, height) { } |
+ virtual ~SkSpecialImage_Base() { } |
+ |
+ virtual void onDraw(SkCanvas*, int x, int y, const SkPaint*) const = 0; |
+ |
+ virtual const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const { return nullptr; } |
+ |
+ virtual GrTexture* onPeekTexture() const { return nullptr; } |
+ |
+ virtual SkSpecialSurface* onNewSurface(const SkImageInfo& info) const { return nullptr; } |
+ |
+private: |
+ typedef SkSpecialImage INHERITED; |
+}; |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+static inline const SkSpecialImage_Base* as_IB(const SkSpecialImage* image) { |
+ return static_cast<const SkSpecialImage_Base*>(image); |
+} |
+ |
+void SkSpecialImage::draw(SkCanvas* canvas, int x, int y, const SkPaint* paint) const { |
+ return as_IB(this)->onDraw(canvas, x, y, paint); |
+} |
+ |
+const void* SkSpecialImage::peekPixels(SkImageInfo* info, size_t* rowBytes) const { |
+ SkImageInfo infoStorage; |
+ size_t rowBytesStorage; |
+ if (!info) { |
+ info = &infoStorage; |
+ } |
+ if (!rowBytes) { |
+ rowBytes = &rowBytesStorage; |
+ } |
+ return as_IB(this)->onPeekPixels(info, rowBytes); |
+} |
+ |
+GrTexture* SkSpecialImage::peekTexture() const { |
+ return as_IB(this)->onPeekTexture(); |
+} |
+ |
+SkSpecialSurface* SkSpecialImage::newSurface(const SkImageInfo& info) const { |
+ return as_IB(this)->onNewSurface(info); |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+#include "SkImage.h" |
+ |
+class SkSpecialImage_Image : public SkSpecialImage_Base { |
+public: |
+ SkSpecialImage_Image(int width, int height, const SkImage* image) |
+ : INHERITED(width, height) |
+ , fImage(SkRef(image)) { |
+ } |
+ |
+ ~SkSpecialImage_Image() override { } |
+ |
+ void onDraw(SkCanvas* canvas, int x, int y, const SkPaint* paint) const override { |
+ SkRect dst = SkRect::MakeXYWH(x, y, this->width(), this->height()); |
+ |
+ canvas->drawImageRect(fImage, SkIRect::MakeWH(this->width(), this->height()), |
+ dst, paint, SkCanvas::kStrict_SrcRectConstraint); |
+ } |
+ |
+ const void* onPeekPixels(SkImageInfo* info, size_t* rowBytes) const override { |
+ return fImage->peekPixels(info, rowBytes); |
+ } |
+ |
+ GrTexture* onPeekTexture() const override { return fImage->getTexture(); } |
+ |
+ SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { |
+ return SkSpecialSurface::New(info, nullptr); |
+ } |
+ |
+private: |
+ SkAutoTUnref<const SkImage> fImage; |
+ |
+ typedef SkSpecialImage_Base INHERITED; |
+}; |
+ |
+SkSpecialImage* SkSpecialImage::New(int width, int height, const SkImage* image) { |
+ SkASSERT(width <= image->width() && height <= image->height()); |
+ return new SkSpecialImage_Image(width, height, image); |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+#include "SkBitmap.h" |
+#include "SkImageInfo.h" |
+#include "SkPixelRef.h" |
+ |
+class SkSpecialImage_Raster : public SkSpecialImage_Base { |
+public: |
+ SkSpecialImage_Raster(int width, int height, const SkBitmap& bm) |
+ : INHERITED(width, height) |
+ , fBitmap(bm) { |
+ if (bm.pixelRef()->isPreLocked()) { |
+ // we only preemptively lock if there is no chance of triggering something expensive |
+ // like a lazy decode or imagegenerator. PreLocked means it is flat pixels already. |
+ fBitmap.lockPixels(); |
+ } |
+ } |
+ |
+ ~SkSpecialImage_Raster() override { } |
+ |
+ void onDraw(SkCanvas* canvas, int x, int y, const SkPaint* paint) const override { |
+ SkRect dst = SkRect::MakeXYWH(x, y, this->width(), this->height()); |
+ |
+ canvas->drawBitmapRect(fBitmap, SkIRect::MakeWH(this->width(), this->height()), |
+ dst, paint, SkCanvas::kStrict_SrcRectConstraint); |
+ } |
+ |
+ const void* onPeekPixels(SkImageInfo* infoPtr, size_t* rowBytes) const override { |
+ const SkImageInfo info = fBitmap.info(); |
+ if ((kUnknown_SkColorType == info.colorType()) || !fBitmap.getPixels()) { |
+ return nullptr; |
+ } |
+ *infoPtr = info; |
+ *rowBytes = fBitmap.rowBytes(); |
+ return fBitmap.getPixels(); |
+ } |
+ |
+ SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { |
+ return SkSpecialSurface::New(info, nullptr); |
+ } |
+ |
+private: |
+ SkBitmap fBitmap; |
+ |
+ typedef SkSpecialImage_Base INHERITED; |
+}; |
+ |
+SkSpecialImage* SkSpecialImage::New(int width, int height, const SkBitmap& bm) { |
+ SkASSERT(nullptr == bm.getTexture()); |
+ SkASSERT(width <= bm.width() && height <= bm.height()); |
+ return new SkSpecialImage_Raster(width, height, bm); |
+} |
+ |
+#if SK_SUPPORT_GPU |
+/////////////////////////////////////////////////////////////////////////////// |
+#include "GrTexture.h" |
+#include "SkGr.h" |
+#include "SkGrPriv.h" |
+ |
+class SkSpecialImage_Gpu : public SkSpecialImage_Base { |
+public: |
+ SkSpecialImage_Gpu(int width, int height, GrTexture* tex) |
+ : INHERITED(width, height) |
+ , fTexture(SkRef(tex)) { |
+ } |
+ |
+ ~SkSpecialImage_Gpu() override { } |
+ |
+ void onDraw(SkCanvas* canvas, int x, int y, const SkPaint* paint) const override { |
+ SkBitmap bm; |
+ |
+ static const bool kUnknownOpacity = false; |
+ GrWrapTextureInBitmap(fTexture, this->width(), this->height(), kUnknownOpacity, &bm); // :( |
+ |
+ canvas->drawBitmap(bm, x, y, paint); |
+ } |
+ |
+ GrTexture* onPeekTexture() const override { return fTexture; } |
+ |
+ SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { |
+ GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info); |
+ desc.fFlags = kRenderTarget_GrSurfaceFlag; |
+ |
+ return SkSpecialSurface::New(fTexture->getContext(), desc); |
+ } |
+ |
+private: |
+ SkAutoTUnref<GrTexture> fTexture; |
+ |
+ typedef SkSpecialImage_Base INHERITED; |
+}; |
+ |
+SkSpecialImage* SkSpecialImage::New(int width, int height, GrTexture* tex) { |
+ SkASSERT(width <= tex->width() && height <= tex->height()); |
+ return new SkSpecialImage_Gpu(width, height, tex); |
+} |
+ |
+#else |
+ |
+SkSpecialImage* SkSpecialImage::New(int width, int height, GrTexture* tex) { |
+ return nullptr; |
+} |
+ |
+#endif |