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