Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(242)

Side by Side Diff: src/gpu/gl/GrGLRenderTarget.cpp

Issue 1810323002: Cache render targets that render to wrapped textures Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrGLRenderTarget.h" 8 #include "GrGLRenderTarget.h"
9 9
10 #include "GrRenderTargetPriv.h" 10 #include "GrRenderTargetPriv.h"
11 #include "GrGLGpu.h" 11 #include "GrGLGpu.h"
12 #include "GrGLUtil.h" 12 #include "GrGLUtil.h"
13 #include "SkTraceMemoryDump.h" 13 #include "SkTraceMemoryDump.h"
14 14
15 #define GPUGL static_cast<GrGLGpu*>(this->getGpu()) 15 #define GPUGL static_cast<GrGLGpu*>(this->getGpu())
16 #define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X) 16 #define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X)
17 17
18 // Because this class is virtually derived from GrSurface we must explicitly cal l its constructor. 18 // Because this class is virtually derived from GrSurface we must explicitly cal l its constructor.
19 GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu, 19 GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu,
20 SkBudgeted budgeted,
20 const GrSurfaceDesc& desc, 21 const GrSurfaceDesc& desc,
21 const IDDesc& idDesc, 22 const IDDesc& idDesc,
22 GrGLStencilAttachment* stencil) 23 GrGLStencilAttachment* stencil)
23 : GrSurface(gpu, idDesc.fLifeCycle, desc) 24 : GrSurface(gpu, budgeted, desc)
24 , INHERITED(gpu, idDesc.fLifeCycle, desc, idDesc.fSampleConfig, stencil) { 25 , INHERITED(gpu, budgeted, desc, idDesc.fSampleConfig, stencil)
25 this->init(desc, idDesc); 26 , fIDDesc(idDesc) {
27 this->init(desc);
26 this->registerWithCache(); 28 this->registerWithCache();
27 } 29 }
28 30
29 GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu, const GrSurfaceDesc& desc, cons t IDDesc& idDesc, 31 GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu, SkBudgeted budgeted, const GrSu rfaceDesc& desc,
30 Derived) 32 const IDDesc& idDesc, Derived)
31 : GrSurface(gpu, idDesc.fLifeCycle, desc) 33 : GrSurface(gpu, budgeted, desc)
32 , INHERITED(gpu, idDesc.fLifeCycle, desc, idDesc.fSampleConfig) { 34 , INHERITED(gpu, budgeted, desc, idDesc.fSampleConfig)
33 this->init(desc, idDesc); 35 , fIDDesc(idDesc) {
36 this->init(desc);
34 } 37 }
35 38
36 void GrGLRenderTarget::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) { 39 void GrGLRenderTarget::init(const GrSurfaceDesc& desc) {
37 fRTFBOID = idDesc.fRTFBOID;
38 fTexFBOID = idDesc.fTexFBOID;
39 fMSColorRenderbufferID = idDesc.fMSColorRenderbufferID;
40 fRTLifecycle = idDesc.fLifeCycle;
41
42 fViewport.fLeft = 0; 40 fViewport.fLeft = 0;
43 fViewport.fBottom = 0; 41 fViewport.fBottom = 0;
44 fViewport.fWidth = desc.fWidth; 42 fViewport.fWidth = desc.fWidth;
45 fViewport.fHeight = desc.fHeight; 43 fViewport.fHeight = desc.fHeight;
46 44
47 fGpuMemorySize = this->totalSamples() * this->totalBytesPerSample(); 45 fGpuMemorySize = this->totalSamples() * this->totalBytesPerSample();
48 46
49 SkASSERT(fGpuMemorySize <= WorseCaseSize(desc)); 47 SkASSERT(fGpuMemorySize <= WorseCaseSize(desc));
48 SkASSERT(GrBackendObjectLifeCycle::kBorrowed == fIDDesc.fTexLifeCycle ||
49 GrBackendObjectLifeCycle::kAdopted == fIDDesc.fTexLifeCycle);
50 } 50 }
51 51
52 GrGLRenderTarget* GrGLRenderTarget::CreateWrapped(GrGLGpu* gpu, 52 GrGLRenderTarget* GrGLRenderTarget::CreateWrapped(GrGLGpu* gpu,
53 SkBudgeted budgeted,
53 const GrSurfaceDesc& desc, 54 const GrSurfaceDesc& desc,
54 const IDDesc& idDesc, 55 const IDDesc& idDesc,
55 int stencilBits) { 56 int stencilBits) {
56 GrGLStencilAttachment* sb = nullptr; 57 GrGLStencilAttachment* sb = nullptr;
57 if (stencilBits) { 58 if (stencilBits) {
58 GrGLStencilAttachment::IDDesc sbDesc; 59 GrGLStencilAttachment::IDDesc sbDesc;
59 GrGLStencilAttachment::Format format; 60 GrGLStencilAttachment::Format format;
60 format.fInternalFormat = GrGLStencilAttachment::kUnknownInternalFormat; 61 format.fInternalFormat = GrGLStencilAttachment::kUnknownInternalFormat;
61 format.fPacked = false; 62 format.fPacked = false;
62 format.fStencilBits = stencilBits; 63 format.fStencilBits = stencilBits;
63 format.fTotalBits = stencilBits; 64 format.fTotalBits = stencilBits;
64 // Owndership of sb is passed to the GrRenderTarget so doesn't need to b e deleted 65 // Owndership of sb is passed to the GrRenderTarget so doesn't need to b e deleted
65 sb = new GrGLStencilAttachment(gpu, sbDesc, desc.fWidth, desc.fHeight, 66 sb = new GrGLStencilAttachment(gpu, sbDesc, desc.fWidth, desc.fHeight,
66 desc.fSampleCnt, format); 67 desc.fSampleCnt, format);
67 } 68 }
68 return (new GrGLRenderTarget(gpu, desc, idDesc, sb)); 69 return (new GrGLRenderTarget(gpu, budgeted, desc, idDesc, sb));
69 } 70 }
70 71
71 size_t GrGLRenderTarget::onGpuMemorySize() const { 72 size_t GrGLRenderTarget::onGpuMemorySize() const {
72 return fGpuMemorySize; 73 return fGpuMemorySize;
73 } 74 }
74 75
75 bool GrGLRenderTarget::completeStencilAttachment() { 76 bool GrGLRenderTarget::completeStencilAttachment() {
76 GrGLGpu* gpu = this->getGLGpu(); 77 GrGLGpu* gpu = this->getGLGpu();
77 const GrGLInterface* interface = gpu->glInterface(); 78 const GrGLInterface* interface = gpu->glInterface();
78 GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment (); 79 GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment ();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 #ifdef SK_DEBUG 113 #ifdef SK_DEBUG
113 GrGLenum status; 114 GrGLenum status;
114 GR_GL_CALL_RET(interface, status, CheckFramebufferStatus(GR_GL_FRAMEBUFF ER)); 115 GR_GL_CALL_RET(interface, status, CheckFramebufferStatus(GR_GL_FRAMEBUFF ER));
115 SkASSERT(GR_GL_FRAMEBUFFER_COMPLETE == status); 116 SkASSERT(GR_GL_FRAMEBUFFER_COMPLETE == status);
116 #endif 117 #endif
117 return true; 118 return true;
118 } 119 }
119 } 120 }
120 121
121 void GrGLRenderTarget::onRelease() { 122 void GrGLRenderTarget::onRelease() {
122 if (kBorrowed_LifeCycle != fRTLifecycle) { 123 if (GrBackendObjectLifeCycle::kBorrowed != fIDDesc.fRTFBOLifeCycle) {
123 if (fTexFBOID) { 124 GrGLuint fbos[2] = {0,};
124 GL_CALL(DeleteFramebuffers(1, &fTexFBOID)); 125 GrGLint i = 0;
126 if (fIDDesc.fTexFBOID) {
127 fbos[i] = fIDDesc.fTexFBOID;
128 i++;
125 } 129 }
126 if (fRTFBOID && fRTFBOID != fTexFBOID) { 130 if (fIDDesc.fRTFBOID && fIDDesc.fRTFBOID != fIDDesc.fTexFBOID) {
127 GL_CALL(DeleteFramebuffers(1, &fRTFBOID)); 131 fbos[i] = fIDDesc.fRTFBOID;
132 i++;
128 } 133 }
129 if (fMSColorRenderbufferID) { 134 if (i > 0) {
130 GL_CALL(DeleteRenderbuffers(1, &fMSColorRenderbufferID)); 135 GL_CALL(DeleteFramebuffers(i, fbos));
131 } 136 }
137 if (fIDDesc.fMSColorRenderbufferID) {
138 GL_CALL(DeleteRenderbuffers(1, &fIDDesc.fMSColorRenderbufferID));
139 }
140 if (GrBackendObjectLifeCycle::kBorrowed != fIDDesc.fTexLifeCycle && fIDD esc.fTexID) {
141 GL_CALL(DeleteTextures(1, &fIDDesc.fTexID));
142 }
143 } else {
144 SkASSERT(fIDDesc.fTexID == 0);
145 SkASSERT(fIDDesc.fTexFBOID == 0);
146 SkASSERT(fIDDesc.fMSColorRenderbufferID == 0);
132 } 147 }
133 fRTFBOID = 0; 148
134 fTexFBOID = 0; 149 fIDDesc.fRTFBOID = 0;
135 fMSColorRenderbufferID = 0; 150 fIDDesc.fTexFBOID = 0;
151 fIDDesc.fTexID = 0;
152 fIDDesc.fMSColorRenderbufferID = 0;
136 INHERITED::onRelease(); 153 INHERITED::onRelease();
137 } 154 }
138 155
139 void GrGLRenderTarget::onAbandon() { 156 void GrGLRenderTarget::onAbandon() {
140 fRTFBOID = 0; 157 fIDDesc.fRTFBOID = 0;
141 fTexFBOID = 0; 158 fIDDesc.fTexFBOID = 0;
142 fMSColorRenderbufferID = 0; 159 fIDDesc.fTexID = 0;
160 fIDDesc.fMSColorRenderbufferID = 0;
143 INHERITED::onAbandon(); 161 INHERITED::onAbandon();
144 } 162 }
145 163
164 bool GrGLRenderTarget::refsWrappedResources() const {
165 // Instances of GrGLRenderTarget wrap external resources.
166 // Internal render targets override this.
167 return true;
168 }
169
146 GrGLGpu* GrGLRenderTarget::getGLGpu() const { 170 GrGLGpu* GrGLRenderTarget::getGLGpu() const {
147 SkASSERT(!this->wasDestroyed()); 171 SkASSERT(!this->wasDestroyed());
148 return static_cast<GrGLGpu*>(this->getGpu()); 172 return static_cast<GrGLGpu*>(this->getGpu());
149 } 173 }
150 174
151 void GrGLRenderTarget::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const { 175 void GrGLRenderTarget::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
152 // Don't log the backing texture's contribution to the memory size. This wil l be handled by the 176 // Due to this resource having both a texture and a renderbuffer component, dump as
153 // texture object. 177 // skia/gpu_resources/resource_#/renderbuffer
178 // skia/gpu_resources/resource_#/texture
179 if (GrBackendObjectLifeCycle::kBorrowed != fIDDesc.fRTFBOLifeCycle) {
180 if (fIDDesc.fRTFBOID && fIDDesc.fTexFBOID != fIDDesc.fRTFBOID) {
181 size_t size = fDesc.fSampleCnt * this->totalBytesPerSample();
154 182
155 // Log any renderbuffer's contribution to memory. We only do this if we own the renderbuffer 183 SkString dumpName("skia/gpu_resources/resource_");
156 // (have a fMSColorRenderbufferID). 184 dumpName.appendS32(this->getUniqueID());
157 if (fMSColorRenderbufferID) { 185 dumpName.append("/renderbuffer");
158 size_t size = this->msaaSamples() * this->totalBytesPerSample();
159 186
160 // Due to this resource having both a texture and a renderbuffer compone nt, dump as 187 traceMemoryDump->dumpNumericValue(dumpName.c_str(), "size", "bytes", size);
161 // skia/gpu_resources/resource_#/renderbuffer
162 SkString dumpName("skia/gpu_resources/resource_");
163 dumpName.appendS32(this->getUniqueID());
164 dumpName.append("/renderbuffer");
165 188
166 traceMemoryDump->dumpNumericValue(dumpName.c_str(), "size", "bytes", siz e); 189 if (this->isPurgeable()) {
190 traceMemoryDump->dumpNumericValue(dumpName.c_str(), "purgeable_s ize", "bytes", size);
191 }
167 192
168 if (this->isPurgeable()) { 193 SkString renderbuffer_id;
169 traceMemoryDump->dumpNumericValue(dumpName.c_str(), "purgeable_size" , "bytes", size); 194 renderbuffer_id.appendU32(fIDDesc.fMSColorRenderbufferID);
195 traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_renderbuffer ",
196 renderbuffer_id.c_str());
170 } 197 }
171 198 }
172 SkString renderbuffer_id; 199 if (GrBackendObjectLifeCycle::kBorrowed != fIDDesc.fTexLifeCycle) {
173 renderbuffer_id.appendU32(fMSColorRenderbufferID); 200 if (fIDDesc.fTexID) {
174 traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_renderbuffer", 201 size_t size = this->totalBytesPerSample();
175 renderbuffer_id.c_str()); 202 SkString dumpName("skia/gpu_resources/resource_");
203 dumpName.appendS32(this->getUniqueID());
204 dumpName.append("/texture");
205 traceMemoryDump->dumpNumericValue(dumpName.c_str(), "size", "bytes", size);
206 if (this->isPurgeable()) {
207 traceMemoryDump->dumpNumericValue(dumpName.c_str(), "purgeable_s ize", "bytes", size);
208 }
209 SkString texID;
210 texID.appendU32(fIDDesc.fTexID);
211 traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_texture",
212 texID.c_str());
213 }
176 } 214 }
177 } 215 }
178 216
179 size_t GrGLRenderTarget::totalBytesPerSample() const { 217 size_t GrGLRenderTarget::totalBytesPerSample() const {
180 SkASSERT(kUnknown_GrPixelConfig != fDesc.fConfig); 218 SkASSERT(kUnknown_GrPixelConfig != fDesc.fConfig);
181 SkASSERT(!GrPixelConfigIsCompressed(fDesc.fConfig)); 219 SkASSERT(!GrPixelConfigIsCompressed(fDesc.fConfig));
182 size_t colorBytes = GrBytesPerPixel(fDesc.fConfig); 220 size_t colorBytes = GrBytesPerPixel(fDesc.fConfig);
183 SkASSERT(colorBytes > 0); 221 SkASSERT(colorBytes > 0);
184 222
185 return fDesc.fWidth * fDesc.fHeight * colorBytes; 223 return fDesc.fWidth * fDesc.fHeight * colorBytes;
186 } 224 }
187 225
188 int GrGLRenderTarget::msaaSamples() const { 226 int GrGLRenderTarget::totalSamples() const {
189 if (fTexFBOID == kUnresolvableFBOID || fTexFBOID != fRTFBOID) { 227 int total_samples = 0;
190 // If the render target's FBO is external (fTexFBOID == kUnresolvableFBO ID), or if we own 228 if (GrBackendObjectLifeCycle::kBorrowed != fIDDesc.fRTFBOLifeCycle) {
191 // the render target's FBO (fTexFBOID == fRTFBOID) then we use the provi ded sample count. 229 if (fIDDesc.fRTFBOID && fIDDesc.fTexFBOID != fIDDesc.fRTFBOID) {
192 return SkTMax(1, fDesc.fSampleCnt); 230 SkASSERT(this->isUnifiedMultisampled());
231 total_samples += fDesc.fSampleCnt;
232 }
193 } 233 }
194 234 if (GrBackendObjectLifeCycle::kBorrowed != fIDDesc.fTexLifeCycle) {
195 // When fTexFBOID == fRTFBOID, we either are not using MSAA, or MSAA is auto resolving, so use 235 if (fIDDesc.fTexFBOID) {
196 // 0 for the sample count. 236 total_samples += 1;
197 return 0; 237 }
238 }
239 return total_samples;
198 } 240 }
199
200 int GrGLRenderTarget::totalSamples() const {
201 int total_samples = this->msaaSamples();
202
203 if (fTexFBOID != kUnresolvableFBOID) {
204 // If we own the resolve buffer then that is one more sample per pixel.
205 total_samples += 1;
206 }
207
208 return total_samples;
209 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698