blob: 02ddc536d3b7b7288dd56d8446fcb0dc5a503358 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.comac10a2d2010-12-22 21:39:39 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@google.comac10a2d2010-12-22 21:39:39 +00007 */
8
9
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
reed@google.comac10a2d2010-12-22 21:39:39 +000011#include "GrGLTexture.h"
12#include "GrGpuGL.h"
13
bsalomon@google.com8fe72472011-03-30 21:26:44 +000014#define GPUGL static_cast<GrGpuGL*>(getGpu())
15
16GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu,
17 const GLRenderTargetIDs& ids,
bsalomon@google.com1da07462011-03-10 14:51:57 +000018 GrGLTexID* texID,
bsalomon@google.comcee661a2011-07-26 12:32:36 +000019 GrPixelConfig config,
twiz@google.com0f31ca72011-03-18 17:38:11 +000020 GrGLuint stencilBits,
bsalomon@google.comf954d8d2011-04-06 17:50:02 +000021 bool isMultisampled,
bsalomon@google.com8895a7a2011-02-18 16:09:55 +000022 const GrGLIRect& viewport,
bsalomon@google.com8fe72472011-03-30 21:26:44 +000023 GrGLTexture* texture)
bsalomon@google.comf954d8d2011-04-06 17:50:02 +000024 : INHERITED(gpu, texture, viewport.fWidth,
bsalomon@google.comcee661a2011-07-26 12:32:36 +000025 viewport.fHeight, config,
26 stencilBits, isMultisampled) {
reed@google.comac10a2d2010-12-22 21:39:39 +000027 fRTFBOID = ids.fRTFBOID;
28 fTexFBOID = ids.fTexFBOID;
29 fStencilRenderbufferID = ids.fStencilRenderbufferID;
30 fMSColorRenderbufferID = ids.fMSColorRenderbufferID;
reed@google.comac10a2d2010-12-22 21:39:39 +000031 fViewport = viewport;
32 fOwnIDs = ids.fOwnIDs;
bsalomon@google.com1da07462011-03-10 14:51:57 +000033 fTexIDObj = texID;
34 GrSafeRef(fTexIDObj);
reed@google.comac10a2d2010-12-22 21:39:39 +000035}
36
bsalomon@google.com8fe72472011-03-30 21:26:44 +000037void GrGLRenderTarget::onRelease() {
Scroggoc29d7cd2011-06-16 13:14:21 +000038 GPUGL->notifyRenderTargetDelete(this);
reed@google.comac10a2d2010-12-22 21:39:39 +000039 if (fOwnIDs) {
40 if (fTexFBOID) {
twiz@google.com59a190b2011-03-14 21:23:01 +000041 GR_GL(DeleteFramebuffers(1, &fTexFBOID));
reed@google.comac10a2d2010-12-22 21:39:39 +000042 }
43 if (fRTFBOID && fRTFBOID != fTexFBOID) {
twiz@google.com59a190b2011-03-14 21:23:01 +000044 GR_GL(DeleteFramebuffers(1, &fRTFBOID));
reed@google.comac10a2d2010-12-22 21:39:39 +000045 }
46 if (fStencilRenderbufferID) {
twiz@google.com59a190b2011-03-14 21:23:01 +000047 GR_GL(DeleteRenderbuffers(1, &fStencilRenderbufferID));
reed@google.comac10a2d2010-12-22 21:39:39 +000048 }
49 if (fMSColorRenderbufferID) {
twiz@google.com59a190b2011-03-14 21:23:01 +000050 GR_GL(DeleteRenderbuffers(1, &fMSColorRenderbufferID));
reed@google.comac10a2d2010-12-22 21:39:39 +000051 }
52 }
bsalomon@google.com8fe72472011-03-30 21:26:44 +000053 fRTFBOID = 0;
54 fTexFBOID = 0;
55 fStencilRenderbufferID = 0;
56 fMSColorRenderbufferID = 0;
bsalomon@google.com1da07462011-03-10 14:51:57 +000057 GrSafeUnref(fTexIDObj);
bsalomon@google.com8fe72472011-03-30 21:26:44 +000058 fTexIDObj = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +000059}
60
bsalomon@google.com8fe72472011-03-30 21:26:44 +000061void GrGLRenderTarget::onAbandon() {
reed@google.comac10a2d2010-12-22 21:39:39 +000062 fRTFBOID = 0;
63 fTexFBOID = 0;
64 fStencilRenderbufferID = 0;
65 fMSColorRenderbufferID = 0;
bsalomon@google.com1da07462011-03-10 14:51:57 +000066 if (NULL != fTexIDObj) {
67 fTexIDObj->abandon();
bsalomon@google.com8fe72472011-03-30 21:26:44 +000068 fTexIDObj = NULL;
bsalomon@google.com1da07462011-03-10 14:51:57 +000069 }
reed@google.comac10a2d2010-12-22 21:39:39 +000070}
71
72
73////////////////////////////////////////////////////////////////////////////////
74
twiz@google.comb65e0cb2011-03-18 20:41:44 +000075const GrGLenum* GrGLTexture::WrapMode2GLWrap() {
76 static const GrGLenum mirrorRepeatModes[] = {
77 GR_GL_CLAMP_TO_EDGE,
78 GR_GL_REPEAT,
79 GR_GL_MIRRORED_REPEAT
80 };
81
82 static const GrGLenum repeatModes[] = {
83 GR_GL_CLAMP_TO_EDGE,
84 GR_GL_REPEAT,
85 GR_GL_REPEAT
86 };
87
88 if (GR_GL_SUPPORT_ES1 && !GR_GL_SUPPORT_ES2) {
89 return repeatModes; // GL_MIRRORED_REPEAT not supported.
90 } else {
91 return mirrorRepeatModes;
92 }
reed@google.comac10a2d2010-12-22 21:39:39 +000093};
94
bsalomon@google.com8fe72472011-03-30 21:26:44 +000095GrGLTexture::GrGLTexture(GrGpuGL* gpu,
96 const GLTextureDesc& textureDesc,
reed@google.comac10a2d2010-12-22 21:39:39 +000097 const GLRenderTargetIDs& rtIDs,
bsalomon@google.com8fe72472011-03-30 21:26:44 +000098 const TexParams& initialTexParams)
99 : INHERITED(gpu,
100 textureDesc.fContentWidth,
101 textureDesc.fContentHeight,
102 textureDesc.fFormat) {
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000103
104 fTexParams = initialTexParams;
bsalomon@google.com5877ffd2011-04-11 17:58:48 +0000105 fTexIDObj = new GrGLTexID(textureDesc.fTextureID,
106 textureDesc.fOwnsID);
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000107 fUploadFormat = textureDesc.fUploadFormat;
108 fUploadByteCount = textureDesc.fUploadByteCount;
109 fUploadType = textureDesc.fUploadType;
110 fOrientation = textureDesc.fOrientation;
111 fAllocWidth = textureDesc.fAllocWidth;
112 fAllocHeight = textureDesc.fAllocHeight;
113 fScaleX = GrIntToScalar(textureDesc.fContentWidth) /
114 textureDesc.fAllocWidth;
115 fScaleY = GrIntToScalar(textureDesc.fContentHeight) /
116 textureDesc.fAllocHeight;
reed@google.comac10a2d2010-12-22 21:39:39 +0000117
118 GrAssert(0 != textureDesc.fTextureID);
119
120 if (rtIDs.fTexFBOID) {
bsalomon@google.com8895a7a2011-02-18 16:09:55 +0000121 // we render to the top left
122 GrGLIRect vp;
reed@google.comac10a2d2010-12-22 21:39:39 +0000123 vp.fLeft = 0;
bsalomon@google.com8895a7a2011-02-18 16:09:55 +0000124 vp.fWidth = textureDesc.fContentWidth;
125 vp.fHeight = textureDesc.fContentHeight;
126 vp.fBottom = textureDesc.fAllocHeight - textureDesc.fContentHeight;
127
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000128 fRenderTarget = new GrGLRenderTarget(gpu, rtIDs, fTexIDObj,
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000129 textureDesc.fFormat,
bsalomon@google.com1da07462011-03-10 14:51:57 +0000130 textureDesc.fStencilBits,
bsalomon@google.comf954d8d2011-04-06 17:50:02 +0000131 rtIDs.fRTFBOID != rtIDs.fTexFBOID,
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000132 vp, this);
reed@google.comac10a2d2010-12-22 21:39:39 +0000133 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000134}
135
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000136void GrGLTexture::onRelease() {
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000137 INHERITED::onRelease();
Scroggoc29d7cd2011-06-16 13:14:21 +0000138 GPUGL->notifyTextureDelete(this);
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000139 if (NULL != fTexIDObj) {
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000140 fTexIDObj->unref();
141 fTexIDObj = NULL;
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000142 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000143}
144
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000145void GrGLTexture::onAbandon() {
bsalomon@google.com6dcf4992011-04-05 21:16:14 +0000146 INHERITED::onAbandon();
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000147 if (NULL != fTexIDObj) {
148 fTexIDObj->abandon();
149 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000150}
151
bsalomon@google.com79d2dbe2011-06-13 19:28:02 +0000152void GrGLTexture::uploadTextureData(int x,
153 int y,
154 int width,
155 int height,
junov@google.com4ee7ae52011-06-30 17:30:49 +0000156 const void* srcData,
157 size_t rowBytes) {
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000158
159 GPUGL->setSpareTextureUnit();
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000160
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000161 // ES2 glCompressedTexSubImage2D doesn't support any formats
reed@google.comac10a2d2010-12-22 21:39:39 +0000162 // (at least without extensions)
bsalomon@google.comc312bf92011-03-21 21:10:33 +0000163 GrAssert(fUploadFormat != GR_GL_PALETTE8_RGBA8);
reed@google.comac10a2d2010-12-22 21:39:39 +0000164
junov@google.com4ee7ae52011-06-30 17:30:49 +0000165 // in case we need a temporary, trimmed copy of the src pixels
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000166 SkAutoSMalloc<128 * 128> tempStorage;
junov@google.com4ee7ae52011-06-30 17:30:49 +0000167
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000168 if (!rowBytes) {
169 rowBytes = fUploadByteCount * width;
170 }
junov@google.com4ee7ae52011-06-30 17:30:49 +0000171 /*
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000172 * check whether to allocate a temporary buffer for flipping y or
173 * because our srcData has extra bytes past each row. If so, we need
174 * to trim those off here, since GL ES doesn't let us specify
175 * GL_UNPACK_ROW_LENGTH.
junov@google.com4ee7ae52011-06-30 17:30:49 +0000176 */
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000177 bool restoreGLRowLength = false;
178 bool flipY = kBottomUp_Orientation == fOrientation;
179 if (GR_GL_SUPPORT_DESKTOP && !flipY) {
180 // can't use this for flipping, only non-neg values allowed. :(
junov@google.com4ee7ae52011-06-30 17:30:49 +0000181 if (srcData && rowBytes) {
182 GR_GL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH,
183 rowBytes / fUploadByteCount));
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000184 restoreGLRowLength = true;
junov@google.com4ee7ae52011-06-30 17:30:49 +0000185 }
186 } else {
187 size_t trimRowBytes = width * fUploadByteCount;
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000188 if (srcData && (trimRowBytes < rowBytes || flipY)) {
junov@google.com4ee7ae52011-06-30 17:30:49 +0000189 // copy the data into our new storage, skipping the trailing bytes
190 size_t trimSize = height * trimRowBytes;
191 const char* src = (const char*)srcData;
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000192 if (flipY) {
193 src += (height - 1) * rowBytes;
194 }
195 char* dst = (char*)tempStorage.realloc(trimSize);
junov@google.com4ee7ae52011-06-30 17:30:49 +0000196 for (int y = 0; y < height; y++) {
197 memcpy(dst, src, trimRowBytes);
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000198 if (flipY) {
199 src -= rowBytes;
200 } else {
201 src += rowBytes;
202 }
junov@google.com4ee7ae52011-06-30 17:30:49 +0000203 dst += trimRowBytes;
204 }
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000205 // now point srcData to our copied version
206 srcData = tempStorage.get();
junov@google.com4ee7ae52011-06-30 17:30:49 +0000207 }
208 }
209
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000210 if (flipY) {
211 y = this->height() - (y + height);
212 }
twiz@google.com0f31ca72011-03-18 17:38:11 +0000213 GR_GL(BindTexture(GR_GL_TEXTURE_2D, fTexIDObj->id()));
214 GR_GL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, fUploadByteCount));
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000215 GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, x, y, width, height,
reed@google.comac10a2d2010-12-22 21:39:39 +0000216 fUploadFormat, fUploadType, srcData));
217
junov@google.com4ee7ae52011-06-30 17:30:49 +0000218 if (GR_GL_SUPPORT_DESKTOP) {
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000219 if (restoreGLRowLength) {
junov@google.com4ee7ae52011-06-30 17:30:49 +0000220 GR_GL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
221 }
222 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000223}
224
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000225intptr_t GrGLTexture::getTextureHandle() const {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000226 return fTexIDObj->id();
reed@google.comac10a2d2010-12-22 21:39:39 +0000227}
228