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);
|
||||
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <android/bitmap.h>
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -7,6 +7,16 @@
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#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
|
||||
Reference in new issue
Block a user