blob: e748853cfd09d09a6b4a881ea2ae5a552c24e208 [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;
robertphillips76948d42016-05-04 12:47:41 -070016class GrTextureProxy;
17class GrRenderTargetProxy;
18
Robert Phillipsc7635fa2016-10-28 13:25:24 -040019// This class replicates the functionality GrIORef<GrSurface> but tracks the
20// utilitization for later resource allocation (for the deferred case) and
21// forwards on the utilization in the wrapped case
22class GrIORefProxy : public SkNoncopyable {
23public:
24 void ref() const {
25 this->validate();
26
27 ++fRefCnt;
28 if (fTarget) {
29 fTarget->ref();
30 }
31 }
32
33 void unref() const {
34 this->validate();
35
36 if (fTarget) {
37 fTarget->unref();
38 }
39
40 if (!(--fRefCnt)) {
41 delete this;
42 return;
43 }
44
45 this->validate();
46 }
47
48 void validate() const {
49#ifdef SK_DEBUG
50 SkASSERT(fRefCnt >= 0);
51#endif
52 }
53
54protected:
55 GrIORefProxy() : fRefCnt(1), fTarget(nullptr) {}
56 GrIORefProxy(sk_sp<GrSurface> surface) : fRefCnt(1) {
57 // Since we're manually forwarding on refs & unrefs we don't want sk_sp doing
58 // anything extra.
59 fTarget = surface.release();
60 }
61 virtual ~GrIORefProxy() {
62 // We don't unref 'fTarget' here since the 'unref' method will already
63 // have forwarded on the unref call that got use here.
64 }
65
66 // TODO: add the IO ref counts. Although if we can delay shader creation to flush time
67 // we may not even need to do that.
68 mutable int32_t fRefCnt;
69
70 // For deferred proxies this will be null. For wrapped proxies it will point to the
71 // wrapped resource.
72 GrSurface* fTarget;
73};
74
75class GrSurfaceProxy : public GrIORefProxy {
robertphillips76948d42016-05-04 12:47:41 -070076public:
77 const GrSurfaceDesc& desc() const { return fDesc; }
78
79 GrSurfaceOrigin origin() const {
80 SkASSERT(kTopLeft_GrSurfaceOrigin == fDesc.fOrigin ||
81 kBottomLeft_GrSurfaceOrigin == fDesc.fOrigin);
82 return fDesc.fOrigin;
83 }
84 int width() const { return fDesc.fWidth; }
Robert Phillipsc7635fa2016-10-28 13:25:24 -040085 int height() const { return fDesc.fHeight; }
robertphillips76948d42016-05-04 12:47:41 -070086 GrPixelConfig config() const { return fDesc.fConfig; }
87
88 uint32_t uniqueID() const { return fUniqueID; }
89
90 /**
robertphillips13a7eee2016-08-31 15:06:24 -070091 * Helper that gets the width and height of the surface as a bounding rectangle.
92 */
93 SkRect getBoundsRect() const { return SkRect::MakeIWH(this->width(), this->height()); }
94
95 /**
robertphillips76948d42016-05-04 12:47:41 -070096 * @return the texture proxy associated with the surface proxy, may be NULL.
97 */
98 virtual GrTextureProxy* asTextureProxy() { return nullptr; }
99 virtual const GrTextureProxy* asTextureProxy() const { return nullptr; }
100
101 /**
102 * @return the render target proxy associated with the surface proxy, may be NULL.
103 */
104 virtual GrRenderTargetProxy* asRenderTargetProxy() { return nullptr; }
105 virtual const GrRenderTargetProxy* asRenderTargetProxy() const { return nullptr; }
106
robertphillips13a7eee2016-08-31 15:06:24 -0700107 /**
108 * Does the resource count against the resource budget?
109 */
110 SkBudgeted isBudgeted() const { return fBudgeted; }
111
Robert Phillipsf2361d22016-10-25 14:20:06 -0400112 void setLastOpList(GrOpList* opList);
113 GrOpList* getLastOpList() { return fLastOpList; }
114
Robert Phillips8bc06d02016-11-01 17:28:40 -0400115 /**
116 * Retrieves the amount of GPU memory that will be or currently is used by this resource
117 * in bytes. It is approximate since we aren't aware of additional padding or copies made
118 * by the driver.
119 *
120 * @return the amount of GPU memory used in bytes
121 */
122 size_t gpuMemorySize() const {
Robert Phillips8bc06d02016-11-01 17:28:40 -0400123 if (kInvalidGpuMemorySize == fGpuMemorySize) {
124 fGpuMemorySize = this->onGpuMemorySize();
125 SkASSERT(kInvalidGpuMemorySize != fGpuMemorySize);
126 }
127 return fGpuMemorySize;
128 }
129
robertphillips76948d42016-05-04 12:47:41 -0700130protected:
robertphillips8abb3702016-08-31 14:04:06 -0700131 // Deferred version
robertphillips76948d42016-05-04 12:47:41 -0700132 GrSurfaceProxy(const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted)
133 : fDesc(desc)
134 , fFit(fit)
135 , fBudgeted(budgeted)
Robert Phillipsf2361d22016-10-25 14:20:06 -0400136 , fUniqueID(GrGpuResource::CreateUniqueID())
Robert Phillips8bc06d02016-11-01 17:28:40 -0400137 , fGpuMemorySize(kInvalidGpuMemorySize)
Robert Phillipsf2361d22016-10-25 14:20:06 -0400138 , fLastOpList(nullptr) {
robertphillips8abb3702016-08-31 14:04:06 -0700139 }
140
141 // Wrapped version
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400142 GrSurfaceProxy(sk_sp<GrSurface> surface, SkBackingFit fit);
robertphillips76948d42016-05-04 12:47:41 -0700143
Robert Phillipsf2361d22016-10-25 14:20:06 -0400144 virtual ~GrSurfaceProxy();
145
robertphillips76948d42016-05-04 12:47:41 -0700146 // For wrapped resources, 'fDesc' will always be filled in from the wrapped resource.
147 const GrSurfaceDesc fDesc;
148 const SkBackingFit fFit; // always exact for wrapped resources
149 const SkBudgeted fBudgeted; // set from the backing resource for wrapped resources
robertphillips8abb3702016-08-31 14:04:06 -0700150 const uint32_t fUniqueID; // set from the backing resource for wrapped resources
robertphillips76948d42016-05-04 12:47:41 -0700151
Robert Phillips8bc06d02016-11-01 17:28:40 -0400152 static const size_t kInvalidGpuMemorySize = ~static_cast<size_t>(0);
Robert Phillips29e52f12016-11-03 10:19:14 -0400153 SkDEBUGCODE(size_t getRawGpuMemorySize_debugOnly() const { return fGpuMemorySize; })
154
155private:
156 virtual size_t onGpuMemorySize() const = 0;
157
Robert Phillips8bc06d02016-11-01 17:28:40 -0400158 // This entry is lazily evaluated so, when the proxy wraps a resource, the resource
159 // will be called but, when the proxy is deferred, it will compute the answer itself.
160 // If the proxy computes its own answer that answer is checked (in debug mode) in
161 // the instantiation method.
162 mutable size_t fGpuMemorySize;
163
Robert Phillipsf2361d22016-10-25 14:20:06 -0400164 // The last opList that wrote to or is currently going to write to this surface
Brian Osman11052242016-10-27 14:47:55 -0400165 // The opList can be closed (e.g., no render target context is currently bound
Robert Phillipsf2361d22016-10-25 14:20:06 -0400166 // to this renderTarget).
167 // This back-pointer is required so that we can add a dependancy between
168 // the opList used to create the current contents of this surface
169 // and the opList of a destination surface to which this one is being drawn or copied.
170 GrOpList* fLastOpList;
171
Robert Phillips29e52f12016-11-03 10:19:14 -0400172
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400173 typedef GrIORefProxy INHERITED;
robertphillips76948d42016-05-04 12:47:41 -0700174};
175
176#endif