1/*
2 * Copyright 2011 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 "GrGLRenderTarget.h"
9
10#include "GrGLGpu.h"
11
12#define GPUGL static_cast<GrGLGpu*>(this->getGpu())
13#define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X)
14
15// Because this class is virtually derived from GrSurface we must explicitly call its constructor.
16GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc)
17    : GrSurface(gpu, idDesc.fLifeCycle, desc)
18    , INHERITED(gpu, idDesc.fLifeCycle, desc) {
19    this->init(desc, idDesc);
20    this->registerWithCache();
21}
22
23GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc,
24                                   Derived)
25    : GrSurface(gpu, idDesc.fLifeCycle, desc)
26    , INHERITED(gpu, idDesc.fLifeCycle, desc) {
27    this->init(desc, idDesc);
28}
29
30void GrGLRenderTarget::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) {
31    fRTFBOID                = idDesc.fRTFBOID;
32    fTexFBOID               = idDesc.fTexFBOID;
33    fMSColorRenderbufferID  = idDesc.fMSColorRenderbufferID;
34    fIsWrapped              = kWrapped_LifeCycle == idDesc.fLifeCycle;
35
36    fViewport.fLeft   = 0;
37    fViewport.fBottom = 0;
38    fViewport.fWidth  = desc.fWidth;
39    fViewport.fHeight = desc.fHeight;
40
41    // We own one color value for each MSAA sample.
42    int colorValuesPerPixel = SkTMax(1, fDesc.fSampleCnt);
43    if (fTexFBOID != fRTFBOID) {
44        // If we own the resolve buffer then that is one more sample per pixel.
45        colorValuesPerPixel += 1;
46    } else if (fTexFBOID != 0) {
47        // For auto-resolving FBOs, the MSAA buffer is free.
48        colorValuesPerPixel = 1;
49    }
50    SkASSERT(kUnknown_GrPixelConfig != fDesc.fConfig);
51    SkASSERT(!GrPixelConfigIsCompressed(fDesc.fConfig));
52    size_t colorBytes = GrBytesPerPixel(fDesc.fConfig);
53    SkASSERT(colorBytes > 0);
54    fGpuMemorySize = colorValuesPerPixel * fDesc.fWidth * fDesc.fHeight * colorBytes;
55}
56
57size_t GrGLRenderTarget::onGpuMemorySize() const {
58    return fGpuMemorySize;
59}
60
61void GrGLRenderTarget::onRelease() {
62    if (!fIsWrapped) {
63        if (fTexFBOID) {
64            GL_CALL(DeleteFramebuffers(1, &fTexFBOID));
65        }
66        if (fRTFBOID && fRTFBOID != fTexFBOID) {
67            GL_CALL(DeleteFramebuffers(1, &fRTFBOID));
68        }
69        if (fMSColorRenderbufferID) {
70            GL_CALL(DeleteRenderbuffers(1, &fMSColorRenderbufferID));
71        }
72    }
73    fRTFBOID                = 0;
74    fTexFBOID               = 0;
75    fMSColorRenderbufferID  = 0;
76    fIsWrapped              = false;
77    INHERITED::onRelease();
78}
79
80void GrGLRenderTarget::onAbandon() {
81    fRTFBOID                = 0;
82    fTexFBOID               = 0;
83    fMSColorRenderbufferID  = 0;
84    fIsWrapped              = false;
85    INHERITED::onAbandon();
86}
87