blob: 780ff8aa449a75d5899ec5b8db1367286ec33497 [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 Phillipse2f7d182016-12-15 09:23:05 -050011#include "GrContext.h"
12#include "GrContextPriv.h"
Robert Phillipsc7635fa2016-10-28 13:25:24 -040013#include "GrGpuResourcePriv.h"
Robert Phillipsf2361d22016-10-25 14:20:06 -040014#include "GrOpList.h"
Robert Phillipse2f7d182016-12-15 09:23:05 -050015#include "GrSurfaceContext.h"
Robert Phillipseaa86252016-11-08 13:49:39 +000016#include "GrTextureProvider.h"
Robert Phillips37430132016-11-09 06:50:43 -050017#include "GrTextureRenderTargetProxy.h"
Robert Phillipsf2361d22016-10-25 14:20:06 -040018
Robert Phillips93f16332016-11-23 19:37:13 -050019#include "SkMathPriv.h"
20
Robert Phillipsc7635fa2016-10-28 13:25:24 -040021GrSurfaceProxy::GrSurfaceProxy(sk_sp<GrSurface> surface, SkBackingFit fit)
22 : INHERITED(std::move(surface))
23 , fDesc(fTarget->desc())
24 , fFit(fit)
25 , fBudgeted(fTarget->resourcePriv().isBudgeted())
Robert Phillips294870f2016-11-11 12:38:40 -050026 , fUniqueID(fTarget->uniqueID()) // Note: converting from unique resource ID to a proxy ID!
Robert Phillips8bc06d02016-11-01 17:28:40 -040027 , fGpuMemorySize(kInvalidGpuMemorySize)
Robert Phillipsc7635fa2016-10-28 13:25:24 -040028 , fLastOpList(nullptr) {
29}
30
Robert Phillipsf2361d22016-10-25 14:20:06 -040031GrSurfaceProxy::~GrSurfaceProxy() {
32 if (fLastOpList) {
33 fLastOpList->clearTarget();
34 }
35 SkSafeUnref(fLastOpList);
36}
37
Robert Phillipseaa86252016-11-08 13:49:39 +000038GrSurface* GrSurfaceProxy::instantiate(GrTextureProvider* texProvider) {
39 if (fTarget) {
40 return fTarget;
41 }
42
43 if (SkBackingFit::kApprox == fFit) {
44 fTarget = texProvider->createApproxTexture(fDesc);
45 } else {
46 fTarget = texProvider->createTexture(fDesc, fBudgeted);
47 }
48 if (!fTarget) {
49 return nullptr;
50 }
51
robertphillips1125a032016-11-16 11:17:17 -080052 this->INHERITED::transferRefs();
53
Robert Phillipseaa86252016-11-08 13:49:39 +000054#ifdef SK_DEBUG
55 if (kInvalidGpuMemorySize != this->getRawGpuMemorySize_debugOnly()) {
Robert Phillips784b7bf2016-12-09 13:35:02 -050056 SkASSERT(fTarget->gpuMemorySize() <= this->getRawGpuMemorySize_debugOnly());
Robert Phillipseaa86252016-11-08 13:49:39 +000057 }
58#endif
59
60 return fTarget;
61}
62
Robert Phillips784b7bf2016-12-09 13:35:02 -050063int GrSurfaceProxy::worstCaseWidth(const GrCaps& caps) const {
Robert Phillips93f16332016-11-23 19:37:13 -050064 if (fTarget) {
65 return fTarget->width();
66 }
67
68 if (SkBackingFit::kExact == fFit) {
69 return fDesc.fWidth;
70 }
71
Robert Phillips784b7bf2016-12-09 13:35:02 -050072 if (caps.reuseScratchTextures() || fDesc.fFlags & kRenderTarget_GrSurfaceFlag) {
73 return SkTMax(GrTextureProvider::kMinScratchTextureSize, GrNextPow2(fDesc.fWidth));
74 }
75
76 return fDesc.fWidth;
Robert Phillips93f16332016-11-23 19:37:13 -050077}
78
Robert Phillips784b7bf2016-12-09 13:35:02 -050079int GrSurfaceProxy::worstCaseHeight(const GrCaps& caps) const {
Robert Phillips93f16332016-11-23 19:37:13 -050080 if (fTarget) {
81 return fTarget->height();
82 }
83
84 if (SkBackingFit::kExact == fFit) {
85 return fDesc.fHeight;
86 }
87
Robert Phillips784b7bf2016-12-09 13:35:02 -050088 if (caps.reuseScratchTextures() || fDesc.fFlags & kRenderTarget_GrSurfaceFlag) {
89 return SkTMax(GrTextureProvider::kMinScratchTextureSize, GrNextPow2(fDesc.fHeight));
90 }
91
92 return fDesc.fHeight;
Robert Phillips93f16332016-11-23 19:37:13 -050093}
94
Robert Phillipsf2361d22016-10-25 14:20:06 -040095void GrSurfaceProxy::setLastOpList(GrOpList* opList) {
96 if (fLastOpList) {
97 // The non-MDB world never closes so we can't check this condition
98#ifdef ENABLE_MDB
99 SkASSERT(fLastOpList->isClosed());
100#endif
101 fLastOpList->clearTarget();
102 }
103
104 SkRefCnt_SafeAssign(fLastOpList, opList);
105}
Robert Phillips37430132016-11-09 06:50:43 -0500106
Brian Osman45580d32016-11-23 09:37:01 -0500107GrRenderTargetOpList* GrSurfaceProxy::getLastRenderTargetOpList() {
108 return fLastOpList ? fLastOpList->asRenderTargetOpList() : nullptr;
109}
110
111GrTextureOpList* GrSurfaceProxy::getLastTextureOpList() {
112 return fLastOpList ? fLastOpList->asTextureOpList() : nullptr;
113}
114
Robert Phillips37430132016-11-09 06:50:43 -0500115sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeWrapped(sk_sp<GrSurface> surf) {
116 if (surf->asTexture()) {
117 if (surf->asRenderTarget()) {
118 return sk_sp<GrSurfaceProxy>(new GrTextureRenderTargetProxy(std::move(surf)));
119 } else {
120 return sk_sp<GrSurfaceProxy>(new GrTextureProxy(std::move(surf)));
121 }
122 } else {
123 SkASSERT(surf->asRenderTarget());
124
125 // Not texturable
126 return sk_sp<GrSurfaceProxy>(new GrRenderTargetProxy(std::move(surf)));
127 }
128}
129
130sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeDeferred(const GrCaps& caps,
131 const GrSurfaceDesc& desc,
132 SkBackingFit fit,
133 SkBudgeted budgeted) {
134 if (kRenderTarget_GrSurfaceFlag & desc.fFlags) {
135 // We know anything we instantiate later from this deferred path will be
136 // both texturable and renderable
137 return sk_sp<GrSurfaceProxy>(new GrTextureRenderTargetProxy(caps, desc, fit, budgeted));
138 }
139
140 return sk_sp<GrSurfaceProxy>(new GrTextureProxy(desc, fit, budgeted, nullptr, 0));
141}
142
143sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeDeferred(const GrCaps& caps,
144 GrTextureProvider* texProvider,
145 const GrSurfaceDesc& desc,
146 SkBudgeted budgeted,
147 const void* srcData,
148 size_t rowBytes) {
149 if (srcData) {
150 // If we have srcData, for now, we create a wrapped GrTextureProxy
151 sk_sp<GrSurface> surf(texProvider->createTexture(desc, budgeted, srcData, rowBytes));
152 return GrSurfaceProxy::MakeWrapped(std::move(surf));
153 }
154
155 return GrSurfaceProxy::MakeDeferred(caps, desc, SkBackingFit::kExact, budgeted);
156}
157
Brian Osman45580d32016-11-23 09:37:01 -0500158#ifdef SK_DEBUG
159void GrSurfaceProxy::validate(GrContext* context) const {
160 if (fTarget) {
161 SkASSERT(fTarget->getContext() == context);
162 }
163
164 INHERITED::validate();
165}
166#endif
Robert Phillipse2f7d182016-12-15 09:23:05 -0500167
168sk_sp<GrSurfaceProxy> GrSurfaceProxy::Copy(GrContext* context,
169 GrSurfaceProxy* src,
170 SkIRect srcRect,
171 SkBudgeted budgeted) {
172 if (!srcRect.intersect(SkIRect::MakeWH(src->width(), src->height()))) {
173 return nullptr;
174 }
175
176 GrSurfaceDesc dstDesc = src->desc();
177 dstDesc.fWidth = srcRect.width();
178 dstDesc.fHeight = srcRect.height();
179
180 sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
181 dstDesc,
182 SkBackingFit::kExact,
183 budgeted));
184 if (!dstContext) {
185 return nullptr;
186 }
187
188 if (!dstContext->copy(src, srcRect, SkIPoint::Make(0, 0))) {
189 return nullptr;
190 }
191
192 return sk_ref_sp(dstContext->asDeferredSurface());
193}
194
195sk_sp<GrSurfaceProxy> GrSurfaceProxy::TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc,
196 GrTexture* srcTexture, SkBudgeted budgeted) {
197
198 sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
199 dstDesc,
200 SkBackingFit::kExact,
201 budgeted));
202 if (!dstContext) {
203 return nullptr;
204 }
205
206 sk_sp<GrSurfaceProxy> srcProxy(GrSurfaceProxy::MakeWrapped(sk_ref_sp(srcTexture)));
207 if (!srcProxy) {
208 return nullptr;
209 }
210
211 if (!dstContext->copy(srcProxy.get())) {
212 return nullptr;
213 }
214
215 return sk_ref_sp(dstContext->asDeferredSurface());
216}