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 size_t colorBytes = (size_t) width * height * GrBytesPerPixel(desc.fConfig);
40
41 // This would be a nice assert to have (i.e., we aren't creating 0 width/height surfaces).
42 // Unfortunately Chromium seems to want to do this.
43 //SkASSERT(colorBytes > 0);
44
45 size = colorValuesPerPixel * colorBytes;
46 size += colorBytes/3; // in case we have to mipmap
47 } else {
48 size = (size_t) width * height * GrBytesPerPixel(desc.fConfig);
49
50 size += size/3; // in case we have to mipmap
51 }
52
53 return size;
54 }
55
ComputeSize(GrPixelConfig config,int width,int height,int colorSamplesPerPixel,GrMipMapped mipMapped,bool useNextPow2)56 size_t GrSurface::ComputeSize(GrPixelConfig config,
57 int width,
58 int height,
59 int colorSamplesPerPixel,
60 GrMipMapped mipMapped,
61 bool useNextPow2) {
62 width = useNextPow2
63 ? SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(width))
64 : width;
65 height = useNextPow2
66 ? SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(height))
67 : height;
68
69 SkASSERT(kUnknown_GrPixelConfig != config);
70 size_t colorSize = (size_t)width * height * GrBytesPerPixel(config);
71 SkASSERT(colorSize > 0);
72
73 size_t finalSize = colorSamplesPerPixel * colorSize;
74
75 if (GrMipMapped::kYes == mipMapped) {
76 // We don't have to worry about the mipmaps being a different size than
77 // we'd expect because we never change fDesc.fWidth/fHeight.
78 finalSize += colorSize/3;
79 }
80 return finalSize;
81 }
82
adjust_params(int surfaceWidth,int surfaceHeight,size_t bpp,int * left,int * top,int * width,int * height,T ** data,size_t * rowBytes)83 template<typename T> static bool adjust_params(int surfaceWidth,
84 int surfaceHeight,
85 size_t bpp,
86 int* left, int* top, int* width, int* height,
87 T** data,
88 size_t* rowBytes) {
89 if (!*rowBytes) {
90 *rowBytes = *width * bpp;
91 }
92
93 SkIRect subRect = SkIRect::MakeXYWH(*left, *top, *width, *height);
94 SkIRect bounds = SkIRect::MakeWH(surfaceWidth, surfaceHeight);
95
96 if (!subRect.intersect(bounds)) {
97 return false;
98 }
99 *data = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(*data) +
100 (subRect.fTop - *top) * *rowBytes + (subRect.fLeft - *left) * bpp);
101
102 *left = subRect.fLeft;
103 *top = subRect.fTop;
104 *width = subRect.width();
105 *height = subRect.height();
106 return true;
107 }
108
AdjustReadPixelParams(int surfaceWidth,int surfaceHeight,size_t bpp,int * left,int * top,int * width,int * height,void ** data,size_t * rowBytes)109 bool GrSurfacePriv::AdjustReadPixelParams(int surfaceWidth,
110 int surfaceHeight,
111 size_t bpp,
112 int* left, int* top, int* width, int* height,
113 void** data,
114 size_t* rowBytes) {
115 return adjust_params<void>(surfaceWidth, surfaceHeight, bpp, left, top, width, height, data,
116 rowBytes);
117 }
118
AdjustWritePixelParams(int surfaceWidth,int surfaceHeight,size_t bpp,int * left,int * top,int * width,int * height,const void ** data,size_t * rowBytes)119 bool GrSurfacePriv::AdjustWritePixelParams(int surfaceWidth,
120 int surfaceHeight,
121 size_t bpp,
122 int* left, int* top, int* width, int* height,
123 const void** data,
124 size_t* rowBytes) {
125 return adjust_params<const void>(surfaceWidth, surfaceHeight, bpp, left, top, width, height,
126 data, rowBytes);
127 }
128
129
130 //////////////////////////////////////////////////////////////////////////////
131
hasPendingRead() const132 bool GrSurface::hasPendingRead() const {
133 const GrTexture* thisTex = this->asTexture();
134 if (thisTex && thisTex->internalHasPendingRead()) {
135 return true;
136 }
137 const GrRenderTarget* thisRT = this->asRenderTarget();
138 if (thisRT && thisRT->internalHasPendingRead()) {
139 return true;
140 }
141 return false;
142 }
143
hasPendingWrite() const144 bool GrSurface::hasPendingWrite() const {
145 const GrTexture* thisTex = this->asTexture();
146 if (thisTex && thisTex->internalHasPendingWrite()) {
147 return true;
148 }
149 const GrRenderTarget* thisRT = this->asRenderTarget();
150 if (thisRT && thisRT->internalHasPendingWrite()) {
151 return true;
152 }
153 return false;
154 }
155
hasPendingIO() const156 bool GrSurface::hasPendingIO() const {
157 const GrTexture* thisTex = this->asTexture();
158 if (thisTex && thisTex->internalHasPendingIO()) {
159 return true;
160 }
161 const GrRenderTarget* thisRT = this->asRenderTarget();
162 if (thisRT && thisRT->internalHasPendingIO()) {
163 return true;
164 }
165 return false;
166 }
167
onRelease()168 void GrSurface::onRelease() {
169 this->INHERITED::onRelease();
170 }
171
onAbandon()172 void GrSurface::onAbandon() {
173 this->INHERITED::onAbandon();
174 }
175