remove unused (by the outside) SkImage::newSurface, and simplify newImage -> newSubset
BUG=skia:
Review URL: https://codereview.chromium.org/1364443002
diff --git a/gm/drawbitmaprect.cpp b/gm/drawbitmaprect.cpp
index dd6d2b7..2f33627 100644
--- a/gm/drawbitmaprect.cpp
+++ b/gm/drawbitmaprect.cpp
@@ -89,33 +89,6 @@
canvas->drawImageRect(image, srcR, dstR, nullptr);
}
-static void imagescaleproc(SkCanvas* canvas, SkImage* image, const SkBitmap&, const SkIRect& srcIR,
- const SkRect& dstR) {
- const int newW = SkScalarRoundToInt(dstR.width());
- const int newH = SkScalarRoundToInt(dstR.height());
- SkAutoTUnref<SkImage> newImage(image->newImage(newW, newH, &srcIR));
-
-#ifdef SK_DEBUG
- const SkIRect baseR = SkIRect::MakeWH(image->width(), image->height());
- const bool containsSubset = baseR.contains(srcIR);
-#endif
-
- if (newImage) {
- SkASSERT(containsSubset);
- canvas->drawImage(newImage, dstR.x(), dstR.y());
- } else {
- // newImage() does not support subsets that are not contained by the original
- // but drawImageRect does, so we just draw an X in its place to indicate that we are
- // deliberately not drawing here.
- SkASSERT(!containsSubset);
- SkPaint paint;
- paint.setStyle(SkPaint::kStroke_Style);
- paint.setStrokeWidth(4);
- canvas->drawLine(4, 4, newW - 4.0f, newH - 4.0f, paint);
- canvas->drawLine(4, newH - 4.0f, newW - 4.0f, 4, paint);
- }
-}
-
typedef void DrawRectRectProc(SkCanvas*, SkImage*, const SkBitmap&, const SkIRect&, const SkRect&);
static const int gSize = 1024;
@@ -228,4 +201,3 @@
DEF_GM( return new DrawBitmapRectGM(canvasproc, nullptr); )
DEF_GM( return new DrawBitmapRectGM(imageproc, "-imagerect"); )
-DEF_GM( return new DrawBitmapRectGM(imagescaleproc, "-imagescale"); )
diff --git a/gm/image.cpp b/gm/image.cpp
index 726ab97..27cce23 100644
--- a/gm/image.cpp
+++ b/gm/image.cpp
@@ -192,96 +192,3 @@
typedef skiagm::GM INHERITED;
};
DEF_GM( return new ImageGM; )
-
-class ImageResizeGM : public skiagm::GM {
- enum {
- W = 100,
- H = 100,
- };
-public:
- ImageResizeGM() {}
-
-protected:
- SkString onShortName() override { return SkString("image-resize"); }
-
- SkISize onISize() override { return SkISize::Make(510, 480); }
-
- void drawIntoImage(SkCanvas* canvas) {
- SkPaint paint;
- paint.setAntiAlias(true);
- paint.setStyle(SkPaint::kStroke_Style);
- paint.setStrokeWidth(3);
- SkRandom rand;
- for (int i = 0; i < 60; ++i) {
- paint.setColor(rand.nextU());
- SkScalar x = rand.nextUScalar1() * W;
- SkScalar y = rand.nextUScalar1() * H;
- SkScalar r = rand.nextUScalar1() * W / 2;
- canvas->drawCircle(x, y, r, paint);
- }
- }
-
- SkImage* makeImage(SkCanvas* canvas) {
- const SkImageInfo info = SkImageInfo::MakeN32Premul(W, H);
- SkAutoTUnref<SkSurface> surface(canvas->newSurface(info));
- if (!surface) {
- surface.reset(SkSurface::NewRaster(info));
- }
- this->drawIntoImage(surface->getCanvas());
- return surface->newImageSnapshot();
- }
-
- void drawResized(SkCanvas* canvas, SkImage* image, int newW, int newH, const SkIRect* subset,
- SkFilterQuality fq) {
- // canvas method
- SkPaint paint;
- paint.setFilterQuality(fq);
- SkRect dstR = SkRect::MakeWH(SkIntToScalar(newW), SkIntToScalar(newH));
- SkRect srcR;
- if (subset) {
- srcR.set(*subset);
- }
- canvas->legacy_drawImageRect(image, subset ? &srcR : nullptr, dstR, &paint);
- canvas->translate(newW + 20.0f, 0);
-
- // image method
- SkAutoTUnref<SkImage> image2(image->newImage(newW, newH, subset, fq));
- canvas->drawImage(image2, 0, 0, nullptr);
- canvas->translate(image2->width() + 20.0f, 0);
- }
-
- void drawImage(SkCanvas* canvas, SkImage* image, SkFilterQuality fq) {
-
- canvas->drawImage(image, 0, 0, nullptr);
- canvas->translate(image->width() + 20.0f, 0);
- this->drawResized(canvas, image, image->width()*4/10, image->height()*4/10, nullptr, fq);
-
- SkIRect subset = SkIRect::MakeLTRB(W/4, H/4, W/2, H/2);
- this->drawResized(canvas, image, W, H, &subset, fq);
- }
-
- void onDraw(SkCanvas* canvas) override {
- canvas->translate(10, 10);
-
- SkAutoTUnref<SkImage> image(this->makeImage(canvas));
-
- const SkFilterQuality fq[] = {
- kNone_SkFilterQuality,
- kLow_SkFilterQuality,
- kMedium_SkFilterQuality,
- kHigh_SkFilterQuality,
- };
- for (size_t i = 0; i < SK_ARRAY_COUNT(fq); ++i) {
- {
- SkAutoCanvasRestore acr(canvas, true);
- this->drawImage(canvas, image, fq[i]);
- }
- canvas->translate(0, image->height() + 20.0f);
- }
- }
-
-private:
- typedef skiagm::GM INHERITED;
-};
-DEF_GM( return new ImageResizeGM; )
-
diff --git a/gm/image_pict.cpp b/gm/image_pict.cpp
index 19271c1..53ae990 100644
--- a/gm/image_pict.cpp
+++ b/gm/image_pict.cpp
@@ -326,7 +326,7 @@
// No API to draw a GrTexture directly, so we cheat and create a private image subclass
SkAutoTUnref<SkImage> image(new SkImage_Gpu(cache->info().width(), cache->info().height(),
cache->uniqueID(), kPremul_SkAlphaType, texture,
- 0, SkSurface::kNo_Budgeted));
+ SkSurface::kNo_Budgeted));
canvas->drawImage(image, x, y);
#endif
}
diff --git a/gm/surface.cpp b/gm/surface.cpp
index bf7f931..8c7c118 100644
--- a/gm/surface.cpp
+++ b/gm/surface.cpp
@@ -143,7 +143,7 @@
SkAutoTUnref<SkImage> image(surf->newImageSnapshot());
canvas->drawImage(image, 10, 10, nullptr);
- SkAutoTUnref<SkSurface> surf2(image->newSurface(info, nullptr));
+ SkAutoTUnref<SkSurface> surf2(surf->newSurface(info));
drawInto(surf2->getCanvas());
// Assert that the props were communicated transitively through the first image
diff --git a/include/core/SkImage.h b/include/core/SkImage.h
index 90448d8..99562f4 100644
--- a/include/core/SkImage.h
+++ b/include/core/SkImage.h
@@ -270,17 +270,9 @@
*/
SkData* refEncoded() const;
- /**
- * Return a new surface that is compatible with this image's internal representation
- * (e.g. raster or gpu).
- *
- * If no surfaceprops are specified, the image will attempt to match the props of when it
- * was created (if it came from a surface).
- */
- SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps* = NULL) const;
-
const char* toString(SkString*) const;
+#ifdef SK_SUPPORT_LEGACY_NEWIMAGE
/**
* Return an image that is a rescale of this image (using newWidth, newHeight).
*
@@ -299,8 +291,17 @@
* since during drawing we will "apply the alpha" to the pixels. Future optimizations
* may take away this caveat, preserving unpremul.
*/
- SkImage* newImage(int newWidth, int newHeight, const SkIRect* subset = NULL,
- SkFilterQuality = kNone_SkFilterQuality) const;
+ SkImage* newImage(int newWidth, int newHeight, const SkIRect* subset) const;
+#endif
+
+ /**
+ * Return a new image that is a subset of this image. The underlying implementation may
+ * share the pixels, or it may make a copy.
+ *
+ * If subset does not intersect the bounds of this image, or the copy/share cannot be made,
+ * NULL will be returned.
+ */
+ SkImage* newSubset(const SkIRect& subset) const;
// Helper functions to convert to SkBitmap
diff --git a/samplecode/SampleFilterQuality.cpp b/samplecode/SampleFilterQuality.cpp
index 8bc2b07..f5558d8 100644
--- a/samplecode/SampleFilterQuality.cpp
+++ b/samplecode/SampleFilterQuality.cpp
@@ -46,14 +46,14 @@
return surface->newImageSnapshot();
}
-static SkImage* zoom_up(SkImage* orig) {
+static SkImage* zoom_up(SkSurface* origSurf, SkImage* orig) {
const SkScalar S = 8; // amount to scale up
const int D = 2; // dimension scaling for the offscreen
// since we only view the center, don't need to produce the entire thing
SkImageInfo info = SkImageInfo::MakeN32(orig->width() * D, orig->height() * D,
kOpaque_SkAlphaType);
- SkAutoTUnref<SkSurface> surface(orig->newSurface(info));
+ SkAutoTUnref<SkSurface> surface(origSurf->newSurface(info));
SkCanvas* canvas = surface->getCanvas();
canvas->drawColor(SK_ColorWHITE);
canvas->scale(S, S);
@@ -221,7 +221,7 @@
if (surface) {
SkAutoTUnref<SkImage> orig(surface->newImageSnapshot());
- SkAutoTUnref<SkImage> zoomed(zoom_up(orig));
+ SkAutoTUnref<SkImage> zoomed(zoom_up(surface, orig));
origCanvas->drawImage(zoomed,
SkScalarHalf(fCell.width() - zoomed->width()),
SkScalarHalf(fCell.height() - zoomed->height()));
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index 6f46557..032be19 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -126,21 +126,15 @@
return generator ? SkImage::NewFromGenerator(generator, subset) : nullptr;
}
-SkSurface* SkImage::newSurface(const SkImageInfo& info, const SkSurfaceProps* props) const {
- if (nullptr == props) {
- props = &as_IB(this)->props();
- }
- return as_IB(this)->onNewSurface(info, *props);
-}
-
const char* SkImage::toString(SkString* str) const {
str->appendf("image: (id:%d (%d, %d) %s)", this->uniqueID(), this->width(), this->height(),
this->isOpaque() ? "opaque" : "");
return str->c_str();
}
-SkImage* SkImage::newImage(int newWidth, int newHeight, const SkIRect* subset,
- SkFilterQuality quality) const {
+#ifdef SK_SUPPORT_LEGACY_NEWIMAGE
+SkImage* SkImage::newImage(int newWidth, int newHeight, const SkIRect* subset) const {
+#if 0
if (newWidth <= 0 || newHeight <= 0) {
return nullptr;
}
@@ -161,6 +155,30 @@
}
return as_IB(this)->onNewImage(newWidth, newHeight, subset, quality);
+#else
+ SkASSERT(subset);
+ SkASSERT(subset->width() == newWidth);
+ SkASSERT(subset->height() == newHeight);
+ return this->newSubset(*subset);
+#endif
+}
+#endif
+
+SkImage* SkImage::newSubset(const SkIRect& subset) const {
+ if (subset.isEmpty()) {
+ return nullptr;
+ }
+
+ const SkIRect bounds = SkIRect::MakeWH(this->width(), this->height());
+ if (!bounds.contains(subset)) {
+ return nullptr;
+ }
+
+ // optimization : return self if the subset == our bounds
+ if (bounds == subset) {
+ return SkRef(const_cast<SkImage*>(this));
+ }
+ return as_IB(this)->onNewSubset(subset);
}
#if SK_SUPPORT_GPU
@@ -244,33 +262,6 @@
return true;
}
-SkImage* SkImage_Base::onNewImage(int newWidth, int newHeight, const SkIRect* subset,
- SkFilterQuality quality) const {
- const bool opaque = this->isOpaque();
- const SkImageInfo info = SkImageInfo::Make(newWidth, newHeight, kN32_SkColorType,
- opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
- SkAutoTUnref<SkSurface> surface(this->newSurface(info, nullptr));
- if (!surface.get()) {
- return nullptr;
- }
-
- SkRect src;
- if (subset) {
- src.set(*subset);
- } else {
- src = SkRect::MakeIWH(this->width(), this->height());
- }
-
- surface->getCanvas()->scale(newWidth / src.width(), newHeight / src.height());
- surface->getCanvas()->translate(-src.x(), -src.y());
-
- SkPaint paint;
- paint.setXfermodeMode(SkXfermode::kSrc_Mode);
- paint.setFilterQuality(quality);
- surface->getCanvas()->drawImage(this, 0, 0, &paint);
- return surface->newImageSnapshot();
-}
-
///////////////////////////////////////////////////////////////////////////////////////////////////
bool SkImage::peekPixels(SkPixmap* pmap) const {
@@ -311,7 +302,7 @@
}
const SkImageInfo info = bm.info();
return new SkImage_Gpu(info.width(), info.height(), bm.getGenerationID(), info.alphaType(),
- tex, 0, SkSurface::kNo_Budgeted);
+ tex, SkSurface::kNo_Budgeted);
}
#endif
diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h
index d0cb8d5..bbcf182 100644
--- a/src/image/SkImage_Base.h
+++ b/src/image/SkImage_Base.h
@@ -37,8 +37,6 @@
const SkSurfaceProps& props() const { return fProps; }
- virtual SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) const = 0;
-
virtual const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const {
return nullptr;
}
@@ -60,9 +58,7 @@
SkShader::TileMode,
const SkMatrix* localMatrix) const { return nullptr; }
- // newWidth > 0, newHeight > 0, subset either nullptr or a proper subset of this bounds
- virtual SkImage* onNewImage(int newWidth, int newHeight, const SkIRect* subset,
- SkFilterQuality) const;
+ virtual SkImage* onNewSubset(const SkIRect&) const = 0;
virtual SkData* onRefEncoded() const { return nullptr; }
virtual bool onAsLegacyBitmap(SkBitmap*, LegacyBitmapMode) const;
diff --git a/src/image/SkImage_Generator.cpp b/src/image/SkImage_Generator.cpp
index 4981f37..765234f 100644
--- a/src/image/SkImage_Generator.cpp
+++ b/src/image/SkImage_Generator.cpp
@@ -7,6 +7,7 @@
#include "SkImage_Base.h"
#include "SkBitmap.h"
+#include "SkCanvas.h"
#include "SkData.h"
#include "SkImageCacherator.h"
#include "SkImagePriv.h"
@@ -20,12 +21,11 @@
, 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(); }
-
+ SkImage* onNewSubset(const SkIRect&) const override;
bool getROPixels(SkBitmap*) const override;
GrTexture* asTextureRef(GrContext*, SkImageUsageType) const override;
@@ -54,11 +54,6 @@
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;
@@ -84,6 +79,22 @@
return fCache->lockAsTexture(ctx, usage, this);
}
+SkImage* SkImage_Generator::onNewSubset(const SkIRect& subset) const {
+ // TODO: make this lazy, by wrapping the subset inside a new generator or something
+ // For now, we do effectively what we did before, make it a raster
+
+ const SkImageInfo info = SkImageInfo::MakeN32(subset.width(), subset.height(),
+ this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
+ SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
+ if (!surface) {
+ return nullptr;
+ }
+ surface->getCanvas()->clear(0);
+ surface->getCanvas()->drawImage(this, SkIntToScalar(-subset.x()), SkIntToScalar(-subset.y()),
+ nullptr);
+ return surface->newImageSnapshot();
+}
+
SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator, const SkIRect* subset) {
SkImageCacherator* cache = SkImageCacherator::NewFromGenerator(generator, subset);
if (!cache) {
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 163e62e..1a63a0d 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -15,10 +15,9 @@
#include "SkPixelRef.h"
SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, GrTexture* tex,
- int sampleCountForNewSurfaces, SkSurface::Budgeted budgeted)
+ SkSurface::Budgeted budgeted)
: INHERITED(w, h, uniqueID, nullptr)
, fTexture(SkRef(tex))
- , fSampleCountForNewSurfaces(sampleCountForNewSurfaces)
, fAlphaType(at)
, fBudgeted(budgeted)
, fAddedRasterVersionToCache(false)
@@ -30,19 +29,6 @@
}
}
-SkSurface* SkImage_Gpu::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) const {
- GrTexture* tex = this->getTexture();
- SkASSERT(tex);
- GrContext* ctx = tex->getContext();
- if (!ctx) {
- // the texture may have been abandoned, so we have to check
- return nullptr;
- }
- // TODO: Change signature of onNewSurface to take a budgeted param.
- const SkSurface::Budgeted budgeted = SkSurface::kNo_Budgeted;
- return SkSurface::NewRenderTarget(ctx, budgeted, info, fSampleCountForNewSurfaces, &props);
-}
-
extern void SkTextureImageApplyBudgetedDecision(SkImage* image) {
if (as_IB(image)->getTexture()) {
((SkImage_Gpu*)image)->applyBudgetDecision();
@@ -136,6 +122,22 @@
return true;
}
+SkImage* SkImage_Gpu::onNewSubset(const SkIRect& subset) const {
+ GrContext* ctx = fTexture->getContext();
+ GrSurfaceDesc desc = fTexture->desc();
+ desc.fWidth = subset.width();
+ desc.fHeight = subset.height();
+
+ GrTexture* subTx = ctx->textureProvider()->createTexture(desc,
+ SkSurface::kYes_Budgeted == fBudgeted);
+ if (!subTx) {
+ return nullptr;
+ }
+ ctx->copySurface(subTx, fTexture, subset, SkIPoint::Make(0, 0));
+ return new SkImage_Gpu(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID, fAlphaType, subTx,
+ fBudgeted);
+}
+
///////////////////////////////////////////////////////////////////////////////////////////////////
static SkImage* new_wrapped_texture_common(GrContext* ctx, const GrBackendTextureDesc& desc,
@@ -154,7 +156,7 @@
}
const SkSurface::Budgeted budgeted = SkSurface::kNo_Budgeted;
- return new SkImage_Gpu(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID, at, tex, 0, budgeted);
+ return new SkImage_Gpu(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID, at, tex, budgeted);
}
SkImage* SkImage::NewFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc, SkAlphaType at,
@@ -186,8 +188,7 @@
}
const SkSurface::Budgeted budgeted = SkSurface::kYes_Budgeted;
- const int sampleCount = 0; // todo: make this an explicit parameter to newSurface()?
- return new SkImage_Gpu(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID, at, dst, sampleCount,
+ return new SkImage_Gpu(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID, at, dst,
budgeted);
}
@@ -267,7 +268,7 @@
drawContext->drawRect(dst->asRenderTarget(), GrClip::WideOpen(), paint, SkMatrix::I(), rect);
ctx->flushSurfaceWrites(dst);
return new SkImage_Gpu(dstDesc.fWidth, dstDesc.fHeight, kNeedNewImageUniqueID,
- kOpaque_SkAlphaType, dst, 0, budgeted);
+ kOpaque_SkAlphaType, dst, budgeted);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/image/SkImage_Gpu.h b/src/image/SkImage_Gpu.h
index d168fb6..5e847dd 100644
--- a/src/image/SkImage_Gpu.h
+++ b/src/image/SkImage_Gpu.h
@@ -22,8 +22,7 @@
* An "image" can be a subset/window into a larger texture, so we explicit take the
* width and height.
*/
- SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType, GrTexture*,
- int sampleCountForNewSurfaces, SkSurface::Budgeted);
+ SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType, GrTexture*, SkSurface::Budgeted);
~SkImage_Gpu() override;
void applyBudgetDecision() const {
@@ -38,19 +37,18 @@
bool getROPixels(SkBitmap*) const override;
GrTexture* asTextureRef(GrContext* ctx, SkImageUsageType usage) const override;
+ SkImage* onNewSubset(const SkIRect&) const override;
GrTexture* peekTexture() const override { return fTexture; }
SkShader* onNewShader(SkShader::TileMode,
SkShader::TileMode,
const SkMatrix* localMatrix) const override;
bool isOpaque() const override;
- SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) const override;
bool onReadPixels(const SkImageInfo&, void* dstPixels, size_t dstRowBytes,
int srcX, int srcY) const override;
private:
SkAutoTUnref<GrTexture> fTexture;
- const int fSampleCountForNewSurfaces; // 0 if we don't know
const SkAlphaType fAlphaType;
const SkSurface::Budgeted fBudgeted;
mutable SkAtomic<bool> fAddedRasterVersionToCache;
diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp
index 67498f0..30ea7cc 100644
--- a/src/image/SkImage_Raster.cpp
+++ b/src/image/SkImage_Raster.cpp
@@ -67,12 +67,12 @@
SkImage_Raster(const SkImageInfo&, SkData*, size_t rb, SkColorTable*, const SkSurfaceProps*);
virtual ~SkImage_Raster();
- 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 getROPixels(SkBitmap*) const override;
GrTexture* asTextureRef(GrContext*, SkImageUsageType) const override;
+ SkImage* onNewSubset(const SkIRect&) const override;
// exposed for SkSurface_Raster via SkNewImageFromPixelRef
SkImage_Raster(const SkImageInfo&, SkPixelRef*, const SkIPoint& pixelRefOrigin, size_t rowBytes,
@@ -149,10 +149,6 @@
return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, localMatrix);
}
-SkSurface* SkImage_Raster::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) const {
- return SkSurface::NewRaster(info, &props);
-}
-
bool SkImage_Raster::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
int srcX, int srcY) const {
SkBitmap shallowCopy(fBitmap);
@@ -212,6 +208,20 @@
return nullptr;
}
+SkImage* SkImage_Raster::onNewSubset(const SkIRect& subset) const {
+ // TODO : could consider heurist of sharing pixels, if subset is pretty close to complete
+
+ SkImageInfo info = SkImageInfo::MakeN32(subset.width(), subset.height(), fBitmap.alphaType());
+ SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
+ if (!surface) {
+ return nullptr;
+ }
+ surface->getCanvas()->clear(0);
+ surface->getCanvas()->drawImage(this, SkIntToScalar(-subset.x()), SkIntToScalar(-subset.y()),
+ nullptr);
+ return surface->newImageSnapshot();
+}
+
///////////////////////////////////////////////////////////////////////////////
SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes,
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index c0c6b6e..b705f47 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -16,7 +16,6 @@
#if SK_SUPPORT_GPU
-///////////////////////////////////////////////////////////////////////////////
SkSurface_Gpu::SkSurface_Gpu(SkGpuDevice* device)
: INHERITED(device->width(), device->height(), &device->surfaceProps())
, fDevice(SkRef(device)) {
@@ -80,12 +79,11 @@
SkImage* SkSurface_Gpu::onNewImageSnapshot(Budgeted budgeted) {
const SkImageInfo info = fDevice->imageInfo();
- const int sampleCount = fDevice->accessRenderTarget()->numColorSamples();
SkImage* image = nullptr;
GrTexture* tex = fDevice->accessRenderTarget()->asTexture();
if (tex) {
image = new SkImage_Gpu(info.width(), info.height(), kNeedNewImageUniqueID,
- info.alphaType(), tex, sampleCount, budgeted);
+ info.alphaType(), tex, budgeted);
}
if (image) {
as_IB(image)->initWithProps(this->props());