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