• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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