blob: 4a0c3480a41c677dc47cc6c0b4383c8f33d65966 [file] [log] [blame]
robertphillips76948d42016-05-04 12:47:41 -07001/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "GrSurfaceProxy.h"
9
Robert Phillips784b7bf2016-12-09 13:35:02 -050010#include "GrCaps.h"
Robert Phillipsc7635fa2016-10-28 13:25:24 -040011#include "GrGpuResourcePriv.h"
Robert Phillipsf2361d22016-10-25 14:20:06 -040012#include "GrOpList.h"
Robert Phillipseaa86252016-11-08 13:49:39 +000013#include "GrTextureProvider.h"
Robert Phillips37430132016-11-09 06:50:43 -050014#include "GrTextureRenderTargetProxy.h"
Robert Phillipsf2361d22016-10-25 14:20:06 -040015
Robert Phillips93f16332016-11-23 19:37:13 -050016#include "SkMathPriv.h"
17
Robert Phillipsc7635fa2016-10-28 13:25:24 -040018GrSurfaceProxy::GrSurfaceProxy(sk_sp<GrSurface> surface, SkBackingFit fit)
19 : INHERITED(std::move(surface))
20 , fDesc(fTarget->desc())
21 , fFit(fit)
22 , fBudgeted(fTarget->resourcePriv().isBudgeted())
Robert Phillips294870f2016-11-11 12:38:40 -050023 , fUniqueID(fTarget->uniqueID()) // Note: converting from unique resource ID to a proxy ID!
Robert Phillips8bc06d02016-11-01 17:28:40 -040024 , fGpuMemorySize(kInvalidGpuMemorySize)
Robert Phillipsc7635fa2016-10-28 13:25:24 -040025 , fLastOpList(nullptr) {
26}
27
Robert Phillipsf2361d22016-10-25 14:20:06 -040028GrSurfaceProxy::~GrSurfaceProxy() {
29 if (fLastOpList) {
30 fLastOpList->clearTarget();
31 }
32 SkSafeUnref(fLastOpList);
33}
34
Robert Phillipseaa86252016-11-08 13:49:39 +000035GrSurface* GrSurfaceProxy::instantiate(GrTextureProvider* texProvider) {
36 if (fTarget) {
37 return fTarget;
38 }
39
40 if (SkBackingFit::kApprox == fFit) {
41 fTarget = texProvider->createApproxTexture(fDesc);
42 } else {
43 fTarget = texProvider->createTexture(fDesc, fBudgeted);
44 }
45 if (!fTarget) {
46 return nullptr;
47 }
48
robertphillips1125a032016-11-16 11:17:17 -080049 this->INHERITED::transferRefs();
50
Robert Phillipseaa86252016-11-08 13:49:39 +000051#ifdef SK_DEBUG
52 if (kInvalidGpuMemorySize != this->getRawGpuMemorySize_debugOnly()) {
Robert Phillips784b7bf2016-12-09 13:35:02 -050053 SkASSERT(fTarget->gpuMemorySize() <= this->getRawGpuMemorySize_debugOnly());
Robert Phillipseaa86252016-11-08 13:49:39 +000054 }
55#endif
56
57 return fTarget;
58}
59
Robert Phillips784b7bf2016-12-09 13:35:02 -050060int GrSurfaceProxy::worstCaseWidth(const GrCaps& caps) const {
Robert Phillips93f16332016-11-23 19:37:13 -050061 if (fTarget) {
62 return fTarget->width();
63 }
64
65 if (SkBackingFit::kExact == fFit) {
66 return fDesc.fWidth;
67 }
68
Robert Phillips784b7bf2016-12-09 13:35:02 -050069 if (caps.reuseScratchTextures() || fDesc.fFlags & kRenderTarget_GrSurfaceFlag) {
70 return SkTMax(GrTextureProvider::kMinScratchTextureSize, GrNextPow2(fDesc.fWidth));
71 }
72
73 return fDesc.fWidth;
Robert Phillips93f16332016-11-23 19:37:13 -050074}
75
Robert Phillips784b7bf2016-12-09 13:35:02 -050076int GrSurfaceProxy::worstCaseHeight(const GrCaps& caps) const {
Robert Phillips93f16332016-11-23 19:37:13 -050077 if (fTarget) {
78 return fTarget->height();
79 }
80
81 if (SkBackingFit::kExact == fFit) {
82 return fDesc.fHeight;
83 }
84
Robert Phillips784b7bf2016-12-09 13:35:02 -050085 if (caps.reuseScratchTextures() || fDesc.fFlags & kRenderTarget_GrSurfaceFlag) {
86 return SkTMax(GrTextureProvider::kMinScratchTextureSize, GrNextPow2(fDesc.fHeight));
87 }
88
89 return fDesc.fHeight;
Robert Phillips93f16332016-11-23 19:37:13 -050090}
91
Robert Phillipsf2361d22016-10-25 14:20:06 -040092void GrSurfaceProxy::setLastOpList(GrOpList* opList) {
93 if (fLastOpList) {
94 // The non-MDB world never closes so we can't check this condition
95#ifdef ENABLE_MDB
96 SkASSERT(fLastOpList->isClosed());
97#endif
98 fLastOpList->clearTarget();
99 }
100
101 SkRefCnt_SafeAssign(fLastOpList, opList);
102}
Robert Phillips37430132016-11-09 06:50:43 -0500103
Brian Osman45580d32016-11-23 09:37:01 -0500104GrRenderTargetOpList* GrSurfaceProxy::getLastRenderTargetOpList() {
105 return fLastOpList ? fLastOpList->asRenderTargetOpList() : nullptr;
106}
107
108GrTextureOpList* GrSurfaceProxy::getLastTextureOpList() {
109 return fLastOpList ? fLastOpList->asTextureOpList() : nullptr;
110}
111
Robert Phillips37430132016-11-09 06:50:43 -0500112sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeWrapped(sk_sp<GrSurface> surf) {
113 if (surf->asTexture()) {
114 if (surf->asRenderTarget()) {
115 return sk_sp<GrSurfaceProxy>(new GrTextureRenderTargetProxy(std::move(surf)));
116 } else {
117 return sk_sp<GrSurfaceProxy>(new GrTextureProxy(std::move(surf)));
118 }
119 } else {
120 SkASSERT(surf->asRenderTarget());
121
122 // Not texturable
123 return sk_sp<GrSurfaceProxy>(new GrRenderTargetProxy(std::move(surf)));
124 }
125}
126
127sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeDeferred(const GrCaps& caps,
128 const GrSurfaceDesc& desc,
129 SkBackingFit fit,
130 SkBudgeted budgeted) {
131 if (kRenderTarget_GrSurfaceFlag & desc.fFlags) {
132 // We know anything we instantiate later from this deferred path will be
133 // both texturable and renderable
134 return sk_sp<GrSurfaceProxy>(new GrTextureRenderTargetProxy(caps, desc, fit, budgeted));
135 }
136
137 return sk_sp<GrSurfaceProxy>(new GrTextureProxy(desc, fit, budgeted, nullptr, 0));
138}
139
140sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeDeferred(const GrCaps& caps,
141 GrTextureProvider* texProvider,
142 const GrSurfaceDesc& desc,
143 SkBudgeted budgeted,
144 const void* srcData,
145 size_t rowBytes) {
146 if (srcData) {
147 // If we have srcData, for now, we create a wrapped GrTextureProxy
148 sk_sp<GrSurface> surf(texProvider->createTexture(desc, budgeted, srcData, rowBytes));
149 return GrSurfaceProxy::MakeWrapped(std::move(surf));
150 }
151
152 return GrSurfaceProxy::MakeDeferred(caps, desc, SkBackingFit::kExact, budgeted);
153}
154
Brian Osman45580d32016-11-23 09:37:01 -0500155#ifdef SK_DEBUG
156void GrSurfaceProxy::validate(GrContext* context) const {
157 if (fTarget) {
158 SkASSERT(fTarget->getContext() == context);
159 }
160
161 INHERITED::validate();
162}
163#endif