1 /*
2 * Copyright 2012 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 "GrSurface.h"
9 #include "GrContext.h"
10 #include "GrOpList.h"
11 #include "GrRenderTarget.h"
12 #include "GrResourceProvider.h"
13 #include "GrSurfacePriv.h"
14 #include "GrTexture.h"
15
16 #include "SkGr.h"
17 #include "SkMathPriv.h"
18
WorstCaseSize(const GrSurfaceDesc & desc,bool useNextPow2)19 size_t GrSurface::WorstCaseSize(const GrSurfaceDesc& desc, bool useNextPow2) {
20 size_t size;
21
22 int width = useNextPow2
23 ? SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(desc.fWidth))
24 : desc.fWidth;
25 int height = useNextPow2
26 ? SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(desc.fHeight))
27 : desc.fHeight;
28
29 bool isRenderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
30 if (isRenderTarget) {
31 // We own one color value for each MSAA sample.
32 SkASSERT(desc.fSampleCnt >= 1);
33 int colorValuesPerPixel = desc.fSampleCnt;
34 if (desc.fSampleCnt > 1) {
35 // Worse case, we own the resolve buffer so that is one more sample per pixel.
36 colorValuesPerPixel += 1;
37 }
38 SkASSERT(kUnknown_GrPixelConfig != desc.fConfig);
39 SkASSERT(!GrPixelConfigIsCompressed(desc.fConfig));
40 size_t colorBytes = (size_t) width * height * GrBytesPerPixel(desc.fConfig);
41
42 // This would be a nice assert to have (i.e., we aren't creating 0 width/height surfaces).
43 // Unfortunately Chromium seems to want to do this.
44 //SkASSERT(colorBytes > 0);
45
46 size = colorValuesPerPixel * colorBytes;
47 size += colorBytes/3; // in case we have to mipmap
48 } else {
49 if (GrPixelConfigIsCompressed(desc.fConfig)) {
50 size = GrCompressedFormatDataSize(desc.fConfig, width, height);
51 } else {
52 size = (size_t)width * height * GrBytesPerPixel(desc.fConfig);
53 }
54
55 size += size/3; // in case we have to mipmap
56 }
57
58 return size;
59 }
60
ComputeSize(GrPixelConfig config,int width,int height,int colorSamplesPerPixel,GrMipMapped mipMapped,bool useNextPow2)61 size_t GrSurface::ComputeSize(GrPixelConfig config,
62 int width,
63 int height,
64 int colorSamplesPerPixel,
65 GrMipMapped mipMapped,
66 bool useNextPow2) {
67 size_t colorSize;
68
69 width = useNextPow2
70 ? SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(width))
71 : width;
72 height = useNextPow2
73 ? SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(height))
74 : height;
75
76 SkASSERT(kUnknown_GrPixelConfig != config);
77 if (GrPixelConfigIsCompressed(config)) {
78 colorSize = GrCompressedFormatDataSize(config, width, height);
79 } else {
80 colorSize = (size_t)width * height * GrBytesPerPixel(config);
81 }
82 SkASSERT(colorSize > 0);
83
84 size_t finalSize = colorSamplesPerPixel * colorSize;
85
86 if (GrMipMapped::kYes == mipMapped) {
87 // We don't have to worry about the mipmaps being a different size than
88 // we'd expect because we never change fDesc.fWidth/fHeight.
89 finalSize += colorSize/3;
90 }
91 return finalSize;
92 }
93
adjust_params(int surfaceWidth,int surfaceHeight,size_t bpp,int * left,int * top,int * width,int * height,T ** data,size_t * rowBytes)94 template<typename T> static bool adjust_params(int surfaceWidth,
95 int surfaceHeight,
96 size_t bpp,
97 int* left, int* top, int* width, int* height,
98 T** data,
99 size_t* rowBytes) {
100 if (!*rowBytes) {
101 *rowBytes = *width * bpp;
102 }
103
104 SkIRect subRect = SkIRect::MakeXYWH(*left, *top, *width, *height);
105 SkIRect bounds = SkIRect::MakeWH(surfaceWidth, surfaceHeight);
106
107 if (!subRect.intersect(bounds)) {
108 return false;
109 }
110 *data = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(*data) +
111 (subRect.fTop - *top) * *rowBytes + (subRect.fLeft - *left) * bpp);
112
113 *left = subRect.fLeft;
114 *top = subRect.fTop;
115 *width = subRect.width();
116 *height = subRect.height();
117 return true;
118 }
119
AdjustReadPixelParams(int surfaceWidth,int surfaceHeight,size_t bpp,int * left,int * top,int * width,int * height,void ** data,size_t * rowBytes)120 bool GrSurfacePriv::AdjustReadPixelParams(int surfaceWidth,
121 int surfaceHeight,
122 size_t bpp,
123 int* left, int* top, int* width, int* height,
124 void** data,
125 size_t* rowBytes) {
126 return adjust_params<void>(surfaceWidth, surfaceHeight, bpp, left, top, width, height, data,
127 rowBytes);
128 }
129
AdjustWritePixelParams(int surfaceWidth,int surfaceHeight,size_t bpp,int * left,int * top,int * width,int * height,const void ** data,size_t * rowBytes)130 bool GrSurfacePriv::AdjustWritePixelParams(int surfaceWidth,
131 int surfaceHeight,
132 size_t bpp,
133 int* left, int* top, int* width, int* height,
134 const void** data,
135 size_t* rowBytes) {
136 return adjust_params<const void>(surfaceWidth, surfaceHeight, bpp, left, top, width, height,
137 data, rowBytes);
138 }
139
140
141 //////////////////////////////////////////////////////////////////////////////
142
hasPendingRead() const143 bool GrSurface::hasPendingRead() const {
144 const GrTexture* thisTex = this->asTexture();
145 if (thisTex && thisTex->internalHasPendingRead()) {
146 return true;
147 }
148 const GrRenderTarget* thisRT = this->asRenderTarget();
149 if (thisRT && thisRT->internalHasPendingRead()) {
150 return true;
151 }
152 return false;
153 }
154
hasPendingWrite() const155 bool GrSurface::hasPendingWrite() const {
156 const GrTexture* thisTex = this->asTexture();
157 if (thisTex && thisTex->internalHasPendingWrite()) {
158 return true;
159 }
160 const GrRenderTarget* thisRT = this->asRenderTarget();
161 if (thisRT && thisRT->internalHasPendingWrite()) {
162 return true;
163 }
164 return false;
165 }
166
hasPendingIO() const167 bool GrSurface::hasPendingIO() const {
168 const GrTexture* thisTex = this->asTexture();
169 if (thisTex && thisTex->internalHasPendingIO()) {
170 return true;
171 }
172 const GrRenderTarget* thisRT = this->asRenderTarget();
173 if (thisRT && thisRT->internalHasPendingIO()) {
174 return true;
175 }
176 return false;
177 }
178
onRelease()179 void GrSurface::onRelease() {
180 this->INHERITED::onRelease();
181 }
182
onAbandon()183 void GrSurface::onAbandon() {
184 this->INHERITED::onAbandon();
185 }
186