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 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 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 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 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 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 132 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 144 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 156 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 168 void GrSurface::onRelease() { 169 this->INHERITED::onRelease(); 170 } 171 172 void GrSurface::onAbandon() { 173 this->INHERITED::onAbandon(); 174 } 175