blob: c5375c9f34fc87e0245126ec6e5ac66509bf8ca8 [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"
20
bsalomon@google.com8fe72472011-03-30 21:26:44 +000021#define GPUGL static_cast<GrGpuGL*>(getGpu())
22
23GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu,
24 const GLRenderTargetIDs& ids,
bsalomon@google.com1da07462011-03-10 14:51:57 +000025 GrGLTexID* texID,
bsalomon@google.comcee661a2011-07-26 12:32:36 +000026 GrPixelConfig config,
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,
bsalomon@google.comcee661a2011-07-26 12:32:36 +000032 viewport.fHeight, config,
33 stencilBits, isMultisampled) {
reed@google.comac10a2d2010-12-22 21:39:39 +000034 fRTFBOID = ids.fRTFBOID;
35 fTexFBOID = ids.fTexFBOID;
36 fStencilRenderbufferID = ids.fStencilRenderbufferID;
37 fMSColorRenderbufferID = ids.fMSColorRenderbufferID;
reed@google.comac10a2d2010-12-22 21:39:39 +000038 fViewport = viewport;
39 fOwnIDs = ids.fOwnIDs;
bsalomon@google.com1da07462011-03-10 14:51:57 +000040 fTexIDObj = texID;
41 GrSafeRef(fTexIDObj);
reed@google.comac10a2d2010-12-22 21:39:39 +000042}
43
bsalomon@google.com8fe72472011-03-30 21:26:44 +000044void GrGLRenderTarget::onRelease() {
Scroggoc29d7cd2011-06-16 13:14:21 +000045 GPUGL->notifyRenderTargetDelete(this);
reed@google.comac10a2d2010-12-22 21:39:39 +000046 if (fOwnIDs) {
47 if (fTexFBOID) {
twiz@google.com59a190b2011-03-14 21:23:01 +000048 GR_GL(DeleteFramebuffers(1, &fTexFBOID));
reed@google.comac10a2d2010-12-22 21:39:39 +000049 }
50 if (fRTFBOID && fRTFBOID != fTexFBOID) {
twiz@google.com59a190b2011-03-14 21:23:01 +000051 GR_GL(DeleteFramebuffers(1, &fRTFBOID));
reed@google.comac10a2d2010-12-22 21:39:39 +000052 }
53 if (fStencilRenderbufferID) {
twiz@google.com59a190b2011-03-14 21:23:01 +000054 GR_GL(DeleteRenderbuffers(1, &fStencilRenderbufferID));
reed@google.comac10a2d2010-12-22 21:39:39 +000055 }
56 if (fMSColorRenderbufferID) {
twiz@google.com59a190b2011-03-14 21:23:01 +000057 GR_GL(DeleteRenderbuffers(1, &fMSColorRenderbufferID));
reed@google.comac10a2d2010-12-22 21:39:39 +000058 }
59 }
bsalomon@google.com8fe72472011-03-30 21:26:44 +000060 fRTFBOID = 0;
61 fTexFBOID = 0;
62 fStencilRenderbufferID = 0;
63 fMSColorRenderbufferID = 0;
bsalomon@google.com1da07462011-03-10 14:51:57 +000064 GrSafeUnref(fTexIDObj);
bsalomon@google.com8fe72472011-03-30 21:26:44 +000065 fTexIDObj = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +000066}
67
bsalomon@google.com8fe72472011-03-30 21:26:44 +000068void GrGLRenderTarget::onAbandon() {
reed@google.comac10a2d2010-12-22 21:39:39 +000069 fRTFBOID = 0;
70 fTexFBOID = 0;
71 fStencilRenderbufferID = 0;
72 fMSColorRenderbufferID = 0;
bsalomon@google.com1da07462011-03-10 14:51:57 +000073 if (NULL != fTexIDObj) {
74 fTexIDObj->abandon();
bsalomon@google.com8fe72472011-03-30 21:26:44 +000075 fTexIDObj = NULL;
bsalomon@google.com1da07462011-03-10 14:51:57 +000076 }
reed@google.comac10a2d2010-12-22 21:39:39 +000077}
78
79
80////////////////////////////////////////////////////////////////////////////////
81
twiz@google.comb65e0cb2011-03-18 20:41:44 +000082const GrGLenum* GrGLTexture::WrapMode2GLWrap() {
83 static const GrGLenum mirrorRepeatModes[] = {
84 GR_GL_CLAMP_TO_EDGE,
85 GR_GL_REPEAT,
86 GR_GL_MIRRORED_REPEAT
87 };
88
89 static const GrGLenum repeatModes[] = {
90 GR_GL_CLAMP_TO_EDGE,
91 GR_GL_REPEAT,
92 GR_GL_REPEAT
93 };
94
95 if (GR_GL_SUPPORT_ES1 && !GR_GL_SUPPORT_ES2) {
96 return repeatModes; // GL_MIRRORED_REPEAT not supported.
97 } else {
98 return mirrorRepeatModes;
99 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000100};
101
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000102GrGLTexture::GrGLTexture(GrGpuGL* gpu,
103 const GLTextureDesc& textureDesc,
reed@google.comac10a2d2010-12-22 21:39:39 +0000104 const GLRenderTargetIDs& rtIDs,
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000105 const TexParams& initialTexParams)
106 : INHERITED(gpu,
107 textureDesc.fContentWidth,
108 textureDesc.fContentHeight,
109 textureDesc.fFormat) {
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000110
111 fTexParams = initialTexParams;
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000112 fTexIDObj = new GrGLTexID(textureDesc.fTextureID,
113 textureDesc.fOwnsID);
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000114 fUploadFormat = textureDesc.fUploadFormat;
115 fUploadByteCount = textureDesc.fUploadByteCount;
116 fUploadType = textureDesc.fUploadType;
117 fOrientation = textureDesc.fOrientation;
118 fAllocWidth = textureDesc.fAllocWidth;
119 fAllocHeight = textureDesc.fAllocHeight;
120 fScaleX = GrIntToScalar(textureDesc.fContentWidth) /
121 textureDesc.fAllocWidth;
122 fScaleY = GrIntToScalar(textureDesc.fContentHeight) /
123 textureDesc.fAllocHeight;
reed@google.comac10a2d2010-12-22 21:39:39 +0000124
125 GrAssert(0 != textureDesc.fTextureID);
126
127 if (rtIDs.fTexFBOID) {
bsalomon@google.com8895a7a2011-02-18 16:09:55 +0000128 // we render to the top left
129 GrGLIRect vp;
reed@google.comac10a2d2010-12-22 21:39:39 +0000130 vp.fLeft = 0;
bsalomon@google.com8895a7a2011-02-18 16:09:55 +0000131 vp.fWidth = textureDesc.fContentWidth;
132 vp.fHeight = textureDesc.fContentHeight;
133 vp.fBottom = textureDesc.fAllocHeight - textureDesc.fContentHeight;
134
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000135 fRenderTarget = new GrGLRenderTarget(gpu, rtIDs, fTexIDObj,
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000136 textureDesc.fFormat,
bsalomon@google.com1da07462011-03-10 14:51:57 +0000137 textureDesc.fStencilBits,
bsalomon@google.comf954d8d2011-04-06 17:50:02 +0000138 rtIDs.fRTFBOID != rtIDs.fTexFBOID,
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000139 vp, this);
reed@google.comac10a2d2010-12-22 21:39:39 +0000140 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000141}
142
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000143void GrGLTexture::onRelease() {
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000144 INHERITED::onRelease();
Scroggoc29d7cd2011-06-16 13:14:21 +0000145 GPUGL->notifyTextureDelete(this);
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000146 if (NULL != fTexIDObj) {
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000147 fTexIDObj->unref();
148 fTexIDObj = NULL;
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000149 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000150}
151
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000152void GrGLTexture::onAbandon() {
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000153 INHERITED::onAbandon();
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000154 if (NULL != fTexIDObj) {
155 fTexIDObj->abandon();
156 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000157}
158
bsalomon@google.com79d2dbe2011-06-13 19:28:02 +0000159void GrGLTexture::uploadTextureData(int x,
160 int y,
161 int width,
162 int height,
junov@google.com4ee7ae52011-06-30 17:30:49 +0000163 const void* srcData,
164 size_t rowBytes) {
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000165
166 GPUGL->setSpareTextureUnit();
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000167
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000168 // ES2 glCompressedTexSubImage2D doesn't support any formats
reed@google.comac10a2d2010-12-22 21:39:39 +0000169 // (at least without extensions)
bsalomon@google.comc312bf92011-03-21 21:10:33 +0000170 GrAssert(fUploadFormat != GR_GL_PALETTE8_RGBA8);
reed@google.comac10a2d2010-12-22 21:39:39 +0000171
junov@google.com4ee7ae52011-06-30 17:30:49 +0000172 // in case we need a temporary, trimmed copy of the src pixels
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000173 SkAutoSMalloc<128 * 128> tempStorage;
junov@google.com4ee7ae52011-06-30 17:30:49 +0000174
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000175 if (!rowBytes) {
176 rowBytes = fUploadByteCount * width;
177 }
junov@google.com4ee7ae52011-06-30 17:30:49 +0000178 /*
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000179 * check whether to allocate a temporary buffer for flipping y or
180 * because our srcData has extra bytes past each row. If so, we need
181 * to trim those off here, since GL ES doesn't let us specify
182 * GL_UNPACK_ROW_LENGTH.
junov@google.com4ee7ae52011-06-30 17:30:49 +0000183 */
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000184 bool restoreGLRowLength = false;
185 bool flipY = kBottomUp_Orientation == fOrientation;
186 if (GR_GL_SUPPORT_DESKTOP && !flipY) {
187 // can't use this for flipping, only non-neg values allowed. :(
junov@google.com4ee7ae52011-06-30 17:30:49 +0000188 if (srcData && rowBytes) {
189 GR_GL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH,
190 rowBytes / fUploadByteCount));
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000191 restoreGLRowLength = true;
junov@google.com4ee7ae52011-06-30 17:30:49 +0000192 }
193 } else {
194 size_t trimRowBytes = width * fUploadByteCount;
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000195 if (srcData && (trimRowBytes < rowBytes || flipY)) {
junov@google.com4ee7ae52011-06-30 17:30:49 +0000196 // copy the data into our new storage, skipping the trailing bytes
197 size_t trimSize = height * trimRowBytes;
198 const char* src = (const char*)srcData;
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000199 if (flipY) {
200 src += (height - 1) * rowBytes;
201 }
202 char* dst = (char*)tempStorage.realloc(trimSize);
junov@google.com4ee7ae52011-06-30 17:30:49 +0000203 for (int y = 0; y < height; y++) {
204 memcpy(dst, src, trimRowBytes);
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000205 if (flipY) {
206 src -= rowBytes;
207 } else {
208 src += rowBytes;
209 }
junov@google.com4ee7ae52011-06-30 17:30:49 +0000210 dst += trimRowBytes;
211 }
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000212 // now point srcData to our copied version
213 srcData = tempStorage.get();
junov@google.com4ee7ae52011-06-30 17:30:49 +0000214 }
215 }
216
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000217 if (flipY) {
218 y = this->height() - (y + height);
219 }
twiz@google.com0f31ca72011-03-18 17:38:11 +0000220 GR_GL(BindTexture(GR_GL_TEXTURE_2D, fTexIDObj->id()));
221 GR_GL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, fUploadByteCount));
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000222 GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, x, y, width, height,
reed@google.comac10a2d2010-12-22 21:39:39 +0000223 fUploadFormat, fUploadType, srcData));
224
junov@google.com4ee7ae52011-06-30 17:30:49 +0000225 if (GR_GL_SUPPORT_DESKTOP) {
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000226 if (restoreGLRowLength) {
junov@google.com4ee7ae52011-06-30 17:30:49 +0000227 GR_GL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
228 }
229 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000230}
231
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000232intptr_t GrGLTexture::getTextureHandle() const {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000233 return fTexIDObj->id();
reed@google.comac10a2d2010-12-22 21:39:39 +0000234}
235