blob: d36e21b247024ab353ba71f0afc30295277a1c97 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
bsalomon@google.com1da07462011-03-10 14:51:57 +00002 Copyright 2011 Google Inc.
reed@google.comac10a2d2010-12-22 21:39:39 +00003
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"
junov@google.com4ee7ae52011-06-30 17:30:49 +000020#include "GrMemory.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000021
bsalomon@google.com8fe72472011-03-30 21:26:44 +000022#define GPUGL static_cast<GrGpuGL*>(getGpu())
23
24GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu,
25 const GLRenderTargetIDs& ids,
bsalomon@google.com1da07462011-03-10 14:51:57 +000026 GrGLTexID* texID,
twiz@google.com0f31ca72011-03-18 17:38:11 +000027 GrGLuint stencilBits,
bsalomon@google.comf954d8d2011-04-06 17:50:02 +000028 bool isMultisampled,
bsalomon@google.com8895a7a2011-02-18 16:09:55 +000029 const GrGLIRect& viewport,
bsalomon@google.com8fe72472011-03-30 21:26:44 +000030 GrGLTexture* texture)
bsalomon@google.comf954d8d2011-04-06 17:50:02 +000031 : INHERITED(gpu, texture, viewport.fWidth,
32 viewport.fHeight, stencilBits, isMultisampled) {
reed@google.comac10a2d2010-12-22 21:39:39 +000033 fRTFBOID = ids.fRTFBOID;
34 fTexFBOID = ids.fTexFBOID;
35 fStencilRenderbufferID = ids.fStencilRenderbufferID;
36 fMSColorRenderbufferID = ids.fMSColorRenderbufferID;
reed@google.comac10a2d2010-12-22 21:39:39 +000037 fViewport = viewport;
38 fOwnIDs = ids.fOwnIDs;
bsalomon@google.com1da07462011-03-10 14:51:57 +000039 fTexIDObj = texID;
40 GrSafeRef(fTexIDObj);
reed@google.comac10a2d2010-12-22 21:39:39 +000041}
42
bsalomon@google.com8fe72472011-03-30 21:26:44 +000043void GrGLRenderTarget::onRelease() {
Scroggoc29d7cd2011-06-16 13:14:21 +000044 GPUGL->notifyRenderTargetDelete(this);
reed@google.comac10a2d2010-12-22 21:39:39 +000045 if (fOwnIDs) {
46 if (fTexFBOID) {
twiz@google.com59a190b2011-03-14 21:23:01 +000047 GR_GL(DeleteFramebuffers(1, &fTexFBOID));
reed@google.comac10a2d2010-12-22 21:39:39 +000048 }
49 if (fRTFBOID && fRTFBOID != fTexFBOID) {
twiz@google.com59a190b2011-03-14 21:23:01 +000050 GR_GL(DeleteFramebuffers(1, &fRTFBOID));
reed@google.comac10a2d2010-12-22 21:39:39 +000051 }
52 if (fStencilRenderbufferID) {
twiz@google.com59a190b2011-03-14 21:23:01 +000053 GR_GL(DeleteRenderbuffers(1, &fStencilRenderbufferID));
reed@google.comac10a2d2010-12-22 21:39:39 +000054 }
55 if (fMSColorRenderbufferID) {
twiz@google.com59a190b2011-03-14 21:23:01 +000056 GR_GL(DeleteRenderbuffers(1, &fMSColorRenderbufferID));
reed@google.comac10a2d2010-12-22 21:39:39 +000057 }
58 }
bsalomon@google.com8fe72472011-03-30 21:26:44 +000059 fRTFBOID = 0;
60 fTexFBOID = 0;
61 fStencilRenderbufferID = 0;
62 fMSColorRenderbufferID = 0;
bsalomon@google.com1da07462011-03-10 14:51:57 +000063 GrSafeUnref(fTexIDObj);
bsalomon@google.com8fe72472011-03-30 21:26:44 +000064 fTexIDObj = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +000065}
66
bsalomon@google.com8fe72472011-03-30 21:26:44 +000067void GrGLRenderTarget::onAbandon() {
reed@google.comac10a2d2010-12-22 21:39:39 +000068 fRTFBOID = 0;
69 fTexFBOID = 0;
70 fStencilRenderbufferID = 0;
71 fMSColorRenderbufferID = 0;
bsalomon@google.com1da07462011-03-10 14:51:57 +000072 if (NULL != fTexIDObj) {
73 fTexIDObj->abandon();
bsalomon@google.com8fe72472011-03-30 21:26:44 +000074 fTexIDObj = NULL;
bsalomon@google.com1da07462011-03-10 14:51:57 +000075 }
reed@google.comac10a2d2010-12-22 21:39:39 +000076}
77
78
79////////////////////////////////////////////////////////////////////////////////
80
twiz@google.comb65e0cb2011-03-18 20:41:44 +000081const GrGLenum* GrGLTexture::WrapMode2GLWrap() {
82 static const GrGLenum mirrorRepeatModes[] = {
83 GR_GL_CLAMP_TO_EDGE,
84 GR_GL_REPEAT,
85 GR_GL_MIRRORED_REPEAT
86 };
87
88 static const GrGLenum repeatModes[] = {
89 GR_GL_CLAMP_TO_EDGE,
90 GR_GL_REPEAT,
91 GR_GL_REPEAT
92 };
93
94 if (GR_GL_SUPPORT_ES1 && !GR_GL_SUPPORT_ES2) {
95 return repeatModes; // GL_MIRRORED_REPEAT not supported.
96 } else {
97 return mirrorRepeatModes;
98 }
reed@google.comac10a2d2010-12-22 21:39:39 +000099};
100
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000101GrGLTexture::GrGLTexture(GrGpuGL* gpu,
102 const GLTextureDesc& textureDesc,
reed@google.comac10a2d2010-12-22 21:39:39 +0000103 const GLRenderTargetIDs& rtIDs,
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000104 const TexParams& initialTexParams)
105 : INHERITED(gpu,
106 textureDesc.fContentWidth,
107 textureDesc.fContentHeight,
108 textureDesc.fFormat) {
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000109
110 fTexParams = initialTexParams;
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000111 fTexIDObj = new GrGLTexID(textureDesc.fTextureID,
112 textureDesc.fOwnsID);
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000113 fUploadFormat = textureDesc.fUploadFormat;
114 fUploadByteCount = textureDesc.fUploadByteCount;
115 fUploadType = textureDesc.fUploadType;
116 fOrientation = textureDesc.fOrientation;
117 fAllocWidth = textureDesc.fAllocWidth;
118 fAllocHeight = textureDesc.fAllocHeight;
119 fScaleX = GrIntToScalar(textureDesc.fContentWidth) /
120 textureDesc.fAllocWidth;
121 fScaleY = GrIntToScalar(textureDesc.fContentHeight) /
122 textureDesc.fAllocHeight;
reed@google.comac10a2d2010-12-22 21:39:39 +0000123
124 GrAssert(0 != textureDesc.fTextureID);
125
126 if (rtIDs.fTexFBOID) {
bsalomon@google.com8895a7a2011-02-18 16:09:55 +0000127 // we render to the top left
128 GrGLIRect vp;
reed@google.comac10a2d2010-12-22 21:39:39 +0000129 vp.fLeft = 0;
bsalomon@google.com8895a7a2011-02-18 16:09:55 +0000130 vp.fWidth = textureDesc.fContentWidth;
131 vp.fHeight = textureDesc.fContentHeight;
132 vp.fBottom = textureDesc.fAllocHeight - textureDesc.fContentHeight;
133
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000134 fRenderTarget = new GrGLRenderTarget(gpu, rtIDs, fTexIDObj,
bsalomon@google.com1da07462011-03-10 14:51:57 +0000135 textureDesc.fStencilBits,
bsalomon@google.comf954d8d2011-04-06 17:50:02 +0000136 rtIDs.fRTFBOID != rtIDs.fTexFBOID,
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000137 vp, this);
reed@google.comac10a2d2010-12-22 21:39:39 +0000138 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000139}
140
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000141void GrGLTexture::onRelease() {
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000142 INHERITED::onRelease();
Scroggoc29d7cd2011-06-16 13:14:21 +0000143 GPUGL->notifyTextureDelete(this);
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000144 if (NULL != fTexIDObj) {
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000145 fTexIDObj->unref();
146 fTexIDObj = NULL;
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000147 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000148}
149
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000150void GrGLTexture::onAbandon() {
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000151 INHERITED::onAbandon();
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000152 if (NULL != fTexIDObj) {
153 fTexIDObj->abandon();
154 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000155}
156
bsalomon@google.com79d2dbe2011-06-13 19:28:02 +0000157void GrGLTexture::uploadTextureData(int x,
158 int y,
159 int width,
160 int height,
junov@google.com4ee7ae52011-06-30 17:30:49 +0000161 const void* srcData,
162 size_t rowBytes) {
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000163
164 GPUGL->setSpareTextureUnit();
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000165
reed@google.comac10a2d2010-12-22 21:39:39 +0000166 // glCompressedTexSubImage2D doesn't support any formats
167 // (at least without extensions)
bsalomon@google.comc312bf92011-03-21 21:10:33 +0000168 GrAssert(fUploadFormat != GR_GL_PALETTE8_RGBA8);
reed@google.comac10a2d2010-12-22 21:39:39 +0000169
junov@google.com4ee7ae52011-06-30 17:30:49 +0000170 // in case we need a temporary, trimmed copy of the src pixels
171 GrAutoSMalloc<128 * 128> trimStorage;
172
173 /*
174 * check if our srcData has extra bytes past each row. If so, we need
175 * to trim those off here, since GL doesn't let us pass the rowBytes as
176 * a parameter to glTexImage2D
177 */
178
179 if (GR_GL_SUPPORT_DESKTOP) {
180 if (srcData && rowBytes) {
181 GR_GL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH,
182 rowBytes / fUploadByteCount));
183 }
184 } else {
185 size_t trimRowBytes = width * fUploadByteCount;
186 if (srcData && (trimRowBytes < rowBytes)) {
187 // copy the data into our new storage, skipping the trailing bytes
188 size_t trimSize = height * trimRowBytes;
189 const char* src = (const char*)srcData;
190 char* dst = (char*)trimStorage.realloc(trimSize);
191 for (int y = 0; y < height; y++) {
192 memcpy(dst, src, trimRowBytes);
193 src += rowBytes;
194 dst += trimRowBytes;
195 }
196 // now point srcData to our trimmed version
197 srcData = trimStorage.get();
198 }
199 }
200
reed@google.comac10a2d2010-12-22 21:39:39 +0000201 // If we need to update textures that are created upside down
202 // then we have to modify this code to flip the srcData
203 GrAssert(kTopDown_Orientation == fOrientation);
twiz@google.com0f31ca72011-03-18 17:38:11 +0000204 GR_GL(BindTexture(GR_GL_TEXTURE_2D, fTexIDObj->id()));
205 GR_GL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, fUploadByteCount));
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000206 GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, x, y, width, height,
reed@google.comac10a2d2010-12-22 21:39:39 +0000207 fUploadFormat, fUploadType, srcData));
208
junov@google.com4ee7ae52011-06-30 17:30:49 +0000209 if (GR_GL_SUPPORT_DESKTOP) {
210 if (srcData && rowBytes) {
211 GR_GL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
212 }
213 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000214}
215
216intptr_t GrGLTexture::getTextureHandle() {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000217 return fTexIDObj->id();
reed@google.comac10a2d2010-12-22 21:39:39 +0000218}
219