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