aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2015-01-16 07:32:33 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-01-16 07:32:33 -0800
commitafe3005be3392e43bc51eb7eb2017eefaed85ad1 (patch)
tree3b96ec2e3249a928a0e876140bec3bf3e9dbb13f /src/gpu
parentb50ced703030dfbda4fc3ef5e6ec9a52fc0405f8 (diff)
Require budget decision when creating a RenderTarget SkSurface.
Restructure SkGpuDevice creation: *SkSurfaceProps are optional. *Use SkSurfaceProps to communicate DF text rather than a flag. *Tell SkGpuDevice::Create whether RT comes from cache or not. Review URL: https://codereview.chromium.org/848903004
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrGpuResource.cpp8
-rw-r--r--src/gpu/GrGpuResourceCacheAccess.h6
-rw-r--r--src/gpu/GrResourceCache2.cpp4
-rw-r--r--src/gpu/SkGpuDevice.cpp98
-rw-r--r--src/gpu/SkGpuDevice.h39
5 files changed, 90 insertions, 65 deletions
diff --git a/src/gpu/GrGpuResource.cpp b/src/gpu/GrGpuResource.cpp
index a2df7e13e8..2f267a4197 100644
--- a/src/gpu/GrGpuResource.cpp
+++ b/src/gpu/GrGpuResource.cpp
@@ -6,7 +6,6 @@
* found in the LICENSE file.
*/
-
#include "GrGpuResource.h"
#include "GrResourceCache2.h"
#include "GrGpu.h"
@@ -134,6 +133,13 @@ void GrGpuResource::removeScratchKey() {
}
}
+void GrGpuResource::makeBudgeted() {
+ if (GrGpuResource::kUncached_LifeCycle == fLifeCycle) {
+ fLifeCycle = kCached_LifeCycle;
+ get_resource_cache2(fGpu)->resourceAccess().didChangeBudgetStatus(this);
+ }
+}
+
uint32_t GrGpuResource::CreateUniqueID() {
static int32_t gUniqueID = SK_InvalidUniqueID;
uint32_t id;
diff --git a/src/gpu/GrGpuResourceCacheAccess.h b/src/gpu/GrGpuResourceCacheAccess.h
index 0aadb89d97..d7c5028b20 100644
--- a/src/gpu/GrGpuResourceCacheAccess.h
+++ b/src/gpu/GrGpuResourceCacheAccess.h
@@ -70,6 +70,12 @@ public:
bool isBudgeted() const { return GrGpuResource::kCached_LifeCycle == fResource->fLifeCycle; }
/**
+ * If the resource is uncached make it cached. Has no effect on resources that are wrapped or
+ * already cached.
+ */
+ void makeBudgeted() { fResource->makeBudgeted(); }
+
+ /**
* Called by the cache to delete the resource under normal circumstances.
*/
void release() {
diff --git a/src/gpu/GrResourceCache2.cpp b/src/gpu/GrResourceCache2.cpp
index e23f9688ac..ba9d4d1016 100644
--- a/src/gpu/GrResourceCache2.cpp
+++ b/src/gpu/GrResourceCache2.cpp
@@ -306,6 +306,10 @@ void GrResourceCache2::didChangeBudgetStatus(GrGpuResource* resource) {
if (resource->cacheAccess().isBudgeted()) {
++fBudgetedCount;
fBudgetedBytes += size;
+#if GR_CACHE_STATS
+ fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes);
+ fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount);
+#endif
this->purgeAsNeeded();
} else {
--fBudgetedCount;
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 5f4713245e..e25cba5202 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -48,8 +48,6 @@
enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 };
-#define CACHE_COMPATIBLE_DEVICE_TEXTURES 1
-
#if 0
extern bool (*gShouldDrawProc)();
#define CHECK_SHOULD_DRAW(draw) \
@@ -68,8 +66,8 @@ enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 };
#define DO_DEFERRED_CLEAR() \
do { \
- if (fFlags & kNeedClear_Flag) { \
- this->clearAll(); \
+ if (fNeedClear) { \
+ this->clearAll(); \
} \
} while (false) \
@@ -124,56 +122,71 @@ public:
///////////////////////////////////////////////////////////////////////////////
-SkGpuDevice* SkGpuDevice::Create(GrSurface* surface, const SkSurfaceProps& props, unsigned flags) {
- SkASSERT(surface);
- if (NULL == surface->asRenderTarget() || surface->wasDestroyed()) {
+SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, const SkSurfaceProps* props, unsigned flags) {
+ if (!rt || rt->wasDestroyed()) {
return NULL;
}
- return SkNEW_ARGS(SkGpuDevice, (surface, props, flags));
+ return SkNEW_ARGS(SkGpuDevice, (rt, props, flags));
}
-static SkDeviceProperties surfaceprops_to_deviceprops(const SkSurfaceProps& props) {
- return SkDeviceProperties(props.pixelGeometry());
+static SkDeviceProperties surfaceprops_to_deviceprops(const SkSurfaceProps* props) {
+ if (props) {
+ return SkDeviceProperties(props->pixelGeometry());
+ } else {
+ return SkDeviceProperties(SkDeviceProperties::kLegacyLCD_InitType);
+ }
}
-SkGpuDevice::SkGpuDevice(GrSurface* surface, const SkSurfaceProps& props, unsigned flags)
+static SkSurfaceProps copy_or_default_props(const SkSurfaceProps* props) {
+ if (props) {
+ return SkSurfaceProps(*props);
+ } else {
+ return SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType);
+ }
+}
+
+SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, const SkSurfaceProps* props, unsigned flags)
: INHERITED(surfaceprops_to_deviceprops(props))
+ , fSurfaceProps(copy_or_default_props(props))
{
fDrawProcs = NULL;
- fContext = SkRef(surface->getContext());
-
- fFlags = flags;
+ fContext = SkRef(rt->getContext());
+ fNeedClear = flags & kNeedClear_Flag;
- fRenderTarget = SkRef(surface->asRenderTarget());
+ fRenderTarget = SkRef(rt);
- SkImageInfo info = surface->surfacePriv().info();
- SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, surface));
+ SkImageInfo info = rt->surfacePriv().info();
+ SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt));
fLegacyBitmap.setInfo(info);
fLegacyBitmap.setPixelRef(pr)->unref();
- bool useDFT = SkToBool(flags & kDFText_Flag);
+ bool useDFT = fSurfaceProps.isUseDistanceFieldFonts();
fTextContext = fContext->createTextContext(fRenderTarget, this->getLeakyProperties(), useDFT);
}
-SkGpuDevice* SkGpuDevice::Create(GrContext* context, const SkImageInfo& origInfo,
- const SkSurfaceProps& props, int sampleCount) {
+SkGpuDevice* SkGpuDevice::Create(GrContext* context, SkSurface::Budgeted budgeted,
+ const SkImageInfo& origInfo, int sampleCount,
+ const SkSurfaceProps* props, unsigned flags) {
if (kUnknown_SkColorType == origInfo.colorType() ||
origInfo.width() < 0 || origInfo.height() < 0) {
return NULL;
}
+ if (!context) {
+ return NULL;
+ }
+
SkColorType ct = origInfo.colorType();
SkAlphaType at = origInfo.alphaType();
- // TODO: perhaps we can loosen this check now that colortype is more detailed
- // e.g. can we support both RGBA and BGRA here?
if (kRGB_565_SkColorType == ct) {
at = kOpaque_SkAlphaType; // force this setting
- } else {
+ } else if (ct != kBGRA_8888_SkColorType && ct != kRGBA_8888_SkColorType) {
+ // Fall back from whatever ct was to default of kRGBA or kBGRA which is aliased as kN32
ct = kN32_SkColorType;
- if (kOpaque_SkAlphaType != at) {
- at = kPremul_SkAlphaType; // force this setting
- }
+ }
+ if (kOpaque_SkAlphaType != at) {
+ at = kPremul_SkAlphaType; // force this setting
}
const SkImageInfo info = SkImageInfo::Make(origInfo.width(), origInfo.height(), ct, at);
@@ -184,12 +197,18 @@ SkGpuDevice* SkGpuDevice::Create(GrContext* context, const SkImageInfo& origInfo
desc.fConfig = SkImageInfo2GrPixelConfig(info);
desc.fSampleCnt = sampleCount;
- SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0));
- if (!texture.get()) {
+ SkAutoTUnref<GrTexture> texture;
+ if (SkSurface::kYes_Budgeted == budgeted) {
+ texture.reset(context->refScratchTexture(desc, GrContext::kExact_ScratchTexMatch));
+ } else {
+ texture.reset(context->createUncachedTexture(desc, NULL, 0));
+ }
+
+ if (!texture) {
return NULL;
}
- return SkNEW_ARGS(SkGpuDevice, (texture.get(), props));
+ return SkNEW_ARGS(SkGpuDevice, (texture->asRenderTarget(), props, flags));
}
SkGpuDevice::~SkGpuDevice() {
@@ -295,7 +314,7 @@ void SkGpuDevice::clearAll() {
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::clearAll", fContext);
SkIRect rect = SkIRect::MakeWH(this->width(), this->height());
fContext->clear(&rect, color, true, fRenderTarget);
- fFlags &= ~kNeedClear_Flag;
+ fNeedClear = false;
}
///////////////////////////////////////////////////////////////////////////////
@@ -1517,7 +1536,7 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
// clear of the source device must occur before CHECK_SHOULD_DRAW
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawDevice", fContext);
SkGpuDevice* dev = static_cast<SkGpuDevice*>(device);
- if (dev->fFlags & kNeedClear_Flag) {
+ if (fNeedClear) {
// TODO: could check here whether we really need to draw at all
dev->clearAll();
}
@@ -1800,21 +1819,17 @@ SkBaseDevice* SkGpuDevice::onCreateCompatibleDevice(const CreateInfo& cinfo) {
SkAutoTUnref<GrTexture> texture;
// Skia's convention is to only clear a device if it is non-opaque.
unsigned flags = cinfo.fInfo.isOpaque() ? 0 : kNeedClear_Flag;
- // If we're using distance field text, enable in the new device
- flags |= (fFlags & kDFText_Flag) ? kDFText_Flag : 0;
-#if CACHE_COMPATIBLE_DEVICE_TEXTURES
// layers are never draw in repeat modes, so we can request an approx
// match and ignore any padding.
const GrContext::ScratchTexMatch match = (kSaveLayer_Usage == cinfo.fUsage) ?
GrContext::kApprox_ScratchTexMatch :
GrContext::kExact_ScratchTexMatch;
texture.reset(fContext->refScratchTexture(desc, match));
-#else
- texture.reset(fContext->createUncachedTexture(desc, NULL, 0));
-#endif
- if (texture.get()) {
- return SkGpuDevice::Create(texture, SkSurfaceProps(0, cinfo.fPixelGeometry), flags);
+
+ if (texture) {
+ SkSurfaceProps props(fSurfaceProps.flags(), cinfo.fPixelGeometry);
+ return SkGpuDevice::Create(texture->asRenderTarget(), &props, flags);
} else {
SkDebugf("---- failed to create compatible device texture [%d %d]\n",
cinfo.fInfo.width(), cinfo.fInfo.height());
@@ -1823,7 +1838,10 @@ SkBaseDevice* SkGpuDevice::onCreateCompatibleDevice(const CreateInfo& cinfo) {
}
SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
- return SkSurface::NewRenderTarget(fContext, info, fRenderTarget->numSamples(), &props);
+ // TODO: Change the signature of newSurface to take a budgeted parameter.
+ static const SkSurface::Budgeted kBudgeted = SkSurface::kNo_Budgeted;
+ return SkSurface::NewRenderTarget(fContext, kBudgeted, info, fRenderTarget->numSamples(),
+ &props);
}
bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture* mainPicture,
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index 56dad1b475..6cbf628e58 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -6,8 +6,6 @@
* found in the LICENSE file.
*/
-
-
#ifndef SkGpuDevice_DEFINED
#define SkGpuDevice_DEFINED
@@ -16,6 +14,7 @@
#include "SkDevice.h"
#include "SkPicture.h"
#include "SkRegion.h"
+#include "SkSurface.h"
#include "GrContext.h"
#include "GrSurfacePriv.h"
@@ -34,25 +33,20 @@ class SK_API SkGpuDevice : public SkBaseDevice {
public:
enum Flags {
kNeedClear_Flag = 1 << 0, //!< Surface requires an initial clear
- kDFText_Flag = 1 << 1, //!< Surface should render text using signed distance fields
};
/**
- * Creates an SkGpuDevice from a GrSurface. This will fail if the surface is not a render
- * target. The caller owns a ref on the returned device. If the surface is cached,
- * the kCached_Flag should be specified to make the device responsible for unlocking
- * the surface when it is released.
+ * Creates an SkGpuDevice from a GrRenderTarget.
*/
- static SkGpuDevice* Create(GrSurface* surface, const SkSurfaceProps&, unsigned flags = 0);
+ static SkGpuDevice* Create(GrRenderTarget* target, const SkSurfaceProps*, unsigned flags = 0);
/**
- * New device that will create an offscreen renderTarget based on the
- * ImageInfo and sampleCount. The device's storage will not
- * count against the GrContext's texture cache budget. The device's pixels
- * will be uninitialized. On failure, returns NULL.
+ * New device that will create an offscreen renderTarget based on the ImageInfo and
+ * sampleCount. The Budgeted param controls whether the device's backing store counts against
+ * the resource cache budget. On failure, returns NULL.
*/
- static SkGpuDevice* Create(GrContext*, const SkImageInfo&, const SkSurfaceProps&,
- int sampleCount);
+ static SkGpuDevice* Create(GrContext*, SkSurface::Budgeted, const SkImageInfo&,
+ int sampleCount, const SkSurfaceProps*, unsigned flags = 0);
virtual ~SkGpuDevice();
@@ -63,7 +57,7 @@ public:
return static_cast<SkGpuDevice*>(dev);
}
- GrContext* context() const { return fContext; }
+ GrContext* context() const { return fRenderTarget->getContext(); }
// set all pixels to 0
void clearAll();
@@ -74,6 +68,8 @@ public:
return fRenderTarget ? fRenderTarget->surfacePriv().info() : SkImageInfo::MakeUnknown();
}
+ const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }
+
void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
const SkPoint[], const SkPaint& paint) SK_OVERRIDE;
@@ -139,21 +135,16 @@ protected:
private:
GrContext* fContext;
-
GrSkDrawProcs* fDrawProcs;
-
GrClipData fClipData;
-
GrTextContext* fTextContext;
-
- // state for our render-target
+ SkSurfaceProps fSurfaceProps;
GrRenderTarget* fRenderTarget;
- uint32_t fFlags;
-
// remove when our clients don't rely on accessBitmap()
- SkBitmap fLegacyBitmap;
+ SkBitmap fLegacyBitmap;
+ bool fNeedClear;
- SkGpuDevice(GrSurface*, const SkSurfaceProps&, unsigned flags = 0);
+ SkGpuDevice(GrRenderTarget*, const SkSurfaceProps*, unsigned flags);
SkBaseDevice* onCreateCompatibleDevice(const CreateInfo&) SK_OVERRIDE;