aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar Brian Osman <brianosman@google.com>2016-11-23 09:37:01 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-11-23 15:52:27 +0000
commit45580d3e3024c1536e8e1b2017b704805442b634 (patch)
tree9ed9fe3bdc0d949ec8e83b06691b37b6ffdcc54a /src/gpu
parent07764cefbb18041a77897df3453903b0a2016583 (diff)
Added GrSurfaceContext and GrTextureContext
This lets copy-to-texture to be treated like copy-to-rt. To match current behavior, though, copies to texture are still executed immediately (forcing a flush). Once MDB is enabled, copies to texture will be deferred. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=5093 Change-Id: Icc0ce5435507a5f0a237c22eedef879824952367 Reviewed-on: https://skia-review.googlesource.com/5093 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrContext.cpp47
-rw-r--r--src/gpu/GrContextPriv.h4
-rw-r--r--src/gpu/GrDrawingManager.cpp34
-rw-r--r--src/gpu/GrDrawingManager.h4
-rw-r--r--src/gpu/GrOpList.h12
-rw-r--r--src/gpu/GrRenderTargetContext.cpp8
-rw-r--r--src/gpu/GrRenderTargetOpList.h2
-rw-r--r--src/gpu/GrRenderTargetProxy.cpp11
-rw-r--r--src/gpu/GrSurfaceContext.cpp26
-rw-r--r--src/gpu/GrSurfaceProxy.cpp17
-rw-r--r--src/gpu/GrTextureContext.cpp83
-rw-r--r--src/gpu/GrTextureOpList.h2
12 files changed, 213 insertions, 37 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 1a5ee20721..7b789bd08d 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -14,7 +14,9 @@
#include "GrResourceProvider.h"
#include "GrRenderTargetProxy.h"
#include "GrSoftwarePathRenderer.h"
+#include "GrSurfaceContext.h"
#include "GrSurfacePriv.h"
+#include "GrTextureContext.h"
#include "SkConfig8888.h"
#include "SkGrPriv.h"
@@ -557,31 +559,23 @@ bool GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRe
return false;
}
- if (!dst->asRenderTarget()) {
- SkIRect clippedSrcRect;
- SkIPoint clippedDstPoint;
- if (!GrCopySurfaceBatch::ClipSrcRectAndDstPoint(dst, src, srcRect, dstPoint,
- &clippedSrcRect, &clippedDstPoint)) {
- return false;
- }
- // If we don't have an RT for the dst then we won't have a GrRenderTargetContext to insert
- // the copy surface into. In the future we plan to have a more limited Context type
- // (GrCopyContext?) that has the subset of GrRenderTargetContext operations that should be
- // allowed on textures that aren't render targets.
- // For now we just flush any writes to the src and issue an immediate copy to the dst.
- src->flushWrites();
- return fGpu->copySurface(dst, src, clippedSrcRect, clippedDstPoint);
- }
- sk_sp<GrRenderTargetContext> renderTargetContext(
- this->contextPriv().makeWrappedRenderTargetContext(sk_ref_sp(dst->asRenderTarget()),
- nullptr));
- if (!renderTargetContext) {
+#ifndef ENABLE_MDB
+ // We can't yet fully defer copies to textures, so GrTextureContext::copySurface will
+ // execute the copy immediately. Ensure the data is ready.
+ src->flushWrites();
+#endif
+
+ sk_sp<GrSurfaceContext> surfaceContext(
+ this->contextPriv().makeWrappedSurfaceContext(sk_ref_sp(dst)));
+
+ if (!surfaceContext) {
return false;
}
- if (!renderTargetContext->copySurface(src, srcRect, dstPoint)) {
+ if (!surfaceContext->copySurface(src, srcRect, dstPoint)) {
return false;
}
+
return true;
}
@@ -633,6 +627,19 @@ sk_sp<GrRenderTargetContext> GrContextPriv::makeWrappedRenderTargetContext(
surfaceProps);
}
+sk_sp<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(sk_sp<GrSurface> surface) {
+ ASSERT_SINGLE_OWNER_PRIV
+
+ sk_sp<GrSurfaceProxy> proxy(GrSurfaceProxy::MakeWrapped(std::move(surface)));
+
+ if (proxy->asRenderTargetProxy()) {
+ return this->drawingManager()->makeRenderTargetContext(std::move(proxy), nullptr, nullptr);
+ } else {
+ SkASSERT(proxy->asTextureProxy());
+ return this->drawingManager()->makeTextureContext(std::move(proxy));
+ }
+}
+
sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendTextureRenderTargetContext(
const GrBackendTextureDesc& desc,
sk_sp<SkColorSpace> colorSpace,
diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h
index d2fa7c1610..dcf0807507 100644
--- a/src/gpu/GrContextPriv.h
+++ b/src/gpu/GrContextPriv.h
@@ -9,6 +9,7 @@
#define GrContextPriv_DEFINED
#include "GrContext.h"
+#include "GrSurfaceContext.h"
/** Class that adds methods to GrContext that are only intended for use internal to Skia.
This class is purely a privileged window into GrContext. It should never have additional
@@ -22,6 +23,9 @@ public:
sk_sp<SkColorSpace> colorSpace,
const SkSurfaceProps* = nullptr);
+ // Create a surfaceContext that wraps an existing texture or renderTarget
+ sk_sp<GrSurfaceContext> makeWrappedSurfaceContext(sk_sp<GrSurface> tex);
+
sk_sp<GrRenderTargetContext> makeBackendTextureRenderTargetContext(
const GrBackendTextureDesc& desc,
sk_sp<SkColorSpace> colorSpace,
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index 5267df3626..e1dff8b14f 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -14,6 +14,8 @@
#include "GrResourceProvider.h"
#include "GrSoftwarePathRenderer.h"
#include "GrSurfacePriv.h"
+#include "GrTextureContext.h"
+#include "GrTextureOpList.h"
#include "SkSurface_Gpu.h"
#include "SkTTopoSort.h"
@@ -172,6 +174,24 @@ GrRenderTargetOpList* GrDrawingManager::newOpList(GrRenderTargetProxy* rtp) {
return SkRef(opList);
}
+GrTextureOpList* GrDrawingManager::newOpList(GrTextureProxy* textureProxy) {
+ SkASSERT(fContext);
+
+ GrTextureOpList* opList = new GrTextureOpList(textureProxy, fContext->getGpu(),
+ fContext->getAuditTrail());
+
+#ifndef ENABLE_MDB
+ // When MDB is disabled we still create a new GrOpList, but don't store or ref it - we rely
+ // on the caller to immediately execute and free it.
+ return opList;
+#else
+ *fOpLists.append() = opList;
+
+ // Drawing manager gets the creation ref - this ref is for the caller
+ return SkRef(opList);
+#endif
+}
+
GrAtlasTextContext* GrDrawingManager::getAtlasTextContext() {
if (!fAtlasTextContext) {
fAtlasTextContext.reset(GrAtlasTextContext::Create());
@@ -253,3 +273,17 @@ sk_sp<GrRenderTargetContext> GrDrawingManager::makeRenderTargetContext(
fContext->getAuditTrail(),
fSingleOwner));
}
+
+sk_sp<GrTextureContext> GrDrawingManager::makeTextureContext(sk_sp<GrSurfaceProxy> sProxy) {
+ if (this->wasAbandoned() || !sProxy->asTextureProxy()) {
+ return nullptr;
+ }
+
+ // GrTextureRenderTargets should always be using GrRenderTargetContext
+ SkASSERT(!sProxy->asRenderTargetProxy());
+
+ sk_sp<GrTextureProxy> textureProxy(sk_ref_sp(sProxy->asTextureProxy()));
+
+ return sk_sp<GrTextureContext>(new GrTextureContext(fContext, this, std::move(textureProxy),
+ fContext->getAuditTrail(), fSingleOwner));
+}
diff --git a/src/gpu/GrDrawingManager.h b/src/gpu/GrDrawingManager.h
index 3816868c75..90a3064e24 100644
--- a/src/gpu/GrDrawingManager.h
+++ b/src/gpu/GrDrawingManager.h
@@ -22,6 +22,8 @@ class GrRenderTargetContext;
class GrRenderTargetProxy;
class GrSingleOWner;
class GrSoftwarePathRenderer;
+class GrTextureContext;
+class GrTextureOpList;
// The GrDrawingManager allocates a new GrRenderTargetContext for each GrRenderTarget
// but all of them still land in the same GrOpList!
@@ -38,10 +40,12 @@ public:
sk_sp<GrRenderTargetContext> makeRenderTargetContext(sk_sp<GrSurfaceProxy>,
sk_sp<SkColorSpace>,
const SkSurfaceProps*);
+ sk_sp<GrTextureContext> makeTextureContext(sk_sp<GrSurfaceProxy>);
// The caller automatically gets a ref on the returned opList. It must
// be balanced by an unref call.
GrRenderTargetOpList* newOpList(GrRenderTargetProxy* rtp);
+ GrTextureOpList* newOpList(GrTextureProxy* textureProxy);
GrContext* getContext() { return fContext; }
diff --git a/src/gpu/GrOpList.h b/src/gpu/GrOpList.h
index 9c965f8f0f..313807d63c 100644
--- a/src/gpu/GrOpList.h
+++ b/src/gpu/GrOpList.h
@@ -15,8 +15,10 @@
class GrAuditTrail;
class GrBatchFlushState;
+class GrRenderTargetOpList;
class GrSurface;
class GrSurfaceProxy;
+class GrTextureOpList;
class GrOpList : public SkRefCnt {
public:
@@ -62,6 +64,16 @@ public:
}
/*
+ * Safely cast this GrOpList to a GrTextureOpList (if possible).
+ */
+ virtual GrTextureOpList* asTextureOpList() { return nullptr; }
+
+ /*
+ * Safely case this GrOpList to a GrRenderTargetOpList (if possible).
+ */
+ virtual GrRenderTargetOpList* asRenderTargetOpList() { return nullptr; }
+
+ /*
* Dump out the GrOpList dependency DAG
*/
SkDEBUGCODE(virtual void dump() const;)
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 6238fa8025..f08f39a1be 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -81,18 +81,14 @@ GrRenderTargetContext::GrRenderTargetContext(GrContext* context,
const SkSurfaceProps* surfaceProps,
GrAuditTrail* auditTrail,
GrSingleOwner* singleOwner)
- : fDrawingManager(drawingMgr)
+ : GrSurfaceContext(context, auditTrail, singleOwner)
+ , fDrawingManager(drawingMgr)
, fRenderTargetProxy(std::move(rtp))
, fOpList(SkSafeRef(fRenderTargetProxy->getLastRenderTargetOpList()))
- , fContext(context)
, fInstancedPipelineInfo(fRenderTargetProxy.get())
, fColorSpace(std::move(colorSpace))
, fColorXformFromSRGB(nullptr)
, fSurfaceProps(SkSurfacePropsCopyOrDefault(surfaceProps))
- , fAuditTrail(auditTrail)
-#ifdef SK_DEBUG
- , fSingleOwner(singleOwner)
-#endif
{
if (fColorSpace) {
// sRGB sources are very common (SkColor, etc...), so we cache that gamut transformation
diff --git a/src/gpu/GrRenderTargetOpList.h b/src/gpu/GrRenderTargetOpList.h
index b084d48291..d96f83d21a 100644
--- a/src/gpu/GrRenderTargetOpList.h
+++ b/src/gpu/GrRenderTargetOpList.h
@@ -127,6 +127,8 @@ public:
return fInstancedRendering.get();
}
+ GrRenderTargetOpList* asRenderTargetOpList() override { return this; }
+
SkDEBUGCODE(void dump() const override;)
private:
diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp
index cb9b97a4a9..03637cf9af 100644
--- a/src/gpu/GrRenderTargetProxy.cpp
+++ b/src/gpu/GrRenderTargetProxy.cpp
@@ -54,17 +54,6 @@ GrRenderTarget* GrRenderTargetProxy::instantiate(GrTextureProvider* texProvider)
return surf->asRenderTarget();
}
-
-#ifdef SK_DEBUG
-void GrRenderTargetProxy::validate(GrContext* context) const {
- if (fTarget) {
- SkASSERT(fTarget->getContext() == context);
- }
-
- INHERITED::validate();
-}
-#endif
-
size_t GrRenderTargetProxy::onGpuMemorySize() const {
if (fTarget) {
return fTarget->gpuMemorySize();
diff --git a/src/gpu/GrSurfaceContext.cpp b/src/gpu/GrSurfaceContext.cpp
new file mode 100644
index 0000000000..682233bd1c
--- /dev/null
+++ b/src/gpu/GrSurfaceContext.cpp
@@ -0,0 +1,26 @@
+/*
+ * 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 "GrSurfaceContext.h"
+
+#include "../private/GrAuditTrail.h"
+
+
+// In MDB mode the reffing of the 'getLastOpList' call's result allows in-progress
+// GrOpLists to be picked up and added to by renderTargetContexts lower in the call
+// stack. When this occurs with a closed GrOpList, a new one will be allocated
+// when the renderTargetContext attempts to use it (via getOpList).
+GrSurfaceContext::GrSurfaceContext(GrContext* context,
+ GrAuditTrail* auditTrail,
+ GrSingleOwner* singleOwner)
+ : fContext(context)
+ , fAuditTrail(auditTrail)
+#ifdef SK_DEBUG
+ , fSingleOwner(singleOwner)
+#endif
+{
+}
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index 9de41ef482..95fc8b9a8a 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -66,6 +66,14 @@ void GrSurfaceProxy::setLastOpList(GrOpList* opList) {
SkRefCnt_SafeAssign(fLastOpList, opList);
}
+GrRenderTargetOpList* GrSurfaceProxy::getLastRenderTargetOpList() {
+ return fLastOpList ? fLastOpList->asRenderTargetOpList() : nullptr;
+}
+
+GrTextureOpList* GrSurfaceProxy::getLastTextureOpList() {
+ return fLastOpList ? fLastOpList->asTextureOpList() : nullptr;
+}
+
sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeWrapped(sk_sp<GrSurface> surf) {
if (surf->asTexture()) {
if (surf->asRenderTarget()) {
@@ -109,3 +117,12 @@ sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeDeferred(const GrCaps& caps,
return GrSurfaceProxy::MakeDeferred(caps, desc, SkBackingFit::kExact, budgeted);
}
+#ifdef SK_DEBUG
+void GrSurfaceProxy::validate(GrContext* context) const {
+ if (fTarget) {
+ SkASSERT(fTarget->getContext() == context);
+ }
+
+ INHERITED::validate();
+}
+#endif
diff --git a/src/gpu/GrTextureContext.cpp b/src/gpu/GrTextureContext.cpp
new file mode 100644
index 0000000000..5c0c17b728
--- /dev/null
+++ b/src/gpu/GrTextureContext.cpp
@@ -0,0 +1,83 @@
+/*
+ * 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 "GrTextureContext.h"
+#include "GrDrawingManager.h"
+#include "GrResourceProvider.h"
+#include "GrTextureOpList.h"
+
+#include "../private/GrAuditTrail.h"
+
+#define ASSERT_SINGLE_OWNER \
+ SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
+#define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return false; }
+
+GrTextureContext::GrTextureContext(GrContext* context,
+ GrDrawingManager* drawingMgr,
+ sk_sp<GrTextureProxy> textureProxy,
+ GrAuditTrail* auditTrail,
+ GrSingleOwner* singleOwner)
+ : GrSurfaceContext(context, auditTrail, singleOwner)
+ , fDrawingManager(drawingMgr)
+ , fTextureProxy(std::move(textureProxy))
+ , fOpList(SkSafeRef(fTextureProxy->getLastTextureOpList()))
+{
+ SkDEBUGCODE(this->validate();)
+}
+
+#ifdef SK_DEBUG
+void GrTextureContext::validate() const {
+ SkASSERT(fTextureProxy);
+ fTextureProxy->validate(fContext);
+
+ if (fOpList && !fOpList->isClosed()) {
+ SkASSERT(fTextureProxy->getLastOpList() == fOpList);
+ }
+}
+#endif
+
+GrTextureContext::~GrTextureContext() {
+ ASSERT_SINGLE_OWNER
+ SkSafeUnref(fOpList);
+}
+
+GrTextureOpList* GrTextureContext::getOpList() {
+ ASSERT_SINGLE_OWNER
+ SkDEBUGCODE(this->validate();)
+
+ if (!fOpList || fOpList->isClosed()) {
+ fOpList = fDrawingManager->newOpList(fTextureProxy.get());
+ }
+
+ return fOpList;
+}
+
+bool GrTextureContext::copySurface(GrSurface* src, const SkIRect& srcRect,
+ const SkIPoint& dstPoint) {
+ ASSERT_SINGLE_OWNER
+ RETURN_FALSE_IF_ABANDONED
+ SkDEBUGCODE(this->validate();)
+ GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrTextureContext::copySurface");
+
+ // TODO: this needs to be fixed up since it ends the deferrable of the GrTexture
+ sk_sp<GrTexture> tex(sk_ref_sp(fTextureProxy->instantiate(fContext->textureProvider())));
+ if (!tex) {
+ return false;
+ }
+
+ GrTextureOpList* opList = this->getOpList();
+ bool result = opList->copySurface(tex.get(), src, srcRect, dstPoint);
+
+#ifndef ENABLE_MDB
+ GrBatchFlushState flushState(fContext->getGpu(), nullptr);
+ opList->prepareBatches(&flushState);
+ opList->drawBatches(&flushState);
+ opList->reset();
+#endif
+
+ return result;
+}
diff --git a/src/gpu/GrTextureOpList.h b/src/gpu/GrTextureOpList.h
index 33ca656cf6..7674184890 100644
--- a/src/gpu/GrTextureOpList.h
+++ b/src/gpu/GrTextureOpList.h
@@ -55,6 +55,8 @@ public:
const SkIRect& srcRect,
const SkIPoint& dstPoint);
+ GrTextureOpList* asTextureOpList() override { return this; }
+
SkDEBUGCODE(void dump() const override;)
private: