blob: 539aaf65aa7b2c22751c40a7b181d8cd3b326a23 [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#ifndef GrSurfaceProxy_DEFINED
9#define GrSurfaceProxy_DEFINED
10
11#include "GrGpuResource.h"
Robert Phillipsc7635fa2016-10-28 13:25:24 -040012#include "GrSurface.h"
csmartdaltonbf4a8f92016-09-06 10:01:06 -070013#include "SkRect.h"
robertphillips76948d42016-05-04 12:47:41 -070014
Robert Phillipsf2361d22016-10-25 14:20:06 -040015class GrOpList;
Robert Phillipseaa86252016-11-08 13:49:39 +000016class GrTextureProvider;
robertphillips76948d42016-05-04 12:47:41 -070017class GrTextureProxy;
18class GrRenderTargetProxy;
19
Robert Phillipsc7635fa2016-10-28 13:25:24 -040020// This class replicates the functionality GrIORef<GrSurface> but tracks the
21// utilitization for later resource allocation (for the deferred case) and
22// forwards on the utilization in the wrapped case
23class GrIORefProxy : public SkNoncopyable {
24public:
25 void ref() const {
26 this->validate();
27
28 ++fRefCnt;
29 if (fTarget) {
30 fTarget->ref();
31 }
32 }
33
34 void unref() const {
35 this->validate();
36
37 if (fTarget) {
38 fTarget->unref();
39 }
40
41 if (!(--fRefCnt)) {
42 delete this;
43 return;
44 }
45
46 this->validate();
47 }
48
49 void validate() const {
50#ifdef SK_DEBUG
51 SkASSERT(fRefCnt >= 0);
52#endif
53 }
54
55protected:
56 GrIORefProxy() : fRefCnt(1), fTarget(nullptr) {}
57 GrIORefProxy(sk_sp<GrSurface> surface) : fRefCnt(1) {
58 // Since we're manually forwarding on refs & unrefs we don't want sk_sp doing
59 // anything extra.
60 fTarget = surface.release();
61 }
62 virtual ~GrIORefProxy() {
63 // We don't unref 'fTarget' here since the 'unref' method will already
64 // have forwarded on the unref call that got use here.
65 }
66
67 // TODO: add the IO ref counts. Although if we can delay shader creation to flush time
68 // we may not even need to do that.
69 mutable int32_t fRefCnt;
70
71 // For deferred proxies this will be null. For wrapped proxies it will point to the
72 // wrapped resource.
73 GrSurface* fTarget;
74};
75
76class GrSurfaceProxy : public GrIORefProxy {
robertphillips76948d42016-05-04 12:47:41 -070077public:
78 const GrSurfaceDesc& desc() const { return fDesc; }
79
80 GrSurfaceOrigin origin() const {
81 SkASSERT(kTopLeft_GrSurfaceOrigin == fDesc.fOrigin ||
82 kBottomLeft_GrSurfaceOrigin == fDesc.fOrigin);
83 return fDesc.fOrigin;
84 }
85 int width() const { return fDesc.fWidth; }
Robert Phillipsc7635fa2016-10-28 13:25:24 -040086 int height() const { return fDesc.fHeight; }
robertphillips76948d42016-05-04 12:47:41 -070087 GrPixelConfig config() const { return fDesc.fConfig; }
88
89 uint32_t uniqueID() const { return fUniqueID; }
90
91 /**
robertphillips13a7eee2016-08-31 15:06:24 -070092 * Helper that gets the width and height of the surface as a bounding rectangle.
93 */
94 SkRect getBoundsRect() const { return SkRect::MakeIWH(this->width(), this->height()); }
95
96 /**
robertphillips76948d42016-05-04 12:47:41 -070097 * @return the texture proxy associated with the surface proxy, may be NULL.
98 */
99 virtual GrTextureProxy* asTextureProxy() { return nullptr; }
100 virtual const GrTextureProxy* asTextureProxy() const { return nullptr; }
101
102 /**
103 * @return the render target proxy associated with the surface proxy, may be NULL.
104 */
105 virtual GrRenderTargetProxy* asRenderTargetProxy() { return nullptr; }
106 virtual const GrRenderTargetProxy* asRenderTargetProxy() const { return nullptr; }
107
robertphillips13a7eee2016-08-31 15:06:24 -0700108 /**
109 * Does the resource count against the resource budget?
110 */
111 SkBudgeted isBudgeted() const { return fBudgeted; }
112
Robert Phillipsf2361d22016-10-25 14:20:06 -0400113 void setLastOpList(GrOpList* opList);
114 GrOpList* getLastOpList() { return fLastOpList; }
115
Robert Phillips8bc06d02016-11-01 17:28:40 -0400116 /**
117 * Retrieves the amount of GPU memory that will be or currently is used by this resource
118 * in bytes. It is approximate since we aren't aware of additional padding or copies made
119 * by the driver.
120 *
121 * @return the amount of GPU memory used in bytes
122 */
123 size_t gpuMemorySize() const {
Robert Phillips8bc06d02016-11-01 17:28:40 -0400124 if (kInvalidGpuMemorySize == fGpuMemorySize) {
125 fGpuMemorySize = this->onGpuMemorySize();
126 SkASSERT(kInvalidGpuMemorySize != fGpuMemorySize);
127 }
128 return fGpuMemorySize;
129 }
130
Robert Phillipseaa86252016-11-08 13:49:39 +0000131 bool isWrapped_ForTesting() const;
132
robertphillips76948d42016-05-04 12:47:41 -0700133protected:
robertphillips8abb3702016-08-31 14:04:06 -0700134 // Deferred version
robertphillips76948d42016-05-04 12:47:41 -0700135 GrSurfaceProxy(const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted)
136 : fDesc(desc)
137 , fFit(fit)
138 , fBudgeted(budgeted)
Robert Phillipsf2361d22016-10-25 14:20:06 -0400139 , fUniqueID(GrGpuResource::CreateUniqueID())
Robert Phillips8bc06d02016-11-01 17:28:40 -0400140 , fGpuMemorySize(kInvalidGpuMemorySize)
Robert Phillipsf2361d22016-10-25 14:20:06 -0400141 , fLastOpList(nullptr) {
robertphillips8abb3702016-08-31 14:04:06 -0700142 }
143
144 // Wrapped version
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400145 GrSurfaceProxy(sk_sp<GrSurface> surface, SkBackingFit fit);
robertphillips76948d42016-05-04 12:47:41 -0700146
Robert Phillipsf2361d22016-10-25 14:20:06 -0400147 virtual ~GrSurfaceProxy();
148
Robert Phillipseaa86252016-11-08 13:49:39 +0000149 GrSurface* instantiate(GrTextureProvider* texProvider);
150
robertphillips76948d42016-05-04 12:47:41 -0700151 // For wrapped resources, 'fDesc' will always be filled in from the wrapped resource.
152 const GrSurfaceDesc fDesc;
153 const SkBackingFit fFit; // always exact for wrapped resources
154 const SkBudgeted fBudgeted; // set from the backing resource for wrapped resources
robertphillips8abb3702016-08-31 14:04:06 -0700155 const uint32_t fUniqueID; // set from the backing resource for wrapped resources
robertphillips76948d42016-05-04 12:47:41 -0700156
Robert Phillips8bc06d02016-11-01 17:28:40 -0400157 static const size_t kInvalidGpuMemorySize = ~static_cast<size_t>(0);
Robert Phillips29e52f12016-11-03 10:19:14 -0400158 SkDEBUGCODE(size_t getRawGpuMemorySize_debugOnly() const { return fGpuMemorySize; })
159
160private:
161 virtual size_t onGpuMemorySize() const = 0;
162
Robert Phillips8bc06d02016-11-01 17:28:40 -0400163 // This entry is lazily evaluated so, when the proxy wraps a resource, the resource
164 // will be called but, when the proxy is deferred, it will compute the answer itself.
165 // If the proxy computes its own answer that answer is checked (in debug mode) in
166 // the instantiation method.
167 mutable size_t fGpuMemorySize;
168
Robert Phillipsf2361d22016-10-25 14:20:06 -0400169 // The last opList that wrote to or is currently going to write to this surface
Brian Osman11052242016-10-27 14:47:55 -0400170 // The opList can be closed (e.g., no render target context is currently bound
Robert Phillipsf2361d22016-10-25 14:20:06 -0400171 // to this renderTarget).
172 // This back-pointer is required so that we can add a dependancy between
173 // the opList used to create the current contents of this surface
174 // and the opList of a destination surface to which this one is being drawn or copied.
175 GrOpList* fLastOpList;
176
Robert Phillips29e52f12016-11-03 10:19:14 -0400177
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400178 typedef GrIORefProxy INHERITED;
robertphillips76948d42016-05-04 12:47:41 -0700179};
180
181#endif