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 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 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 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 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 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 143 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 155 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 167 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 179 void GrSurface::onRelease() { 180 this->INHERITED::onRelease(); 181 } 182 183 void GrSurface::onAbandon() { 184 this->INHERITED::onAbandon(); 185 } 186