Take budgeted param when snapping new image.
Review URL: https://codereview.chromium.org/872543002
diff --git a/src/image/SkImagePriv.h b/src/image/SkImagePriv.h
index 7306934..874476b 100644
--- a/src/image/SkImagePriv.h
+++ b/src/image/SkImagePriv.h
@@ -9,6 +9,7 @@
#define SkImagePriv_DEFINED
#include "SkImage.h"
+#include "SkSurface.h"
// Call this if you explicitly want to use/share this pixelRef in the image
extern SkImage* SkNewImageFromPixelRef(const SkImageInfo&, SkPixelRef*, size_t rowBytes,
@@ -40,11 +41,18 @@
// in which case the surface may need to perform a copy-on-write.
extern GrTexture* SkTextureImageGetTexture(SkImage* textureImage);
+// When a texture is shared by a surface and an image its budgeted status is that of the
+// surface. This function is used when the surface makes a new texture for itself in order
+// for the orphaned image to determine whether the original texture counts against the
+// budget or not.
+extern void SkTextureImageApplyBudgetedDecision(SkImage* textureImage);
+
// Update the texture wrapped by an image created with NewTexture. This
// is called when a surface and image share the same GrTexture and the
// surface needs to perform a copy-on-write
extern void SkTextureImageSetTexture(SkImage* image, GrTexture* texture);
-extern SkImage* SkNewImageFromBitmapTexture(const SkBitmap&, int sampleCountForNewSurfaces);
+extern SkImage* SkNewImageFromBitmapTexture(const SkBitmap&, int sampleCountForNewSurfaces,
+ SkSurface::Budgeted);
#endif
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 8169b2a..7ccff17 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -5,48 +5,16 @@
* found in the LICENSE file.
*/
-#include "SkImage_Base.h"
-#include "SkImagePriv.h"
-#include "SkBitmap.h"
+#include "SkImage_Gpu.h"
#include "SkCanvas.h"
-#include "SkSurface.h"
#include "GrContext.h"
-#include "GrTexture.h"
-class SkImage_Gpu : public SkImage_Base {
-public:
- SK_DECLARE_INST_COUNT(SkImage_Gpu)
-
- SkImage_Gpu(const SkBitmap&, int sampleCountForNewSurfaces);
-
- void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const SK_OVERRIDE;
- void onDrawRect(SkCanvas*, const SkRect* src, const SkRect& dst,
- const SkPaint*) const SK_OVERRIDE;
- SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) const SK_OVERRIDE;
- GrTexture* onGetTexture() const SK_OVERRIDE;
- bool getROPixels(SkBitmap*) const SK_OVERRIDE;
-
- GrTexture* getTexture() const { return fBitmap.getTexture(); }
-
- SkShader* onNewShader(SkShader::TileMode,
- SkShader::TileMode,
- const SkMatrix* localMatrix) const SK_OVERRIDE;
-
- bool isOpaque() const SK_OVERRIDE;
-
-private:
- SkBitmap fBitmap;
- const int fSampleCountForNewSurfaces; // 0 if we don't know
-
- typedef SkImage_Base INHERITED;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkImage_Gpu::SkImage_Gpu(const SkBitmap& bitmap, int sampleCountForNewSurfaces)
+SkImage_Gpu::SkImage_Gpu(const SkBitmap& bitmap, int sampleCountForNewSurfaces,
+ SkSurface::Budgeted budgeted)
: INHERITED(bitmap.width(), bitmap.height(), NULL)
, fBitmap(bitmap)
, fSampleCountForNewSurfaces(sampleCountForNewSurfaces)
+ , fBudgeted(budgeted)
{
SkASSERT(fBitmap.getTexture());
}
@@ -88,14 +56,18 @@
///////////////////////////////////////////////////////////////////////////////
-SkImage* SkNewImageFromBitmapTexture(const SkBitmap& bitmap, int sampleCountForNewSurfaces) {
+SkImage* SkNewImageFromBitmapTexture(const SkBitmap& bitmap, int sampleCountForNewSurfaces,
+ SkSurface::Budgeted budgeted) {
if (0 == bitmap.width() || 0 == bitmap.height() || NULL == bitmap.getTexture()) {
return NULL;
}
- return SkNEW_ARGS(SkImage_Gpu, (bitmap, sampleCountForNewSurfaces));
+ return SkNEW_ARGS(SkImage_Gpu, (bitmap, sampleCountForNewSurfaces, budgeted));
}
GrTexture* SkTextureImageGetTexture(SkImage* image) {
return ((SkImage_Gpu*)image)->getTexture();
}
+extern void SkTextureImageApplyBudgetedDecision(SkImage* image) {
+ ((SkImage_Gpu*)image)->applyBudgetDecision();
+}
diff --git a/src/image/SkImage_Gpu.h b/src/image/SkImage_Gpu.h
new file mode 100644
index 0000000..f20625a
--- /dev/null
+++ b/src/image/SkImage_Gpu.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkImage_Gpu_DEFINED
+#define SkImage_Gpu_DEFINED
+
+#include "GrTexture.h"
+#include "GrGpuResourceCacheAccess.h"
+#include "SkBitmap.h"
+#include "SkImage_Base.h"
+#include "SkImagePriv.h"
+#include "SkSurface.h"
+
+class SkImage_Gpu : public SkImage_Base {
+public:
+ SK_DECLARE_INST_COUNT(SkImage_Gpu)
+
+ SkImage_Gpu(const SkBitmap&, int sampleCountForNewSurfaces, SkSurface::Budgeted);
+
+ void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const SK_OVERRIDE;
+ void onDrawRect(SkCanvas*, const SkRect* src, const SkRect& dst,
+ const SkPaint*) const SK_OVERRIDE;
+ SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) const SK_OVERRIDE;
+ GrTexture* onGetTexture() const SK_OVERRIDE;
+ bool getROPixels(SkBitmap*) const SK_OVERRIDE;
+
+ GrTexture* getTexture() const { return fBitmap.getTexture(); }
+
+ SkShader* onNewShader(SkShader::TileMode,
+ SkShader::TileMode,
+ const SkMatrix* localMatrix) const SK_OVERRIDE;
+
+ bool isOpaque() const SK_OVERRIDE;
+
+ void applyBudgetDecision() const {
+ if (fBudgeted) {
+ fBitmap.getTexture()->cacheAccess().makeBudgeted();
+ } else {
+ fBitmap.getTexture()->cacheAccess().makeUnbudgeted();
+ }
+ }
+
+private:
+ SkBitmap fBitmap;
+ const int fSampleCountForNewSurfaces; // 0 if we don't know
+ SkSurface::Budgeted fBudgeted;
+
+ typedef SkImage_Base INHERITED;
+};
+
+#endif
diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp
index 81b348f..2d3fa2b 100644
--- a/src/image/SkSurface.cpp
+++ b/src/image/SkSurface.cpp
@@ -79,7 +79,7 @@
}
void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
- SkImage* image = this->newImageSnapshot();
+ SkImage* image = this->newImageSnapshot(kYes_Budgeted);
if (image) {
canvas->drawImage(image, x, y, paint);
image->unref();
@@ -151,8 +151,8 @@
return asSB(this)->getCachedCanvas();
}
-SkImage* SkSurface::newImageSnapshot() {
- SkImage* image = asSB(this)->getCachedImage();
+SkImage* SkSurface::newImageSnapshot(Budgeted budgeted) {
+ SkImage* image = asSB(this)->getCachedImage(budgeted);
SkSafeRef(image); // the caller will call unref() to balance this
return image;
}
diff --git a/src/image/SkSurface_Base.h b/src/image/SkSurface_Base.h
index 4da4cfb..30af976 100644
--- a/src/image/SkSurface_Base.h
+++ b/src/image/SkSurface_Base.h
@@ -32,9 +32,9 @@
* Allocate an SkImage that represents the current contents of the surface.
* This needs to be able to outlive the surface itself (if need be), and
* must faithfully represent the current contents, even if the surface
- * is chaged after this calle (e.g. it is drawn to via its canvas).
+ * is changed after this called (e.g. it is drawn to via its canvas).
*/
- virtual SkImage* onNewImageSnapshot() = 0;
+ virtual SkImage* onNewImageSnapshot(Budgeted) = 0;
/**
* Default implementation:
@@ -61,7 +61,7 @@
virtual void onCopyOnWrite(ContentChangeMode) = 0;
inline SkCanvas* getCachedCanvas();
- inline SkImage* getCachedImage();
+ inline SkImage* getCachedImage(Budgeted);
// called by SkSurface to compute a new genID
uint32_t newGenerationID();
@@ -87,9 +87,9 @@
return fCachedCanvas;
}
-SkImage* SkSurface_Base::getCachedImage() {
+SkImage* SkSurface_Base::getCachedImage(Budgeted budgeted) {
if (NULL == fCachedImage) {
- fCachedImage = this->onNewImageSnapshot();
+ fCachedImage = this->onNewImageSnapshot(budgeted);
SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this);
}
return fCachedImage;
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index 6cd741d..34aec2b 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -44,9 +44,10 @@
&this->props());
}
-SkImage* SkSurface_Gpu::onNewImageSnapshot() {
+SkImage* SkSurface_Gpu::onNewImageSnapshot(Budgeted budgeted) {
const int sampleCount = fDevice->accessRenderTarget()->numSamples();
- SkImage* image = SkNewImageFromBitmapTexture(fDevice->accessBitmap(false), sampleCount);
+ SkImage* image = SkNewImageFromBitmapTexture(fDevice->accessBitmap(false), sampleCount,
+ budgeted);
if (image) {
as_IB(image)->initWithProps(this->props());
}
@@ -63,9 +64,11 @@
// doesn't force an OpenGL flush.
void SkSurface_Gpu::onCopyOnWrite(ContentChangeMode mode) {
GrRenderTarget* rt = fDevice->accessRenderTarget();
- // are we sharing our render target with the image?
- SkASSERT(this->getCachedImage());
- if (rt->asTexture() == SkTextureImageGetTexture(this->getCachedImage())) {
+ // are we sharing our render target with the image? Note this call should never create a new
+ // image because onCopyOnWrite is only called when there is a cached image.
+ SkImage* image = this->getCachedImage(kNo_Budgeted);
+ SkASSERT(image);
+ if (rt->asTexture() == SkTextureImageGetTexture(image)) {
GrRenderTarget* oldRT = this->fDevice->accessRenderTarget();
SkSurface::Budgeted budgeted = oldRT->cacheAccess().isBudgeted() ? kYes_Budgeted :
kNo_Budgeted;
@@ -82,10 +85,7 @@
this->getCachedCanvas()->setRootDevice(newDevice);
SkRefCnt_SafeAssign(fDevice, newDevice.get());
- // For now we always treat the image snapshots as budgeted. We could make newImageSnapshot
- // take a Budgeted param.
- oldRT->cacheAccess().makeBudgeted();
-
+ SkTextureImageApplyBudgetedDecision(image);
} else if (kDiscard_ContentChangeMode == mode) {
this->SkSurface_Gpu::onDiscard();
}
diff --git a/src/image/SkSurface_Gpu.h b/src/image/SkSurface_Gpu.h
index f87c5d7..90c00c4 100644
--- a/src/image/SkSurface_Gpu.h
+++ b/src/image/SkSurface_Gpu.h
@@ -23,7 +23,7 @@
SkCanvas* onNewCanvas() SK_OVERRIDE;
SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE;
- SkImage* onNewImageSnapshot() SK_OVERRIDE;
+ SkImage* onNewImageSnapshot(Budgeted) SK_OVERRIDE;
virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y,
const SkPaint*) SK_OVERRIDE;
void onCopyOnWrite(ContentChangeMode) SK_OVERRIDE;
diff --git a/src/image/SkSurface_Raster.cpp b/src/image/SkSurface_Raster.cpp
index 0752383..9c38640 100644
--- a/src/image/SkSurface_Raster.cpp
+++ b/src/image/SkSurface_Raster.cpp
@@ -24,7 +24,7 @@
SkCanvas* onNewCanvas() SK_OVERRIDE;
SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE;
- SkImage* onNewImageSnapshot() SK_OVERRIDE;
+ SkImage* onNewImageSnapshot(Budgeted) SK_OVERRIDE;
virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y,
const SkPaint*) SK_OVERRIDE;
void onCopyOnWrite(ContentChangeMode) SK_OVERRIDE;
@@ -118,14 +118,14 @@
canvas->drawBitmap(fBitmap, x, y, paint);
}
-SkImage* SkSurface_Raster::onNewImageSnapshot() {
+SkImage* SkSurface_Raster::onNewImageSnapshot(Budgeted) {
return SkNewImageFromBitmap(fBitmap, fWeOwnThePixels, &this->props());
}
void SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) {
// are we sharing pixelrefs with the image?
- SkASSERT(this->getCachedImage());
- if (SkBitmapImageGetPixelRef(this->getCachedImage()) == fBitmap.pixelRef()) {
+ SkASSERT(this->getCachedImage(kNo_Budgeted));
+ if (SkBitmapImageGetPixelRef(this->getCachedImage(kNo_Budgeted)) == fBitmap.pixelRef()) {
SkASSERT(fWeOwnThePixels);
if (kDiscard_ContentChangeMode == mode) {
fBitmap.setPixelRef(NULL);