Call glTexSubImage2D in native code for ImageTexture.Tile

This commit is contained in:
seven332 committed 2016-03-05 16:34:59 +08:00
1 parent e80df262a3
commit 92fc062ca0
17 files changed
+268 -99

No files matched your search

@@ -33,7 +33,7 @@ public class ImageWrapper implements Animatable, Runnable {
private static final String TAG = ImageWrapper.class.getSimpleName();
private Image mImage;
private final Image mImage;
private boolean mRunning = false;
@@ -51,9 +51,9 @@ public class ImageWrapper implements Animatable, Runnable {
return mImage.getHeight();
}
public boolean render(int srcX, int srcY, Bitmap dst, int dstX, int dstY,
public void render(int srcX, int srcY, Bitmap dst, int dstX, int dstY,
int width, int height, boolean fillBlank, int defaultColor) {
return mImage.render(srcX, srcY, dst, dstX, dstY,
mImage.render(srcX, srcY, dst, dstX, dstY,
width, height, fillBlank, defaultColor);
}
@@ -16,8 +16,6 @@
package com.hippo.gl.glrenderer;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.RectF;
import android.graphics.drawable.Animatable;
import android.os.SystemClock;
@@ -61,8 +59,6 @@ public class ImageTexture implements Texture, Animatable {
// In this 16ms, we use about 4~8 ms to upload tiles.
private static final long UPLOAD_TILE_LIMIT = 4; // ms
private static final Bitmap sSmallUploadBitmap;
private static final Bitmap sLargeUploadBitmap;
private static final PriorityThreadFactory sThreadFactory;
private static final PVLock sPVLock;
@@ -90,8 +86,6 @@ public class ImageTexture implements Texture, Animatable {
private WeakReference<Callback> mCallback;
static {
sSmallUploadBitmap = Bitmap.createBitmap(SMALL_TILE_SIZE, SMALL_TILE_SIZE, Bitmap.Config.ARGB_8888);
sLargeUploadBitmap = Bitmap.createBitmap(LARGE_TILE_SIZE, LARGE_TILE_SIZE, Bitmap.Config.ARGB_8888);
sThreadFactory = new PriorityThreadFactory("ImageTexture$AnimateTask", android.os.Process.THREAD_PRIORITY_BACKGROUND);
sPVLock = new PVLock(3);
}
@@ -142,7 +136,7 @@ public class ImageTexture implements Texture, Animatable {
}
}
private static class Tile extends UploadedTexture {
private static class Tile extends NativeTexture {
@TileType
private int mTileType;
@@ -153,76 +147,38 @@ public class ImageTexture implements Texture, Animatable {
public int contentWidth;
public int contentHeight;
public int borderSize;
public int tileSize;
public Bitmap uploadBitmap;
public void setSize(@TileType int tileType, int width, int height) {
mTileType = tileType;
int tileSize;
if (tileType == TILE_SMALL) {
borderSize = SMALL_BORDER_SIZE;
tileSize = SMALL_TILE_SIZE;
uploadBitmap = sSmallUploadBitmap;
} else if (tileType == TILE_LARGE) {
borderSize = LARGE_BORDER_SIZE;
tileSize = LARGE_TILE_SIZE;
uploadBitmap = sLargeUploadBitmap;
} else {
throw new IllegalStateException("Not support tile type: " + tileType);
}
contentWidth = width;
contentHeight = height;
mWidth = width + 2 * borderSize;
mHeight = height + 2 * borderSize;
mTextureWidth = tileSize;
mTextureHeight = tileSize;
}
@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
@Override
protected Bitmap onGetBitmap() {
final Image image = this.image;
if (image != null) {
int srcX;
int dstX;
if (offsetX - borderSize < 0) {
srcX = 0;
dstX = borderSize - offsetX;
} else {
srcX = offsetX - borderSize;
dstX = 0;
}
int srcY;
int dstY;
if (offsetY - borderSize < 0) {
srcY = 0;
dstY = borderSize - offsetY;
} else {
srcY = offsetY - borderSize;
dstY = 0;
}
image.render(srcX, srcY, uploadBitmap, dstX, dstY,
Math.min(image.getWidth() - srcX, tileSize - dstX),
Math.min(image.getHeight() - srcY, tileSize - dstY),
true, Color.TRANSPARENT);
protected void texImage(boolean init) {
if (image != null && !image.isRecycled()) {
image.texImage(init, mTileType, offsetX, offsetY);
}
return uploadBitmap;
}
@Override
protected void onFreeBitmap(Bitmap bitmap) {
// Nothing
}
@Override
public boolean isOpaque() {
return false;
}
private void invalidate() {
invalidateContent();
image = null;
uploadBitmap = null;
}
public void free() {
@@ -584,11 +540,7 @@ public class ImageTexture implements Texture, Animatable {
if (mFrameDirty.getAndSet(false)) {
// invalid tiles
for (Tile tile : mTiles) {
int width = tile.mWidth;
int height = tile.mHeight;
tile.invalidateContent();
tile.mWidth = width;
tile.mHeight = height;
}
}
}
@@ -0,0 +1,101 @@
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.gl.glrenderer;
import android.opengl.GLES20;
import android.util.Log;
import javax.microedition.khronos.opengles.GL11;
public abstract class NativeTexture extends BasicTexture {
private static final String TAG = NativeTexture.class.getSimpleName();
private boolean mContentValid = true;
private boolean mOpaque = true;
public void invalidateContent() {
mContentValid = false;
}
public static void checkError() {
int error = GLES20.glGetError();
if (error != 0) {
Throwable t = new Throwable();
Log.e(TAG, "GL error: " + error, t);
}
}
protected abstract void texImage(boolean init);
private void uploadToCanvas(GLCanvas canvas) {
// Get id
mId = canvas.getGLId().generateTexture();
// Prepare
canvas.setTextureParameters(this);
// Call glTexImage2D
GLES20.glBindTexture(getTarget(), mId);
checkError();
texImage(true);
setAssociatedCanvas(canvas);
mState = STATE_LOADED;
mContentValid = true;
}
public void updateContent(GLCanvas canvas) {
if (!isLoaded()) {
uploadToCanvas(canvas);
} else if (!mContentValid) {
// Call glTexSubImage2D
GLES20.glBindTexture(getTarget(), mId);
checkError();
texImage(false);
mContentValid = true;
}
}
/**
* Whether the content on GPU is valid.
*/
public boolean isContentValid() {
return isLoaded() && mContentValid;
}
@Override
protected boolean onBind(GLCanvas canvas) {
updateContent(canvas);
return isContentValid();
}
@Override
protected int getTarget() {
return GL11.GL_TEXTURE_2D;
}
public void setOpaque(boolean isOpaque) {
mOpaque = isOpaque;
}
@Override
public boolean isOpaque() {
return mOpaque;
}
}
+11 -3
View File
@@ -66,13 +66,18 @@ public class Image {
return nativeIsCompleted(mNativePtr, mFormat);
}
public boolean render(int srcX, int srcY, Bitmap dst, int dstX, int dstY,
public void render(int srcX, int srcY, Bitmap dst, int dstX, int dstY,
int width, int height, boolean fillBlank, int defaultColor) {
checkRecycled();
return nativeRender(mNativePtr, mFormat, srcX, srcY, dst, dstX, dstY,
nativeRender(mNativePtr, mFormat, srcX, srcY, dst, dstX, dstY,
width, height, fillBlank, defaultColor);
}
public void texImage(boolean init, int tileType, int offsetX, int offsetY) {
checkRecycled();
nativeTexImage(mNativePtr, mFormat, init, tileType, offsetX, offsetY);
}
public void advance() {
checkRecycled();
nativeAdvance(mNativePtr, mFormat);
@@ -118,10 +123,13 @@ public class Image {
private static native boolean nativeIsCompleted(long nativePtr, int format);
private static native boolean nativeRender(long nativePtr, int format,
private static native void nativeRender(long nativePtr, int format,
int srcX, int srcY, Bitmap dst, int dstX, int dstY,
int width, int height, boolean fillBlank, int defaultColor);
private static native void nativeTexImage(long nativePtr, int format,
boolean init, int tileType, int offsetX, int offsetY);
private static native void nativeAdvance(long nativePtr, int format);
private static native int nativeGetDelay(long nativePtr, int format);