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 #include "GrGLTexture.h"
19 #include "GrGpuGL.h"
20
21 #define GPUGL static_cast<GrGpuGL*>(getGpu())
22
GrGLRenderTarget(GrGpuGL * gpu,const GLRenderTargetIDs & ids,GrGLTexID * texID,GrGLuint stencilBits,bool isMultisampled,const GrGLIRect & viewport,GrGLTexture * texture)23 GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu,
24 const GLRenderTargetIDs& ids,
25 GrGLTexID* texID,
26 GrGLuint stencilBits,
27 bool isMultisampled,
28 const GrGLIRect& viewport,
29 GrGLTexture* texture)
30 : INHERITED(gpu, texture, viewport.fWidth,
31 viewport.fHeight, stencilBits, isMultisampled) {
32 fRTFBOID = ids.fRTFBOID;
33 fTexFBOID = ids.fTexFBOID;
34 fStencilRenderbufferID = ids.fStencilRenderbufferID;
35 fMSColorRenderbufferID = ids.fMSColorRenderbufferID;
36 fViewport = viewport;
37 fOwnIDs = ids.fOwnIDs;
38 fTexIDObj = texID;
39 GrSafeRef(fTexIDObj);
40 }
41
onRelease()42 void GrGLRenderTarget::onRelease() {
43 if (fOwnIDs) {
44 if (fTexFBOID) {
45 GPUGL->notifyRenderTargetDelete(this);
46 GR_GL(DeleteFramebuffers(1, &fTexFBOID));
47 }
48 if (fRTFBOID && fRTFBOID != fTexFBOID) {
49 GR_GL(DeleteFramebuffers(1, &fRTFBOID));
50 }
51 if (fStencilRenderbufferID) {
52 GR_GL(DeleteRenderbuffers(1, &fStencilRenderbufferID));
53 }
54 if (fMSColorRenderbufferID) {
55 GR_GL(DeleteRenderbuffers(1, &fMSColorRenderbufferID));
56 }
57 }
58 fRTFBOID = 0;
59 fTexFBOID = 0;
60 fStencilRenderbufferID = 0;
61 fMSColorRenderbufferID = 0;
62 GrSafeUnref(fTexIDObj);
63 fTexIDObj = NULL;
64 }
65
onAbandon()66 void GrGLRenderTarget::onAbandon() {
67 fRTFBOID = 0;
68 fTexFBOID = 0;
69 fStencilRenderbufferID = 0;
70 fMSColorRenderbufferID = 0;
71 if (NULL != fTexIDObj) {
72 fTexIDObj->abandon();
73 fTexIDObj = NULL;
74 }
75 }
76
77
78 ////////////////////////////////////////////////////////////////////////////////
79
WrapMode2GLWrap()80 const GrGLenum* GrGLTexture::WrapMode2GLWrap() {
81 static const GrGLenum mirrorRepeatModes[] = {
82 GR_GL_CLAMP_TO_EDGE,
83 GR_GL_REPEAT,
84 GR_GL_MIRRORED_REPEAT
85 };
86
87 static const GrGLenum repeatModes[] = {
88 GR_GL_CLAMP_TO_EDGE,
89 GR_GL_REPEAT,
90 GR_GL_REPEAT
91 };
92
93 if (GR_GL_SUPPORT_ES1 && !GR_GL_SUPPORT_ES2) {
94 return repeatModes; // GL_MIRRORED_REPEAT not supported.
95 } else {
96 return mirrorRepeatModes;
97 }
98 };
99
GrGLTexture(GrGpuGL * gpu,const GLTextureDesc & textureDesc,const GLRenderTargetIDs & rtIDs,const TexParams & initialTexParams)100 GrGLTexture::GrGLTexture(GrGpuGL* gpu,
101 const GLTextureDesc& textureDesc,
102 const GLRenderTargetIDs& rtIDs,
103 const TexParams& initialTexParams)
104 : INHERITED(gpu,
105 textureDesc.fContentWidth,
106 textureDesc.fContentHeight,
107 textureDesc.fFormat) {
108
109 fTexParams = initialTexParams;
110 fTexIDObj = new GrGLTexID(textureDesc.fTextureID,
111 textureDesc.fOwnsID);
112 fUploadFormat = textureDesc.fUploadFormat;
113 fUploadByteCount = textureDesc.fUploadByteCount;
114 fUploadType = textureDesc.fUploadType;
115 fOrientation = textureDesc.fOrientation;
116 fAllocWidth = textureDesc.fAllocWidth;
117 fAllocHeight = textureDesc.fAllocHeight;
118 fScaleX = GrIntToScalar(textureDesc.fContentWidth) /
119 textureDesc.fAllocWidth;
120 fScaleY = GrIntToScalar(textureDesc.fContentHeight) /
121 textureDesc.fAllocHeight;
122
123 GrAssert(0 != textureDesc.fTextureID);
124
125 if (rtIDs.fTexFBOID) {
126 // we render to the top left
127 GrGLIRect vp;
128 vp.fLeft = 0;
129 vp.fWidth = textureDesc.fContentWidth;
130 vp.fHeight = textureDesc.fContentHeight;
131 vp.fBottom = textureDesc.fAllocHeight - textureDesc.fContentHeight;
132
133 fRenderTarget = new GrGLRenderTarget(gpu, rtIDs, fTexIDObj,
134 textureDesc.fStencilBits,
135 rtIDs.fRTFBOID != rtIDs.fTexFBOID,
136 vp, this);
137 }
138 }
139
onRelease()140 void GrGLTexture::onRelease() {
141 INHERITED::onRelease();
142 if (NULL != fTexIDObj) {
143 GPUGL->notifyTextureDelete(this);
144 fTexIDObj->unref();
145 fTexIDObj = NULL;
146 }
147 }
148
onAbandon()149 void GrGLTexture::onAbandon() {
150 INHERITED::onAbandon();
151 if (NULL != fTexIDObj) {
152 fTexIDObj->abandon();
153 }
154 }
155
uploadTextureData(uint32_t x,uint32_t y,uint32_t width,uint32_t height,const void * srcData)156 void GrGLTexture::uploadTextureData(uint32_t x,
157 uint32_t y,
158 uint32_t width,
159 uint32_t height,
160 const void* srcData) {
161
162 GPUGL->setSpareTextureUnit();
163
164 // glCompressedTexSubImage2D doesn't support any formats
165 // (at least without extensions)
166 GrAssert(fUploadFormat != GR_GL_PALETTE8_RGBA8);
167
168 // If we need to update textures that are created upside down
169 // then we have to modify this code to flip the srcData
170 GrAssert(kTopDown_Orientation == fOrientation);
171 GR_GL(BindTexture(GR_GL_TEXTURE_2D, fTexIDObj->id()));
172 GR_GL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, fUploadByteCount));
173 GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, x, y, width, height,
174 fUploadFormat, fUploadType, srcData));
175
176 }
177
getTextureHandle()178 intptr_t GrGLTexture::getTextureHandle() {
179 return fTexIDObj->id();
180 }
181
182