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 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 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 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 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 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 122 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 134 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 146 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 158 void GrSurface::onRelease() { 159 this->INHERITED::onRelease(); 160 } 161 162 void GrSurface::onAbandon() { 163 this->INHERITED::onAbandon(); 164 } 165