Call glTexSubImage2D in native code for ImageTexture.Tile
This commit is contained in:
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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user