From 92fc062ca0b2e94bc3639c3def0cd2aaadd9f38c Mon Sep 17 00:00:00 2001 From: seven332 Date: Sat, 5 Mar 2016 16:34:59 +0800 Subject: [PATCH] Call glTexSubImage2D in native code for ImageTexture.Tile --- .../java/com/hippo/drawable/ImageWrapper.java | 6 +- .../com/hippo/gl/glrenderer/ImageTexture.java | 60 ++--------- .../hippo/gl/glrenderer/NativeTexture.java | 101 ++++++++++++++++++ app/src/main/java/com/hippo/image/Image.java | 14 ++- app/src/main/jni/image/Android.mk | 2 +- app/src/main/jni/image/image.c | 13 ++- app/src/main/jni/image/image.h | 2 +- app/src/main/jni/image/image_gif.c | 4 +- app/src/main/jni/image/image_gif.h | 2 +- app/src/main/jni/image/image_jpeg.c | 4 +- app/src/main/jni/image/image_jpeg.h | 2 +- app/src/main/jni/image/image_png.c | 4 +- app/src/main/jni/image/image_png.h | 2 +- app/src/main/jni/image/image_utils.c | 80 +++++++++++--- app/src/main/jni/image/image_utils.h | 2 +- app/src/main/jni/image/java_wrapper.c | 59 ++++++++-- app/src/main/jni/image/java_wrapper.h | 10 ++ 17 files changed, 268 insertions(+), 99 deletions(-) create mode 100644 app/src/main/java/com/hippo/gl/glrenderer/NativeTexture.java diff --git a/app/src/main/java/com/hippo/drawable/ImageWrapper.java b/app/src/main/java/com/hippo/drawable/ImageWrapper.java index 63d276b71..b631a5916 100644 --- a/app/src/main/java/com/hippo/drawable/ImageWrapper.java +++ b/app/src/main/java/com/hippo/drawable/ImageWrapper.java @@ -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); } diff --git a/app/src/main/java/com/hippo/gl/glrenderer/ImageTexture.java b/app/src/main/java/com/hippo/gl/glrenderer/ImageTexture.java index 85f46bb3f..7e31f5055 100644 --- a/app/src/main/java/com/hippo/gl/glrenderer/ImageTexture.java +++ b/app/src/main/java/com/hippo/gl/glrenderer/ImageTexture.java @@ -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 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; } } } diff --git a/app/src/main/java/com/hippo/gl/glrenderer/NativeTexture.java b/app/src/main/java/com/hippo/gl/glrenderer/NativeTexture.java new file mode 100644 index 000000000..17d170cb0 --- /dev/null +++ b/app/src/main/java/com/hippo/gl/glrenderer/NativeTexture.java @@ -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; + } +} diff --git a/app/src/main/java/com/hippo/image/Image.java b/app/src/main/java/com/hippo/image/Image.java index 24190adc7..7e047a5c8 100644 --- a/app/src/main/java/com/hippo/image/Image.java +++ b/app/src/main/java/com/hippo/image/Image.java @@ -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); diff --git a/app/src/main/jni/image/Android.mk b/app/src/main/jni/image/Android.mk index e19763ac8..d0efbbec3 100644 --- a/app/src/main/jni/image/Android.mk +++ b/app/src/main/jni/image/Android.mk @@ -25,7 +25,7 @@ image_png.c \ image_gif.c \ image_utils.c \ java_wrapper.c -LOCAL_LDLIBS := -llog -ljnigraphics +LOCAL_LDLIBS := -llog -ljnigraphics -lGLESv2 LOCAL_STATIC_LIBRARIES := jpeg-turbo png gif stream include $(BUILD_SHARED_LIBRARY) diff --git a/app/src/main/jni/image/image.c b/app/src/main/jni/image/image.c index eb2f33ce0..47387f967 100644 --- a/app/src/main/jni/image/image.c +++ b/app/src/main/jni/image/image.c @@ -195,32 +195,35 @@ int get_height(void* image, int format) } } -bool render(void* image, int format, int src_x, int src_y, +void render(void* image, int format, int src_x, int src_y, void* dst, int dst_w, int dst_h, int dst_x, int dst_y, int width, int height, bool fill_blank, int default_color) { switch (format) { #ifdef IMAGE_SUPPORT_JPEG case IMAGE_FORMAT_JPEG: - return JPEG_render((JPEG*) image, src_x, src_y, + JPEG_render((JPEG*) image, src_x, src_y, dst, dst_w, dst_h, dst_x, dst_y, width, height, fill_blank, default_color); + break; #endif #ifdef IMAGE_SUPPORT_PNG case IMAGE_FORMAT_PNG: - return PNG_render((PNG*) image, src_x, src_y, + PNG_render((PNG*) image, src_x, src_y, dst, dst_w, dst_h, dst_x, dst_y, width, height, fill_blank, default_color); + break; #endif #ifdef IMAGE_SUPPORT_GIF case IMAGE_FORMAT_GIF: - return GIF_render((GIF*) image, src_x, src_y, + GIF_render((GIF*) image, src_x, src_y, dst, dst_w, dst_h, dst_x, dst_y, width, height, fill_blank, default_color); + break; #endif default: LOGE(EMSG("Can't detect format %d"), format); - return false; + break; } } diff --git a/app/src/main/jni/image/image.h b/app/src/main/jni/image/image.h index e98e3da75..4c6e49b35 100644 --- a/app/src/main/jni/image/image.h +++ b/app/src/main/jni/image/image.h @@ -42,7 +42,7 @@ bool complete(void* image, int format); bool is_completed(void* image, int format); int get_width(void* image, int format); int get_height(void* image, int format); -bool render(void* image, int format, int src_x, int src_y, +void render(void* image, int format, int src_x, int src_y, void* dst, int dst_w, int dst_h, int dst_x, int dst_y, int width, int height, bool fill_blank, int default_color); void advance(void* image, int format); diff --git a/app/src/main/jni/image/image_gif.c b/app/src/main/jni/image/image_gif.c index c32ac12b6..60f057d9c 100644 --- a/app/src/main/jni/image/image_gif.c +++ b/app/src/main/jni/image/image_gif.c @@ -289,11 +289,11 @@ int GIF_get_height(GIF* gif) return gif->gif_file->SHeight; } -bool GIF_render(GIF* gif, int src_x, int src_y, +void GIF_render(GIF* gif, int src_x, int src_y, void* dst, int dst_w, int dst_h, int dst_x, int dst_y, int width, int height, bool fill_blank, int default_color) { - return copy_pixels(gif->buffer, gif->gif_file->SWidth, gif->gif_file->SHeight, src_x, src_y, + copy_pixels(gif->buffer, gif->gif_file->SWidth, gif->gif_file->SHeight, src_x, src_y, dst, dst_w, dst_h, dst_x, dst_y, width, height, fill_blank, default_color); } diff --git a/app/src/main/jni/image/image_gif.h b/app/src/main/jni/image/image_gif.h index 3cb621087..5e0910756 100644 --- a/app/src/main/jni/image/image_gif.h +++ b/app/src/main/jni/image/image_gif.h @@ -61,7 +61,7 @@ bool GIF_complete(GIF* gif); bool GIF_is_completed(GIF* gif); int GIF_get_width(GIF* gif); int GIF_get_height(GIF* gif); -bool GIF_render(GIF* gif, int src_x, int src_y, +void GIF_render(GIF* gif, int src_x, int src_y, void* dst, int dst_w, int dst_h, int dst_x, int dst_y, int width, int height, bool fill_blank, int default_color); void GIF_advance(GIF* gif); diff --git a/app/src/main/jni/image/image_jpeg.c b/app/src/main/jni/image/image_jpeg.c index 2d1655aac..2aa8d0062 100644 --- a/app/src/main/jni/image/image_jpeg.c +++ b/app/src/main/jni/image/image_jpeg.c @@ -153,11 +153,11 @@ int JPEG_get_height(JPEG* jpeg) return jpeg->height; } -bool JPEG_render(JPEG* jpeg, int src_x, int src_y, +void JPEG_render(JPEG* jpeg, int src_x, int src_y, void* dst, int dst_w, int dst_h, int dst_x, int dst_y, int width, int height, bool fill_blank, int default_color) { - return copy_pixels(jpeg->buffer, jpeg->width, jpeg->height, src_x, src_y, + copy_pixels(jpeg->buffer, jpeg->width, jpeg->height, src_x, src_y, dst, dst_w, dst_h, dst_x, dst_y, width, height, fill_blank, default_color); } diff --git a/app/src/main/jni/image/image_jpeg.h b/app/src/main/jni/image/image_jpeg.h index 197cbb151..68b82c2dc 100644 --- a/app/src/main/jni/image/image_jpeg.h +++ b/app/src/main/jni/image/image_jpeg.h @@ -43,7 +43,7 @@ bool JPEG_complete(JPEG* jpeg); bool JPEG_is_completed(JPEG* jpeg); int JPEG_get_width(JPEG* jpeg); int JPEG_get_height(JPEG* jpeg); -bool JPEG_render(JPEG* jpeg, int src_x, int src_y, +void JPEG_render(JPEG* jpeg, int src_x, int src_y, void* dst, int dst_w, int dst_h, int dst_x, int dst_y, int width, int height, bool fill_blank, int default_color); void JPEG_advance(JPEG* jpeg); diff --git a/app/src/main/jni/image/image_png.c b/app/src/main/jni/image/image_png.c index b36e88ed1..e2c0d9da1 100644 --- a/app/src/main/jni/image/image_png.c +++ b/app/src/main/jni/image/image_png.c @@ -410,11 +410,11 @@ int PNG_get_height(PNG* png) return png->height; } -bool PNG_render(PNG* png, int src_x, int src_y, +void PNG_render(PNG* png, int src_x, int src_y, void* dst, int dst_w, int dst_h, int dst_x, int dst_y, int width, int height, bool fill_blank, int default_color) { - return copy_pixels(png->buffer, png->width, png->height, src_x, src_y, + copy_pixels(png->buffer, png->width, png->height, src_x, src_y, dst, dst_w, dst_h, dst_x, dst_y, width, height, fill_blank, default_color); } diff --git a/app/src/main/jni/image/image_png.h b/app/src/main/jni/image/image_png.h index da42b006b..889d9779e 100644 --- a/app/src/main/jni/image/image_png.h +++ b/app/src/main/jni/image/image_png.h @@ -71,7 +71,7 @@ bool PNG_complete(PNG* png); bool PNG_is_completed(PNG* png); int PNG_get_width(PNG* png); int PNG_get_height(PNG* png); -bool PNG_render(PNG* png, int src_x, int src_y, +void PNG_render(PNG* png, int src_x, int src_y, void* dst, int dst_w, int dst_h, int dst_x, int dst_y, int width, int height, bool fill_blank, int default_color); void PNG_advance(PNG* png); diff --git a/app/src/main/jni/image/image_utils.c b/app/src/main/jni/image/image_utils.c index 1af9da9d5..37e477c23 100644 --- a/app/src/main/jni/image/image_utils.c +++ b/app/src/main/jni/image/image_utils.c @@ -68,30 +68,66 @@ static void memset_int(int* dst, int val, size_t size) { *ptr++ = val; } -bool copy_pixels(const void* src, int src_w, int src_h, int src_x, int src_y, +bool copy_pixels_internal(const void* src, int src_w, int src_h, int src_x, int src_y, void* dst, int dst_w, int dst_h, int dst_x, int dst_y, - int width, int height, bool fill_blank, int default_color) + int width, int height, bool fill_blank, int color) { + int left; int line; size_t line_stride; int src_stride; int src_pos; int dst_pos; size_t dst_blank_length; - int color = 0; - // Check valid first - if (src_w < 0 || src_h < 0 || src_x < 0 || src_y < 0 || - dst_w < 0 || dst_h < 0 || dst_x < 0 || dst_y < 0 || - width < 0 || height < 0 || - src_x + width > src_w || src_y + height > src_h || - dst_x + width > dst_w || dst_y + height > dst_h) { + // Sanitize + if (src_x < 0) { + width -= src_x; + dst_x -= src_x; + src_x = 0; + } + if (dst_x < 0) { + width -= dst_x; + src_x -= dst_x; + dst_x = 0; + } + if (width <= 0) { return false; } - - if (width == 0 || height == 0) { - // No need to copy pixels - return true; + if (src_y < 0) { + height -= src_y; + dst_y -= src_y; + src_y = 0; + } + if (dst_y < 0) { + height -= dst_y; + src_y -= dst_y; + dst_y = 0; + } + if (height <= 0) { + return false; + } + left = src_x + width - src_w; + if (left > 0) { + width -= left; + } + left = dst_x + width - dst_w; + if (left > 0) { + width -= left; + } + if (width <= 0) { + return false; + } + left = src_y + height - src_h; + if (left > 0) { + height -= left; + } + left = dst_y + height - dst_h; + if (left > 0) { + height -= left; + } + if (height <= 0) { + return false; } // Init @@ -99,9 +135,6 @@ bool copy_pixels(const void* src, int src_w, int src_h, int src_x, int src_y, src_stride = src_w * 4; src_pos = src_y * src_stride + src_x * 4; dst_pos = 0; - if (fill_blank) { - color = convert_color(default_color); - } dst_blank_length = (size_t) (dst_y * dst_w + dst_x) * 4; // Fill start blank if necessary @@ -134,3 +167,18 @@ bool copy_pixels(const void* src, int src_w, int src_h, int src_x, int src_y, return true; } + +void copy_pixels(const void* src, int src_w, int src_h, int src_x, int src_y, + void* dst, int dst_w, int dst_h, int dst_x, int dst_y, + int width, int height, bool fill_blank, int default_color) +{ + int color = 0; + if (fill_blank) { + color = convert_color(default_color); + } + + if (!copy_pixels_internal(src, src_w, src_h, src_x, src_y, dst, dst_w, dst_h, dst_x, + dst_y, width, height, fill_blank, color) && fill_blank) { + memset_int(dst, color, (size_t) (dst_w * dst_h)); + } +} diff --git a/app/src/main/jni/image/image_utils.h b/app/src/main/jni/image/image_utils.h index 4ef9b83e2..455ecd51f 100644 --- a/app/src/main/jni/image/image_utils.h +++ b/app/src/main/jni/image/image_utils.h @@ -7,7 +7,7 @@ #include -bool copy_pixels(const void* src, int src_w, int src_h, int src_x, int src_y, +void copy_pixels(const void* src, int src_w, int src_h, int src_x, int src_y, void* dst, int dst_w, int dst_h, int dst_x, int dst_y, int width, int height, bool fill_blank, int default_color); diff --git a/app/src/main/jni/image/java_wrapper.c b/app/src/main/jni/image/java_wrapper.c index e4cd62d12..6831804a1 100644 --- a/app/src/main/jni/image/java_wrapper.c +++ b/app/src/main/jni/image/java_wrapper.c @@ -20,6 +20,7 @@ #include #include +#include #include "java_wrapper.h" #include "input_stream.h" @@ -28,6 +29,8 @@ static JavaVM* jvm; +static void* tile_buffer; + JNIEnv *get_env() { JNIEnv *env; @@ -98,7 +101,7 @@ Java_com_hippo_image_Image_nativeIsCompleted(JNIEnv* env, return (jboolean) is_completed((void*) (intptr_t) ptr, format); } -JNIEXPORT jboolean JNICALL +JNIEXPORT void JNICALL Java_com_hippo_image_Image_nativeRender(JNIEnv* env, jclass clazz, jlong ptr, jint format, jint src_x, jint src_y, jobject dst, jint dst_x, jint dst_y, @@ -106,22 +109,60 @@ Java_com_hippo_image_Image_nativeRender(JNIEnv* env, { AndroidBitmapInfo info; void *pixels = NULL; - bool result; AndroidBitmap_getInfo(env, dst, &info); AndroidBitmap_lockPixels(env, dst, &pixels); if (pixels == NULL) { LOGE(EMSG("Can't lock bitmap pixels")); - return JNI_FALSE; + return; } - result = render((void*) (intptr_t) ptr, format, src_x, src_y, + render((void*) (intptr_t) ptr, format, src_x, src_y, pixels, info.width, info.height, dst_x, dst_y, width, height, fill_blank, default_color); AndroidBitmap_unlockPixels(env, dst); - return (jboolean) result; + return; +} + +JNIEXPORT void JNICALL +Java_com_hippo_image_Image_nativeTexImage(JNIEnv* env, + jclass clazz, jlong ptr, jint format, jboolean init, jint tile_type, + jint offset_x, jint offset_y) +{ + // Check tile_buffer NULL + if (NULL == tile_buffer) { + return; + } + + // Get border size and tile size + int border_size; + int tile_size; + switch (tile_type) { + case IMAGE_TILE_TYPE_SMALL: + border_size = IMAGE_SMALL_TILE_BORDER_SIZE; + tile_size = IMAGE_SMALL_TILE_SIZE; + break; + case IMAGE_TILE_TYPE_LARGE: + border_size = IMAGE_LARGE_TILE_BORDER_SIZE; + tile_size = IMAGE_LARGE_TILE_SIZE; + break; + default: + return; + } + + render((void*) (intptr_t) ptr, format, + offset_x - border_size, offset_y - border_size, + tile_buffer, tile_size, tile_size, 0, 0, + tile_size, tile_size, true, 0); + if (init) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tile_size, tile_size, + 0, GL_RGBA, GL_UNSIGNED_BYTE, tile_buffer); + } else { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tile_size, tile_size, + GL_RGBA, GL_UNSIGNED_BYTE, tile_buffer); + } } JNIEXPORT void JNICALL @@ -162,12 +203,18 @@ Java_com_hippo_image_Image_nativeRecycle(JNIEnv* env, jint JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEnv* env; - if ((*vm)->GetEnv(vm, (void**) (&env), JNI_VERSION_1_6) != JNI_OK) + if ((*vm)->GetEnv(vm, (void**) (&env), JNI_VERSION_1_6) != JNI_OK) { return -1; + } jvm = vm; + + tile_buffer = malloc(IMAGE_LARGE_TILE_SIZE * IMAGE_LARGE_TILE_SIZE * 4); + return JNI_VERSION_1_6; } void JNI_OnUnload(JavaVM *vm, void *reserved) { + free(tile_buffer); + tile_buffer = NULL; } diff --git a/app/src/main/jni/image/java_wrapper.h b/app/src/main/jni/image/java_wrapper.h index 3696292ef..a9baa7777 100644 --- a/app/src/main/jni/image/java_wrapper.h +++ b/app/src/main/jni/image/java_wrapper.h @@ -7,6 +7,16 @@ #include +#define IMAGE_TILE_TYPE_SMALL 0x00 +#define IMAGE_SMALL_TILE_CONTENT_SIZE 254 +#define IMAGE_SMALL_TILE_BORDER_SIZE 1 +#define IMAGE_SMALL_TILE_SIZE 256 + +#define IMAGE_TILE_TYPE_LARGE 0x01 +#define IMAGE_LARGE_TILE_CONTENT_SIZE 508 +#define IMAGE_LARGE_TILE_BORDER_SIZE 2 +#define IMAGE_LARGE_TILE_SIZE 512 + JNIEnv *get_env(); #endif // IMAGE_JAVA_WRAPPER_H