Home | History | Annotate | Download | only in gpu
      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