Home | History | Annotate | Download | only in include
      1 /*
      2     Copyright 2011 Google Inc.
      3 
      4     Licensed under the Apache License, Version 2.0 (the "License");
      5     you may not use this file except in compliance with the License.
      6     You may obtain a copy of the License at
      7 
      8          http://www.apache.org/licenses/LICENSE-2.0
      9 
     10     Unless required by applicable law or agreed to in writing, software
     11     distributed under the License is distributed on an "AS IS" BASIS,
     12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13     See the License for the specific language governing permissions and
     14     limitations under the License.
     15  */
     16 
     17 
     18 #ifndef GrTexture_DEFINED
     19 #define GrTexture_DEFINED
     20 
     21 #include "GrRefCnt.h"
     22 #include "GrClip.h"
     23 #include "GrResource.h"
     24 
     25 class GrTexture;
     26 
     27 /**
     28  * GrRenderTarget represents a 2D buffer of pixels that can be rendered to.
     29  * A context's render target is set by setRenderTarget(). Render targets are
     30  * created by a createTexture with the kRenderTarget_TextureFlag flag.
     31  * Additionally, GrContext provides methods for creating GrRenderTargets
     32  * that wrap externally created render targets.
     33  */
     34 class GrRenderTarget : public GrResource {
     35 
     36 public:
     37     /**
     38      * @return the width of the rendertarget
     39      */
     40     int width() const { return fWidth; }
     41     /**
     42      * @return the height of the rendertarget
     43      */
     44     int height() const { return fHeight; }
     45 
     46     /**
     47      * @return the number of stencil bits in the rendertarget
     48      */
     49     int stencilBits() const { return fStencilBits; }
     50 
     51     /**
     52      * @return the texture associated with the rendertarget, may be NULL.
     53      */
     54     GrTexture* asTexture() {return fTexture;}
     55 
     56     /**
     57      * @return true if the render target is multisampled, false otherwise
     58      */
     59     bool isMultisampled() { return fIsMultisampled; }
     60 
     61     /**
     62      * Call to indicate the multisample contents were modified such that the
     63      * render target needs to be resolved before it can be used as texture. Gr
     64      * tracks this for its own drawing and thus this only needs to be called
     65      * when the render target has been modified outside of Gr. Only meaningful
     66      * for Gr-created RT/Textures and Platform RT/Textures created with the
     67      * kGrCanResolve flag.
     68      * @param rect  a rect bounding the area needing resolve. NULL indicates
     69      *              the whole RT needs resolving.
     70      */
     71     void flagAsNeedingResolve(const GrIRect* rect = NULL);
     72 
     73     /**
     74      * Call to override the region that needs to be resolved.
     75      */
     76     void overrideResolveRect(const GrIRect rect);
     77 
     78     /**
     79      * Call to indicate that GrRenderTarget was externally resolved. This may
     80      * allow Gr to skip a redundant resolve step.
     81      */
     82     void flagAsResolved() { fResolveRect.setLargestInverted(); }
     83 
     84     /**
     85      * @return true if the GrRenderTarget requires MSAA resolving
     86      */
     87     bool needsResolve() const { return !fResolveRect.isEmpty(); }
     88 
     89     /**
     90      * Returns a rect bounding the region needing resolving.
     91      */
     92     const GrIRect& getResolveRect() const { return fResolveRect; }
     93 
     94     /**
     95      * Reads a rectangle of pixels from the render target.
     96      * @param left          left edge of the rectangle to read (inclusive)
     97      * @param top           top edge of the rectangle to read (inclusive)
     98      * @param width         width of rectangle to read in pixels.
     99      * @param height        height of rectangle to read in pixels.
    100      * @param config        the pixel config of the destination buffer
    101      * @param buffer        memory to read the rectangle into.
    102      *
    103      * @return true if the read succeeded, false if not. The read can fail
    104      *              because of a unsupported pixel config.
    105      */
    106     bool readPixels(int left, int top, int width, int height,
    107                     GrPixelConfig config, void* buffer);
    108 
    109     // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
    110     // 0 in GL), or be unresolvable because the client didn't give us the
    111     // resolve destination.
    112     enum ResolveType {
    113         kCanResolve_ResolveType,
    114         kAutoResolves_ResolveType,
    115         kCantResolve_ResolveType,
    116     };
    117     virtual ResolveType getResolveType() const = 0;
    118 
    119 protected:
    120     GrRenderTarget(GrGpu* gpu,
    121                    GrTexture* texture,
    122                    int width,
    123                    int height,
    124                    int stencilBits,
    125                    bool isMultisampled)
    126         : INHERITED(gpu)
    127         , fTexture(texture)
    128         , fWidth(width)
    129         , fHeight(height)
    130         , fStencilBits(stencilBits)
    131         , fIsMultisampled(isMultisampled)
    132     {
    133         fResolveRect.setLargestInverted();
    134     }
    135 
    136     friend class GrTexture;
    137     // When a texture unrefs an owned rendertarget this func
    138     // removes the back pointer. This could be done called from
    139     // texture's destructor but would have to be done in derived
    140     // class. By the time of texture base destructor it has already
    141     // lost its pointer to the rt.
    142     void onTextureReleaseRenderTarget() {
    143         GrAssert(NULL != fTexture);
    144         fTexture = NULL;
    145     }
    146 
    147 private:
    148     GrTexture* fTexture; // not ref'ed
    149     int        fWidth;
    150     int        fHeight;
    151     int        fStencilBits;
    152     bool       fIsMultisampled;
    153     GrIRect    fResolveRect;
    154 
    155     // GrGpu keeps a cached clip in the render target to avoid redundantly
    156     // rendering the clip into the same stencil buffer.
    157     friend class GrGpu;
    158     GrClip     fLastStencilClip;
    159 
    160     typedef GrResource INHERITED;
    161 };
    162 
    163 class GrTexture : public GrResource {
    164 
    165 public:
    166     /**
    167      * Retrieves the width of the texture.
    168      *
    169      * @return the width in texels
    170      */
    171     int width() const { return fWidth; }
    172 
    173     /**
    174      * Retrieves the height of the texture.
    175      *
    176      * @return the height in texels
    177      */
    178     int height() const { return fHeight; }
    179 
    180     /**
    181      * Convert from texels to normalized texture coords for POT textures
    182      * only.
    183      */
    184     GrFixed normalizeFixedX(GrFixed x) const { GrAssert(GrIsPow2(fWidth));
    185                                                return x >> fShiftFixedX; }
    186     GrFixed normalizeFixedY(GrFixed y) const { GrAssert(GrIsPow2(fHeight));
    187                                                return y >> fShiftFixedY; }
    188 
    189     /**
    190      * Retrieves the pixel config specified when the texture was created.
    191      */
    192     GrPixelConfig config() const { return fConfig; }
    193 
    194     /**
    195      *  Approximate number of bytes used by the texture
    196      */
    197     size_t sizeInBytes() const {
    198         return fWidth * fHeight * GrBytesPerPixel(fConfig);
    199     }
    200 
    201     /**
    202      * Updates a subrectangle of texels in the texture.
    203      *
    204      * @param x       left edge of rectangle to update
    205      * @param y       top edge of rectangle to update
    206      * @param width   width of rectangle to update
    207      * @param height  height of rectangle to update
    208      * @param srcData width*height texels of data in same format that was used
    209      *                at texture creation.
    210      */
    211     virtual void uploadTextureData(uint32_t x,
    212                                    uint32_t y,
    213                                    uint32_t width,
    214                                    uint32_t height,
    215                                    const void* srcData) = 0;
    216 
    217     /**
    218      * Reads a rectangle of pixels from the texture.
    219      * @param left          left edge of the rectangle to read (inclusive)
    220      * @param top           top edge of the rectangle to read (inclusive)
    221      * @param width         width of rectangle to read in pixels.
    222      * @param height        height of rectangle to read in pixels.
    223      * @param config        the pixel config of the destination buffer
    224      * @param buffer        memory to read the rectangle into.
    225      *
    226      * @return true if the read succeeded, false if not. The read can fail
    227      *              because of a unsupported pixel config.
    228      */
    229     bool readPixels(int left, int top, int width, int height,
    230                     GrPixelConfig config, void* buffer);
    231 
    232     /**
    233      * Retrieves the render target underlying this texture that can be passed to
    234      * GrGpu::setRenderTarget().
    235      *
    236      * @return    handle to render target or NULL if the texture is not a
    237      *            render target
    238      */
    239     GrRenderTarget* asRenderTarget() { return fRenderTarget; }
    240 
    241     /**
    242      * Removes the reference on the associated GrRenderTarget held by this
    243      * texture. Afterwards asRenderTarget() will return NULL. The
    244      * GrRenderTarget survives the release if another ref is held on it.
    245      */
    246     void releaseRenderTarget() {
    247         if (NULL != fRenderTarget) {
    248             GrAssert(fRenderTarget->asTexture() == this);
    249             fRenderTarget->onTextureReleaseRenderTarget();
    250             fRenderTarget->unref();
    251             fRenderTarget = NULL;
    252         }
    253     }
    254 
    255     /**
    256      *  Return the native ID or handle to the texture, depending on the
    257      *  platform. e.g. on opengl, return the texture ID.
    258      */
    259     virtual intptr_t getTextureHandle() = 0;
    260 
    261 #if GR_DEBUG
    262     void validate() const {
    263         this->INHERITED::validate();
    264     }
    265 #else
    266     void validate() const {}
    267 #endif
    268 
    269 protected:
    270     GrRenderTarget* fRenderTarget; // texture refs its rt representation
    271                                    // base class cons sets to NULL
    272                                    // subclass cons can create and set
    273 
    274     GrTexture(GrGpu* gpu,
    275               int width,
    276               int height,
    277               GrPixelConfig config)
    278     : INHERITED(gpu)
    279     , fRenderTarget(NULL)
    280     , fWidth(width)
    281     , fHeight(height)
    282     , fConfig(config) {
    283         // only make sense if alloc size is pow2
    284         fShiftFixedX = 31 - Gr_clz(fWidth);
    285         fShiftFixedY = 31 - Gr_clz(fHeight);
    286     }
    287 
    288     // GrResource overrides
    289     virtual void onRelease() {
    290         releaseRenderTarget();
    291     }
    292 
    293     virtual void onAbandon() {
    294         if (NULL != fRenderTarget) {
    295             fRenderTarget->abandon();
    296         }
    297     }
    298 
    299 private:
    300     int fWidth;
    301     int fHeight;
    302     // these two shift a fixed-point value into normalized coordinates
    303     // for this texture if the texture is power of two sized.
    304     int      fShiftFixedX;
    305     int      fShiftFixedY;
    306 
    307     GrPixelConfig fConfig;
    308 
    309     typedef GrResource INHERITED;
    310 };
    311 
    312 #endif
    313 
    314