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>
"$_include/gpu/GrResourceKey.h",
"$_include/gpu/GrShaderVar.h",
"$_include/gpu/GrSurface.h",
+ "$_include/gpu/GrSurfaceContext.h",
"$_include/gpu/GrTexture.h",
+ "$_include/gpu/GrTextureContext.h",
"$_include/gpu/GrSamplerParams.h",
"$_include/gpu/GrTextureProvider.h",
"$_include/gpu/GrTestUtils.h",
"$_src/gpu/GrSoftwarePathRenderer.h",
"$_src/gpu/GrSurfacePriv.h",
"$_src/gpu/GrSurface.cpp",
+ "$_src/gpu/GrSurfaceContext.cpp",
"$_src/gpu/GrSurfaceProxy.cpp",
"$_src/gpu/GrSwizzle.h",
"$_src/gpu/GrTexture.cpp",
+ "$_src/gpu/GrTextureContext.cpp",
"$_src/gpu/GrTextureParamsAdjuster.h",
"$_src/gpu/GrTextureParamsAdjuster.cpp",
"$_src/gpu/GrTexturePriv.h",
GrRenderTargetPriv renderTargetPriv();
const GrRenderTargetPriv renderTargetPriv() const;
- GrRenderTargetOpList* getLastRenderTargetOpList() {
- return (GrRenderTargetOpList*) this->getLastOpList();
- }
-
protected:
enum class Flags {
kNone = 0,
#include "GrColor.h"
#include "GrContext.h"
#include "GrPaint.h"
-#include "GrRenderTarget.h"
+#include "GrSurfaceContext.h"
#include "SkRefCnt.h"
-#include "SkRegion.h"
#include "SkSurfaceProps.h"
#include "../private/GrInstancedPipelineInfo.h"
#include "../private/GrRenderTargetProxy.h"
-#include "../private/GrSingleOwner.h"
-class GrAuditTrail;
class GrClip;
class GrDrawBatch;
-class GrRenderTargetContextPriv;
-class GrDrawPathBatchBase;
class GrDrawingManager;
class GrFixedClip;
-class GrPaint;
-class GrPathProcessor;
class GrPipelineBuilder;
class GrRenderTarget;
+class GrRenderTargetContextPriv;
class GrRenderTargetOpList;
class GrStyle;
class GrSurface;
class SkPath;
struct SkPoint;
struct SkRect;
+class SkRegion;
class SkRRect;
struct SkRSXform;
class SkTextBlob;
-/*
- * A helper object to orchestrate draws
+/**
+ * A helper object to orchestrate commands (draws, etc...) for GrSurfaces that are GrRenderTargets.
*/
-class SK_API GrRenderTargetContext : public SkRefCnt {
+class SK_API GrRenderTargetContext : public GrSurfaceContext {
public:
~GrRenderTargetContext() override;
- bool copySurface(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint);
+ bool copySurface(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
// TODO: it is odd that we need both the SkPaint in the following 3 methods.
// We should extract the text parameters from SkPaint and pass them separately
GrRenderTargetContextPriv priv();
const GrRenderTargetContextPriv priv() const;
- GrAuditTrail* auditTrail() { return fAuditTrail; }
-
bool isWrapped_ForTesting() const;
protected:
GrDrawingManager* drawingManager() { return fDrawingManager; }
- SkDEBUGCODE(GrSingleOwner* singleOwner() { return fSingleOwner; })
SkDEBUGCODE(void validate() const;)
private:
// In MDB-mode the GrOpList can be closed by some other renderTargetContext that has picked
// it up. For this reason, the GrOpList should only ever be accessed via 'getOpList'.
GrRenderTargetOpList* fOpList;
- GrContext* fContext;
GrInstancedPipelineInfo fInstancedPipelineInfo;
sk_sp<SkColorSpace> fColorSpace;
sk_sp<GrColorSpaceXform> fColorXformFromSRGB;
SkSurfaceProps fSurfaceProps;
- GrAuditTrail* fAuditTrail;
-
- // In debug builds we guard against improper thread handling
- SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;)
};
#endif
--- /dev/null
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrSurfaceContext_DEFINED
+#define GrSurfaceContext_DEFINED
+
+#include "SkRefCnt.h"
+
+class GrAuditTrail;
+class GrContext;
+class GrSingleOwner;
+class GrSurface;
+struct SkIPoint;
+struct SkIRect;
+
+/**
+ * A helper object to orchestrate commands for a particular surface
+ */
+class SK_API GrSurfaceContext : public SkRefCnt {
+public:
+ ~GrSurfaceContext() override {}
+
+ virtual bool copySurface(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) = 0;
+
+ GrAuditTrail* auditTrail() { return fAuditTrail; }
+
+protected:
+ GrSurfaceContext(GrContext*, GrAuditTrail*, GrSingleOwner*);
+
+ SkDEBUGCODE(GrSingleOwner* singleOwner() { return fSingleOwner; })
+
+ GrContext* fContext;
+ GrAuditTrail* fAuditTrail;
+
+ // In debug builds we guard against improper thread handling
+ SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;)
+};
+
+#endif
--- /dev/null
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrTextureContext_DEFINED
+#define GrTextureContext_DEFINED
+
+#include "GrSurfaceContext.h"
+#include "../private/GrTextureProxy.h"
+
+class GrContext;
+class GrDrawingManager;
+class GrSurface;
+class GrTextureOpList;
+class GrTextureProxy;
+struct SkIPoint;
+struct SkIRect;
+
+/**
+ * A helper object to orchestrate commands (currently just copies) for GrSurfaces that are
+ * GrTextures and not GrRenderTargets.
+ */
+class SK_API GrTextureContext : public GrSurfaceContext {
+public:
+ ~GrTextureContext() override;
+
+ bool copySurface(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
+
+protected:
+ GrTextureContext(GrContext*, GrDrawingManager*, sk_sp<GrTextureProxy>, GrAuditTrail*,
+ GrSingleOwner*);
+
+ GrDrawingManager* drawingManager() { return fDrawingManager; }
+
+ SkDEBUGCODE(void validate() const;)
+
+private:
+ friend class GrDrawingManager; // for ctor
+
+ GrTextureOpList* getOpList();
+
+ GrDrawingManager* fDrawingManager;
+ sk_sp<GrTextureProxy> fTextureProxy;
+
+ // In MDB-mode the GrOpList can be closed by some other renderTargetContext that has picked
+ // it up. For this reason, the GrOpList should only ever be accessed via 'getOpList'.
+ GrTextureOpList* fOpList;
+};
+
+#endif
GrRenderTarget::Flags testingOnly_getFlags() const;
- GrRenderTargetOpList* getLastRenderTargetOpList() {
- return (GrRenderTargetOpList*) this->getLastOpList();
- }
-
- SkDEBUGCODE(void validate(GrContext*) const;)
-
protected:
friend class GrSurfaceProxy; // for ctors
#include "SkRect.h"
class GrCaps;
-class GrOpList;
-class GrTextureProvider;
-class GrTextureProxy;
+class GrRenderTargetOpList;
class GrRenderTargetProxy;
+class GrTextureOpList;
class GrTextureProvider;
+class GrTextureProxy;
// This class replicates the functionality GrIORef<GrSurface> but tracks the
// utilitization for later resource allocation (for the deferred case) and
void setLastOpList(GrOpList* opList);
GrOpList* getLastOpList() { return fLastOpList; }
+ GrRenderTargetOpList* getLastRenderTargetOpList();
+ GrTextureOpList* getLastTextureOpList();
+
/**
* Retrieves the amount of GPU memory that will be or currently is used by this resource
* in bytes. It is approximate since we aren't aware of additional padding or copies made
bool isWrapped_ForTesting() const;
+ SkDEBUGCODE(void validate(GrContext*) const;)
+
protected:
// Deferred version
GrSurfaceProxy(const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted)
#include "GrTexture.h"
class GrCaps;
+class GrTextureOpList;
class GrTextureProvider;
// This class delays the acquisition of textures until they are actually required
#include "GrResourceProvider.h"
#include "GrRenderTargetProxy.h"
#include "GrSoftwarePathRenderer.h"
+#include "GrSurfaceContext.h"
#include "GrSurfacePriv.h"
+#include "GrTextureContext.h"
#include "SkConfig8888.h"
#include "SkGrPriv.h"
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;
}
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,
#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
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,
#include "GrResourceProvider.h"
#include "GrSoftwarePathRenderer.h"
#include "GrSurfacePriv.h"
+#include "GrTextureContext.h"
+#include "GrTextureOpList.h"
#include "SkSurface_Gpu.h"
#include "SkTTopoSort.h"
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());
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));
+}
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!
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; }
class GrAuditTrail;
class GrBatchFlushState;
+class GrRenderTargetOpList;
class GrSurface;
class GrSurfaceProxy;
+class GrTextureOpList;
class GrOpList : public SkRefCnt {
public:
return fDependencies.find(dependedOn) >= 0;
}
+ /*
+ * 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
*/
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
return fInstancedRendering.get();
}
+ GrRenderTargetOpList* asRenderTargetOpList() override { return this; }
+
SkDEBUGCODE(void dump() const override;)
private:
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();
--- /dev/null
+/*
+ * 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
+{
+}
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()) {
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
--- /dev/null
+/*
+ * 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;
+}
const SkIRect& srcRect,
const SkIPoint& dstPoint);
+ GrTextureOpList* asTextureOpList() override { return this; }
+
SkDEBUGCODE(void dump() const override;)
private: