blob: e7db2eeffdda57bdc9c60564994045623f5b4449 [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
10#include "GrGLTexture.h"
bsalomon@google.comaa5b6732011-07-29 15:13:20 +000011
reed@google.comac10a2d2010-12-22 21:39:39 +000012#include "GrGpuGL.h"
13
bsalomon@google.com8fe72472011-03-30 21:26:44 +000014#define GPUGL static_cast<GrGpuGL*>(getGpu())
15
twiz@google.comb65e0cb2011-03-18 20:41:44 +000016const GrGLenum* GrGLTexture::WrapMode2GLWrap() {
17 static const GrGLenum mirrorRepeatModes[] = {
18 GR_GL_CLAMP_TO_EDGE,
19 GR_GL_REPEAT,
20 GR_GL_MIRRORED_REPEAT
21 };
22
23 static const GrGLenum repeatModes[] = {
24 GR_GL_CLAMP_TO_EDGE,
25 GR_GL_REPEAT,
26 GR_GL_REPEAT
27 };
28
29 if (GR_GL_SUPPORT_ES1 && !GR_GL_SUPPORT_ES2) {
30 return repeatModes; // GL_MIRRORED_REPEAT not supported.
31 } else {
32 return mirrorRepeatModes;
33 }
reed@google.comac10a2d2010-12-22 21:39:39 +000034};
35
bsalomon@google.com8fe72472011-03-30 21:26:44 +000036GrGLTexture::GrGLTexture(GrGpuGL* gpu,
37 const GLTextureDesc& textureDesc,
reed@google.comac10a2d2010-12-22 21:39:39 +000038 const GLRenderTargetIDs& rtIDs,
bsalomon@google.com8fe72472011-03-30 21:26:44 +000039 const TexParams& initialTexParams)
40 : INHERITED(gpu,
41 textureDesc.fContentWidth,
42 textureDesc.fContentHeight,
43 textureDesc.fFormat) {
bsalomon@google.comc6cf7232011-02-17 16:43:10 +000044
45 fTexParams = initialTexParams;
bsalomon@google.com5877ffd2011-04-11 17:58:48 +000046 fTexIDObj = new GrGLTexID(textureDesc.fTextureID,
47 textureDesc.fOwnsID);
bsalomon@google.comc6cf7232011-02-17 16:43:10 +000048 fUploadFormat = textureDesc.fUploadFormat;
49 fUploadByteCount = textureDesc.fUploadByteCount;
50 fUploadType = textureDesc.fUploadType;
51 fOrientation = textureDesc.fOrientation;
52 fAllocWidth = textureDesc.fAllocWidth;
53 fAllocHeight = textureDesc.fAllocHeight;
54 fScaleX = GrIntToScalar(textureDesc.fContentWidth) /
55 textureDesc.fAllocWidth;
56 fScaleY = GrIntToScalar(textureDesc.fContentHeight) /
57 textureDesc.fAllocHeight;
reed@google.comac10a2d2010-12-22 21:39:39 +000058
59 GrAssert(0 != textureDesc.fTextureID);
60
61 if (rtIDs.fTexFBOID) {
bsalomon@google.com8895a7a2011-02-18 16:09:55 +000062 // we render to the top left
63 GrGLIRect vp;
reed@google.comac10a2d2010-12-22 21:39:39 +000064 vp.fLeft = 0;
bsalomon@google.com8895a7a2011-02-18 16:09:55 +000065 vp.fWidth = textureDesc.fContentWidth;
66 vp.fHeight = textureDesc.fContentHeight;
67 vp.fBottom = textureDesc.fAllocHeight - textureDesc.fContentHeight;
68
bsalomon@google.com8fe72472011-03-30 21:26:44 +000069 fRenderTarget = new GrGLRenderTarget(gpu, rtIDs, fTexIDObj,
bsalomon@google.comcee661a2011-07-26 12:32:36 +000070 textureDesc.fFormat,
bsalomon@google.com1da07462011-03-10 14:51:57 +000071 textureDesc.fStencilBits,
bsalomon@google.comf954d8d2011-04-06 17:50:02 +000072 rtIDs.fRTFBOID != rtIDs.fTexFBOID,
bsalomon@google.com8fe72472011-03-30 21:26:44 +000073 vp, this);
reed@google.comac10a2d2010-12-22 21:39:39 +000074 }
reed@google.comac10a2d2010-12-22 21:39:39 +000075}
76
bsalomon@google.com8fe72472011-03-30 21:26:44 +000077void GrGLTexture::onRelease() {
bsalomon@google.com6dcf4992011-04-05 21:16:14 +000078 INHERITED::onRelease();
Scroggoc29d7cd2011-06-16 13:14:21 +000079 GPUGL->notifyTextureDelete(this);
bsalomon@google.com8fe72472011-03-30 21:26:44 +000080 if (NULL != fTexIDObj) {
bsalomon@google.com8fe72472011-03-30 21:26:44 +000081 fTexIDObj->unref();
82 fTexIDObj = NULL;
bsalomon@google.com8fe72472011-03-30 21:26:44 +000083 }
reed@google.comac10a2d2010-12-22 21:39:39 +000084}
85
bsalomon@google.com8fe72472011-03-30 21:26:44 +000086void GrGLTexture::onAbandon() {
bsalomon@google.com6dcf4992011-04-05 21:16:14 +000087 INHERITED::onAbandon();
bsalomon@google.com8fe72472011-03-30 21:26:44 +000088 if (NULL != fTexIDObj) {
89 fTexIDObj->abandon();
90 }
reed@google.comac10a2d2010-12-22 21:39:39 +000091}
92
bsalomon@google.com79d2dbe2011-06-13 19:28:02 +000093void GrGLTexture::uploadTextureData(int x,
94 int y,
95 int width,
96 int height,
junov@google.com4ee7ae52011-06-30 17:30:49 +000097 const void* srcData,
98 size_t rowBytes) {
bsalomon@google.com8fe72472011-03-30 21:26:44 +000099
100 GPUGL->setSpareTextureUnit();
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000101
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000102 // ES2 glCompressedTexSubImage2D doesn't support any formats
reed@google.comac10a2d2010-12-22 21:39:39 +0000103 // (at least without extensions)
bsalomon@google.comc312bf92011-03-21 21:10:33 +0000104 GrAssert(fUploadFormat != GR_GL_PALETTE8_RGBA8);
reed@google.comac10a2d2010-12-22 21:39:39 +0000105
junov@google.com4ee7ae52011-06-30 17:30:49 +0000106 // in case we need a temporary, trimmed copy of the src pixels
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000107 SkAutoSMalloc<128 * 128> tempStorage;
junov@google.com4ee7ae52011-06-30 17:30:49 +0000108
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000109 if (!rowBytes) {
110 rowBytes = fUploadByteCount * width;
111 }
junov@google.com4ee7ae52011-06-30 17:30:49 +0000112 /*
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000113 * check whether to allocate a temporary buffer for flipping y or
114 * because our srcData has extra bytes past each row. If so, we need
115 * to trim those off here, since GL ES doesn't let us specify
116 * GL_UNPACK_ROW_LENGTH.
junov@google.com4ee7ae52011-06-30 17:30:49 +0000117 */
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000118 bool restoreGLRowLength = false;
119 bool flipY = kBottomUp_Orientation == fOrientation;
120 if (GR_GL_SUPPORT_DESKTOP && !flipY) {
121 // can't use this for flipping, only non-neg values allowed. :(
junov@google.com4ee7ae52011-06-30 17:30:49 +0000122 if (srcData && rowBytes) {
123 GR_GL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH,
124 rowBytes / fUploadByteCount));
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000125 restoreGLRowLength = true;
junov@google.com4ee7ae52011-06-30 17:30:49 +0000126 }
127 } else {
128 size_t trimRowBytes = width * fUploadByteCount;
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000129 if (srcData && (trimRowBytes < rowBytes || flipY)) {
junov@google.com4ee7ae52011-06-30 17:30:49 +0000130 // copy the data into our new storage, skipping the trailing bytes
131 size_t trimSize = height * trimRowBytes;
132 const char* src = (const char*)srcData;
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000133 if (flipY) {
134 src += (height - 1) * rowBytes;
135 }
136 char* dst = (char*)tempStorage.realloc(trimSize);
junov@google.com4ee7ae52011-06-30 17:30:49 +0000137 for (int y = 0; y < height; y++) {
138 memcpy(dst, src, trimRowBytes);
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000139 if (flipY) {
140 src -= rowBytes;
141 } else {
142 src += rowBytes;
143 }
junov@google.com4ee7ae52011-06-30 17:30:49 +0000144 dst += trimRowBytes;
145 }
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000146 // now point srcData to our copied version
147 srcData = tempStorage.get();
junov@google.com4ee7ae52011-06-30 17:30:49 +0000148 }
149 }
150
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000151 if (flipY) {
152 y = this->height() - (y + height);
153 }
twiz@google.com0f31ca72011-03-18 17:38:11 +0000154 GR_GL(BindTexture(GR_GL_TEXTURE_2D, fTexIDObj->id()));
155 GR_GL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, fUploadByteCount));
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000156 GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, x, y, width, height,
reed@google.comac10a2d2010-12-22 21:39:39 +0000157 fUploadFormat, fUploadType, srcData));
158
junov@google.com4ee7ae52011-06-30 17:30:49 +0000159 if (GR_GL_SUPPORT_DESKTOP) {
bsalomon@google.comd9f826c2011-07-18 15:25:04 +0000160 if (restoreGLRowLength) {
junov@google.com4ee7ae52011-06-30 17:30:49 +0000161 GR_GL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
162 }
163 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000164}
165
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000166intptr_t GrGLTexture::getTextureHandle() const {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000167 return fTexIDObj->id();
reed@google.comac10a2d2010-12-22 21:39:39 +0000168}
169