• 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 "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