blob: b75cad5ec01005c3bda375e6f2d693dc7299e145 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
2 Copyright 2010 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#include "GrGLTexture.h"
19#include "GrGpuGL.h"
20
21GrGLRenderTarget::GrGLRenderTarget(const GLRenderTargetIDs& ids,
22 const GrIRect& viewport,
23 GrGLTexture* texture,
24 GrGpuGL* gl) : INHERITED(texture) {
25 fGL = gl;
26 fRTFBOID = ids.fRTFBOID;
27 fTexFBOID = ids.fTexFBOID;
28 fStencilRenderbufferID = ids.fStencilRenderbufferID;
29 fMSColorRenderbufferID = ids.fMSColorRenderbufferID;
30 fNeedsResolve = false;
31 fViewport = viewport;
32 fOwnIDs = ids.fOwnIDs;
33 // viewport should be GL's viewport with top >= bottom
34 GrAssert(viewport.height() <= 0);
35}
36
37GrGLRenderTarget::~GrGLRenderTarget() {
38 fGL->notifyRenderTargetDelete(this);
39 if (fOwnIDs) {
40 if (fTexFBOID) {
41 GR_GLEXT(fGL->extensions(), DeleteFramebuffers(1, &fTexFBOID));
42 }
43 if (fRTFBOID && fRTFBOID != fTexFBOID) {
44 GR_GLEXT(fGL->extensions(), DeleteFramebuffers(1, &fRTFBOID));
45 }
46 if (fStencilRenderbufferID) {
47 GR_GLEXT(fGL->extensions(), DeleteRenderbuffers(1, &fStencilRenderbufferID));
48 }
49 if (fMSColorRenderbufferID) {
50 GR_GLEXT(fGL->extensions(), DeleteRenderbuffers(1, &fMSColorRenderbufferID));
51 }
52 }
53}
54
55void GrGLRenderTarget::abandon() {
56 fRTFBOID = 0;
57 fTexFBOID = 0;
58 fStencilRenderbufferID = 0;
59 fMSColorRenderbufferID = 0;
60}
61
62
63////////////////////////////////////////////////////////////////////////////////
64
65const GLenum GrGLTexture::gWrapMode2GLWrap[] = {
66 GL_CLAMP_TO_EDGE,
67 GL_REPEAT,
68#ifdef GL_MIRRORED_REPEAT
69 GL_MIRRORED_REPEAT
70#else
71 GL_REPEAT // GL_MIRRORED_REPEAT not supported :(
72#endif
73};
74
75
76GrGLTexture::GrGLTexture(const GLTextureDesc& textureDesc,
77 const GLRenderTargetIDs& rtIDs,
78 GrGpuGL* gl) :
79 INHERITED(textureDesc.fContentWidth,
80 textureDesc.fContentHeight,
81 textureDesc.fAllocWidth,
82 textureDesc.fAllocHeight,
83 textureDesc.fFormat),
84 fTextureID(textureDesc.fTextureID),
85 fUploadFormat(textureDesc.fUploadFormat),
86 fUploadByteCount(textureDesc.fUploadByteCount),
87 fUploadType(textureDesc.fUploadType),
88 fOrientation(textureDesc.fOrientation),
89 fRenderTarget(NULL),
90 fGpuGL(gl) {
91
92 GrAssert(0 != textureDesc.fTextureID);
93
94 if (rtIDs.fTexFBOID) {
95 GrIRect vp;
96 vp.fLeft = 0;
97 vp.fRight = (int32_t) textureDesc.fContentWidth;
98 // viewport for GL is top > bottom
99 vp.fTop = (int32_t) textureDesc.fAllocHeight;
100 vp.fBottom = (int32_t) textureDesc.fAllocHeight -
101 (int32_t)textureDesc.fContentHeight;
102 fRenderTarget = new GrGLRenderTarget(rtIDs, vp, this, gl);
103 }
104
105 fSamplerState.setClampNoFilter();
106
107 GR_GL(BindTexture(GL_TEXTURE_2D, fTextureID));
108 gl->notifyTextureBind(this);
109 GR_GL(TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
110 GR_GL(TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
111 GR_GL(TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
112 GR_GL(TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
113}
114
115GrGLTexture::~GrGLTexture() {
116 // make sure we haven't been abandoned
117 if (fTextureID) {
118 fGpuGL->notifyTextureDelete(this);
119 GR_GL(DeleteTextures(1, &fTextureID));
120 }
121 delete fRenderTarget;
122}
123
124void GrGLTexture::abandon() {
125 fTextureID = 0;
126 if (NULL != fRenderTarget) {
127 fRenderTarget->abandon();
128 }
129}
130
131bool GrGLTexture::isRenderTarget() const {
132 return NULL != fRenderTarget;
133}
134
135GrRenderTarget* GrGLTexture::asRenderTarget() {
136 return (GrRenderTarget*)fRenderTarget;
137}
138
139void GrGLTexture::removeRenderTarget() {
140 GrAssert(NULL != fRenderTarget);
141 if (NULL != fRenderTarget) {
142 // must do this notify before the delete
143 fGpuGL->notifyTextureRemoveRenderTarget(this);
144 delete fRenderTarget;
145 fRenderTarget = NULL;
146 }
147}
148
149void GrGLTexture::uploadTextureData(uint32_t x,
150 uint32_t y,
151 uint32_t width,
152 uint32_t height,
153 const void* srcData) {
154 // glCompressedTexSubImage2D doesn't support any formats
155 // (at least without extensions)
156 GrAssert(fUploadFormat != GR_PALETTE8_RGBA8);
157
158 // If we need to update textures that are created upside down
159 // then we have to modify this code to flip the srcData
160 GrAssert(kTopDown_Orientation == fOrientation);
161 GR_GL(BindTexture(GL_TEXTURE_2D, fTextureID));
162 fGpuGL->notifyTextureBind(this);
163 GR_GL(PixelStorei(GL_UNPACK_ALIGNMENT, fUploadByteCount));
164 GR_GL(TexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height,
165 fUploadFormat, fUploadType, srcData));
166
167}
168
169intptr_t GrGLTexture::getTextureHandle() {
170 return fTextureID;
171}
172
173
174