1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/* 2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project 3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License"); 5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License. 6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at 7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * http://www.apache.org/licenses/LICENSE-2.0 9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software 11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS, 12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and 14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License. 15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 17a4eae1abb4f2547dfbda84301ee764ce35464881John Reckpackage com.android.gallery3d.glrenderer; 18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 19f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.Bitmap; 20f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.Bitmap.Config; 21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.opengl.GLUtils; 22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 23a4eae1abb4f2547dfbda84301ee764ce35464881John Reckimport junit.framework.Assert; 242b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Lin 25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.HashMap; 262b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Lin 27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport javax.microedition.khronos.opengles.GL11; 28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 29f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// UploadedTextures use a Bitmap for the content of the texture. 30f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// 31f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// Subclasses should implement onGetBitmap() to provide the Bitmap and 32f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// implement onFreeBitmap(mBitmap) which will be called when the Bitmap 33f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// is not needed anymore. 34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// 35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// isContentValid() is meaningful only when the isLoaded() returns true. 36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// It means whether the content needs to be updated. 37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// 38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// The user of this class should call recycle() when the texture is not 39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// needed anymore. 40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// 41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// By default an UploadedTexture is opaque (so it can be drawn faster without 42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// blending). The user or subclass can override it using setOpaque(). 43a4eae1abb4f2547dfbda84301ee764ce35464881John Reckpublic abstract class UploadedTexture extends BasicTexture { 44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // To prevent keeping allocation the borders, we store those used borders here. 46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Since the length will be power of two, it won't use too much memory. 47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static HashMap<BorderKey, Bitmap> sBorderLines = 48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin new HashMap<BorderKey, Bitmap>(); 49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static BorderKey sBorderKey = new BorderKey(); 50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @SuppressWarnings("unused") 52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final String TAG = "Texture"; 53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private boolean mContentValid = true; 5437c605949219b8bf54c165c34d6405f5f2989f50Owen Lin 5537c605949219b8bf54c165c34d6405f5f2989f50Owen Lin // indicate this textures is being uploaded in background 5637c605949219b8bf54c165c34d6405f5f2989f50Owen Lin private boolean mIsUploading = false; 57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private boolean mOpaque = true; 58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private boolean mThrottled = false; 59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static int sUploadedCount; 60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int UPLOAD_LIMIT = 100; 61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin protected Bitmap mBitmap; 631a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang private int mBorder; 64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin protected UploadedTexture() { 661a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang this(false); 671a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang } 681a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang 691a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang protected UploadedTexture(boolean hasBorder) { 70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin super(null, 0, STATE_UNLOADED); 711a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang if (hasBorder) { 721a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang setBorder(true); 731a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang mBorder = 1; 741a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang } 75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 7737c605949219b8bf54c165c34d6405f5f2989f50Owen Lin protected void setIsUploading(boolean uploading) { 7837c605949219b8bf54c165c34d6405f5f2989f50Owen Lin mIsUploading = uploading; 7937c605949219b8bf54c165c34d6405f5f2989f50Owen Lin } 8037c605949219b8bf54c165c34d6405f5f2989f50Owen Lin 8137c605949219b8bf54c165c34d6405f5f2989f50Owen Lin public boolean isUploading() { 8237c605949219b8bf54c165c34d6405f5f2989f50Owen Lin return mIsUploading; 8337c605949219b8bf54c165c34d6405f5f2989f50Owen Lin } 8437c605949219b8bf54c165c34d6405f5f2989f50Owen Lin 85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static class BorderKey implements Cloneable { 86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public boolean vertical; 87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public Config config; 88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int length; 89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int hashCode() { 92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int x = config.hashCode() ^ length; 93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return vertical ? x : -x; 94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public boolean equals(Object object) { 98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (!(object instanceof BorderKey)) return false; 99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin BorderKey o = (BorderKey) object; 100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return vertical == o.vertical 101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin && config == o.config && length == o.length; 102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public BorderKey clone() { 106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return (BorderKey) super.clone(); 108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } catch (CloneNotSupportedException e) { 109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin throw new AssertionError(e); 110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin protected void setThrottled(boolean throttled) { 115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mThrottled = throttled; 116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static Bitmap getBorderLine( 119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin boolean vertical, Config config, int length) { 120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin BorderKey key = sBorderKey; 121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin key.vertical = vertical; 122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin key.config = config; 123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin key.length = length; 124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Bitmap bitmap = sBorderLines.get(key); 125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (bitmap == null) { 126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin bitmap = vertical 127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ? Bitmap.createBitmap(1, length, config) 128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin : Bitmap.createBitmap(length, 1, config); 129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin sBorderLines.put(key.clone(), bitmap); 130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return bitmap; 132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private Bitmap getBitmap() { 135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mBitmap == null) { 136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mBitmap = onGetBitmap(); 1371a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang int w = mBitmap.getWidth() + mBorder * 2; 1381a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang int h = mBitmap.getHeight() + mBorder * 2; 139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mWidth == UNSPECIFIED) { 1401a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang setSize(w, h); 141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mBitmap; 144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void freeBitmap() { 147a4eae1abb4f2547dfbda84301ee764ce35464881John Reck Assert.assertTrue(mBitmap != null); 148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin onFreeBitmap(mBitmap); 149f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mBitmap = null; 150f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 151f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 152f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int getWidth() { 154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mWidth == UNSPECIFIED) getBitmap(); 155f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mWidth; 156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int getHeight() { 160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mWidth == UNSPECIFIED) getBitmap(); 161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mHeight; 162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin protected abstract Bitmap onGetBitmap(); 165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin protected abstract void onFreeBitmap(Bitmap bitmap); 167f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 168f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin protected void invalidateContent() { 169f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mBitmap != null) freeBitmap(); 170f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentValid = false; 171cb4fb7c19f20405fb5e08513e6297dffce824118Chih-Chung Chang mWidth = UNSPECIFIED; 172cb4fb7c19f20405fb5e08513e6297dffce824118Chih-Chung Chang mHeight = UNSPECIFIED; 173f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin /** 176f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Whether the content on GPU is valid. 177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 17837c605949219b8bf54c165c34d6405f5f2989f50Owen Lin public boolean isContentValid() { 17937c605949219b8bf54c165c34d6405f5f2989f50Owen Lin return isLoaded() && mContentValid; 180f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 181f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 182f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin /** 183f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Updates the content on GPU's memory. 184f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * @param canvas 185f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 186f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void updateContent(GLCanvas canvas) { 18737c605949219b8bf54c165c34d6405f5f2989f50Owen Lin if (!isLoaded()) { 188f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mThrottled && ++sUploadedCount > UPLOAD_LIMIT) { 189f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return; 190f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 191f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin uploadToCanvas(canvas); 192f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else if (!mContentValid) { 193f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Bitmap bitmap = getBitmap(); 194f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int format = GLUtils.getInternalFormat(bitmap); 195f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int type = GLUtils.getType(bitmap); 1967da54d7e41e04ea5122009b40de19be0724e1ca4George Mount canvas.texSubImage2D(this, mBorder, mBorder, bitmap, format, type); 197f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin freeBitmap(); 198f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentValid = true; 199f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 200f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 201f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 202f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public static void resetUploadLimit() { 203f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin sUploadedCount = 0; 204f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 205f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 206f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public static boolean uploadLimitReached() { 207f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return sUploadedCount > UPLOAD_LIMIT; 208f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 209f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 210f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void uploadToCanvas(GLCanvas canvas) { 211f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 212f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Bitmap bitmap = getBitmap(); 213f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (bitmap != null) { 214f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 2151a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang int bWidth = bitmap.getWidth(); 2161a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang int bHeight = bitmap.getHeight(); 2171a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang int width = bWidth + mBorder * 2; 2181a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang int height = bHeight + mBorder * 2; 2191a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang int texWidth = getTextureWidth(); 2201a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang int texHeight = getTextureHeight(); 221c2c0b01fbbf243eee1a11c33ba6dd1ce918a9ce5Owen Lin 222a4eae1abb4f2547dfbda84301ee764ce35464881John Reck Assert.assertTrue(bWidth <= texWidth && bHeight <= texHeight); 223c2c0b01fbbf243eee1a11c33ba6dd1ce918a9ce5Owen Lin 224f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Upload the bitmap to a new texture. 22550b33abe053ccab7be3d1bca2328e792507963d4George Mount mId = canvas.getGLId().generateTexture(); 2267da54d7e41e04ea5122009b40de19be0724e1ca4George Mount canvas.setTextureParameters(this); 227f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2281a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang if (bWidth == texWidth && bHeight == texHeight) { 2297da54d7e41e04ea5122009b40de19be0724e1ca4George Mount canvas.initializeTexture(this, bitmap); 230f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 231f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int format = GLUtils.getInternalFormat(bitmap); 232f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int type = GLUtils.getType(bitmap); 233f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Config config = bitmap.getConfig(); 234f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2357da54d7e41e04ea5122009b40de19be0724e1ca4George Mount canvas.initializeTextureSize(this, format, type); 2367da54d7e41e04ea5122009b40de19be0724e1ca4George Mount canvas.texSubImage2D(this, mBorder, mBorder, bitmap, format, type); 2371a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang 2381a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang if (mBorder > 0) { 2391a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang // Left border 2401a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang Bitmap line = getBorderLine(true, config, texHeight); 2417da54d7e41e04ea5122009b40de19be0724e1ca4George Mount canvas.texSubImage2D(this, 0, 0, line, format, type); 2421a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang 2431a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang // Top border 2441a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang line = getBorderLine(false, config, texWidth); 2457da54d7e41e04ea5122009b40de19be0724e1ca4George Mount canvas.texSubImage2D(this, 0, 0, line, format, type); 246f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 247f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2481a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang // Right border 2491a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang if (mBorder + bWidth < texWidth) { 2501a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang Bitmap line = getBorderLine(true, config, texHeight); 2517da54d7e41e04ea5122009b40de19be0724e1ca4George Mount canvas.texSubImage2D(this, mBorder + bWidth, 0, line, format, type); 252f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 253f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2541a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang // Bottom border 2551a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang if (mBorder + bHeight < texHeight) { 2561a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang Bitmap line = getBorderLine(false, config, texWidth); 2577da54d7e41e04ea5122009b40de19be0724e1ca4George Mount canvas.texSubImage2D(this, 0, mBorder + bHeight, line, format, type); 2581a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang } 259f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 260f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } finally { 261f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin freeBitmap(); 262f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 263f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Update texture state. 264f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setAssociatedCanvas(canvas); 26537c605949219b8bf54c165c34d6405f5f2989f50Owen Lin mState = STATE_LOADED; 266f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentValid = true; 267f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 268f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mState = STATE_ERROR; 269f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin throw new RuntimeException("Texture load fail, no bitmap"); 270f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 271f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 272f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 273f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 274f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin protected boolean onBind(GLCanvas canvas) { 275f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin updateContent(canvas); 27637c605949219b8bf54c165c34d6405f5f2989f50Owen Lin return isContentValid(); 277f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 278f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 279b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang @Override 280b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang protected int getTarget() { 281b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang return GL11.GL_TEXTURE_2D; 282b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang } 283b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 284f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void setOpaque(boolean isOpaque) { 285f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mOpaque = isOpaque; 286f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 287f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2887817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 289f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public boolean isOpaque() { 290f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mOpaque; 291f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 292f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 293f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 294f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void recycle() { 295f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin super.recycle(); 296f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mBitmap != null) freeBitmap(); 297f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 298f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin} 299