Merge "Removing unused BlockingGLTextureView" into ub-launcher3-master
This commit is contained in:
@@ -1,438 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* 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.android.photos.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.opengl.GLSurfaceView.Renderer;
|
||||
import android.opengl.GLUtils;
|
||||
import android.util.Log;
|
||||
import android.view.TextureView;
|
||||
import android.view.TextureView.SurfaceTextureListener;
|
||||
|
||||
import javax.microedition.khronos.egl.EGL10;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.egl.EGLContext;
|
||||
import javax.microedition.khronos.egl.EGLDisplay;
|
||||
import javax.microedition.khronos.egl.EGLSurface;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
/**
|
||||
* A TextureView that supports blocking rendering for synchronous drawing
|
||||
*/
|
||||
public class BlockingGLTextureView extends TextureView
|
||||
implements SurfaceTextureListener {
|
||||
|
||||
private RenderThread mRenderThread;
|
||||
|
||||
public BlockingGLTextureView(Context context) {
|
||||
super(context);
|
||||
setSurfaceTextureListener(this);
|
||||
}
|
||||
|
||||
public void setRenderer(Renderer renderer) {
|
||||
if (mRenderThread != null) {
|
||||
throw new IllegalArgumentException("Renderer already set");
|
||||
}
|
||||
mRenderThread = new RenderThread(renderer);
|
||||
}
|
||||
|
||||
public void render() {
|
||||
mRenderThread.render();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (mRenderThread != null) {
|
||||
mRenderThread.finish();
|
||||
mRenderThread = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
|
||||
int height) {
|
||||
mRenderThread.setSurface(surface);
|
||||
mRenderThread.setSize(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
|
||||
int height) {
|
||||
mRenderThread.setSize(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
|
||||
if (mRenderThread != null) {
|
||||
mRenderThread.setSurface(null);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
destroy();
|
||||
} catch (Throwable t) {
|
||||
// Ignore
|
||||
}
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
/**
|
||||
* An EGL helper class.
|
||||
*/
|
||||
|
||||
private static class EglHelper {
|
||||
private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
|
||||
private static final int EGL_OPENGL_ES2_BIT = 4;
|
||||
|
||||
EGL10 mEgl;
|
||||
EGLDisplay mEglDisplay;
|
||||
EGLSurface mEglSurface;
|
||||
EGLConfig mEglConfig;
|
||||
EGLContext mEglContext;
|
||||
|
||||
private EGLConfig chooseEglConfig() {
|
||||
int[] configsCount = new int[1];
|
||||
EGLConfig[] configs = new EGLConfig[1];
|
||||
int[] configSpec = getConfig();
|
||||
if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) {
|
||||
throw new IllegalArgumentException("eglChooseConfig failed " +
|
||||
GLUtils.getEGLErrorString(mEgl.eglGetError()));
|
||||
} else if (configsCount[0] > 0) {
|
||||
return configs[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int[] getConfig() {
|
||||
return new int[] {
|
||||
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL10.EGL_RED_SIZE, 8,
|
||||
EGL10.EGL_GREEN_SIZE, 8,
|
||||
EGL10.EGL_BLUE_SIZE, 8,
|
||||
EGL10.EGL_ALPHA_SIZE, 8,
|
||||
EGL10.EGL_DEPTH_SIZE, 0,
|
||||
EGL10.EGL_STENCIL_SIZE, 0,
|
||||
EGL10.EGL_NONE
|
||||
};
|
||||
}
|
||||
|
||||
EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
|
||||
int[] attribList = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
|
||||
return egl.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attribList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize EGL for a given configuration spec.
|
||||
*/
|
||||
public void start() {
|
||||
/*
|
||||
* Get an EGL instance
|
||||
*/
|
||||
mEgl = (EGL10) EGLContext.getEGL();
|
||||
|
||||
/*
|
||||
* Get to the default display.
|
||||
*/
|
||||
mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
|
||||
|
||||
if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
|
||||
throw new RuntimeException("eglGetDisplay failed");
|
||||
}
|
||||
|
||||
/*
|
||||
* We can now initialize EGL for that display
|
||||
*/
|
||||
int[] version = new int[2];
|
||||
if (!mEgl.eglInitialize(mEglDisplay, version)) {
|
||||
throw new RuntimeException("eglInitialize failed");
|
||||
}
|
||||
mEglConfig = chooseEglConfig();
|
||||
|
||||
/*
|
||||
* Create an EGL context. We want to do this as rarely as we can, because an
|
||||
* EGL context is a somewhat heavy object.
|
||||
*/
|
||||
mEglContext = createContext(mEgl, mEglDisplay, mEglConfig);
|
||||
|
||||
if (mEglContext == null || mEglContext == EGL10.EGL_NO_CONTEXT) {
|
||||
mEglContext = null;
|
||||
throwEglException("createContext");
|
||||
}
|
||||
|
||||
mEglSurface = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an egl surface for the current SurfaceTexture surface. If a surface
|
||||
* already exists, destroy it before creating the new surface.
|
||||
*
|
||||
* @return true if the surface was created successfully.
|
||||
*/
|
||||
public boolean createSurface(SurfaceTexture surface) {
|
||||
/*
|
||||
* Check preconditions.
|
||||
*/
|
||||
if (mEgl == null) {
|
||||
throw new RuntimeException("egl not initialized");
|
||||
}
|
||||
if (mEglDisplay == null) {
|
||||
throw new RuntimeException("eglDisplay not initialized");
|
||||
}
|
||||
if (mEglConfig == null) {
|
||||
throw new RuntimeException("mEglConfig not initialized");
|
||||
}
|
||||
|
||||
/*
|
||||
* The window size has changed, so we need to create a new
|
||||
* surface.
|
||||
*/
|
||||
destroySurfaceImp();
|
||||
|
||||
/*
|
||||
* Create an EGL surface we can render into.
|
||||
*/
|
||||
if (surface != null) {
|
||||
mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, surface, null);
|
||||
} else {
|
||||
mEglSurface = null;
|
||||
}
|
||||
|
||||
if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
|
||||
int error = mEgl.eglGetError();
|
||||
if (error == EGL10.EGL_BAD_NATIVE_WINDOW) {
|
||||
Log.e("EglHelper", "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Before we can issue GL commands, we need to make sure
|
||||
* the context is current and bound to a surface.
|
||||
*/
|
||||
if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
|
||||
/*
|
||||
* Could not make the context current, probably because the underlying
|
||||
* SurfaceView surface has been destroyed.
|
||||
*/
|
||||
logEglErrorAsWarning("EGLHelper", "eglMakeCurrent", mEgl.eglGetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a GL object for the current EGL context.
|
||||
*/
|
||||
public GL10 createGL() {
|
||||
return (GL10) mEglContext.getGL();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the current render surface.
|
||||
* @return the EGL error code from eglSwapBuffers.
|
||||
*/
|
||||
public int swap() {
|
||||
if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
|
||||
return mEgl.eglGetError();
|
||||
}
|
||||
return EGL10.EGL_SUCCESS;
|
||||
}
|
||||
|
||||
public void destroySurface() {
|
||||
destroySurfaceImp();
|
||||
}
|
||||
|
||||
private void destroySurfaceImp() {
|
||||
if (mEglSurface != null && mEglSurface != EGL10.EGL_NO_SURFACE) {
|
||||
mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
|
||||
EGL10.EGL_NO_SURFACE,
|
||||
EGL10.EGL_NO_CONTEXT);
|
||||
mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
|
||||
mEglSurface = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
if (mEglContext != null) {
|
||||
mEgl.eglDestroyContext(mEglDisplay, mEglContext);
|
||||
mEglContext = null;
|
||||
}
|
||||
if (mEglDisplay != null) {
|
||||
mEgl.eglTerminate(mEglDisplay);
|
||||
mEglDisplay = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void throwEglException(String function) {
|
||||
throwEglException(function, mEgl.eglGetError());
|
||||
}
|
||||
|
||||
public static void throwEglException(String function, int error) {
|
||||
String message = formatEglError(function, error);
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
|
||||
public static void logEglErrorAsWarning(String tag, String function, int error) {
|
||||
Log.w(tag, formatEglError(function, error));
|
||||
}
|
||||
|
||||
public static String formatEglError(String function, int error) {
|
||||
return function + " failed: " + error;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class RenderThread extends Thread {
|
||||
private static final int INVALID = -1;
|
||||
private static final int RENDER = 1;
|
||||
private static final int CHANGE_SURFACE = 2;
|
||||
private static final int RESIZE_SURFACE = 3;
|
||||
private static final int FINISH = 4;
|
||||
|
||||
private EglHelper mEglHelper = new EglHelper();
|
||||
|
||||
private Object mLock = new Object();
|
||||
private int mExecMsgId = INVALID;
|
||||
private SurfaceTexture mSurface;
|
||||
private Renderer mRenderer;
|
||||
private int mWidth, mHeight;
|
||||
|
||||
private boolean mFinished = false;
|
||||
private GL10 mGL;
|
||||
|
||||
public RenderThread(Renderer renderer) {
|
||||
super("RenderThread");
|
||||
mRenderer = renderer;
|
||||
start();
|
||||
}
|
||||
|
||||
private void checkRenderer() {
|
||||
if (mRenderer == null) {
|
||||
throw new IllegalArgumentException("Renderer is null!");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkSurface() {
|
||||
if (mSurface == null) {
|
||||
throw new IllegalArgumentException("surface is null!");
|
||||
}
|
||||
}
|
||||
|
||||
public void setSurface(SurfaceTexture surface) {
|
||||
// If the surface is null we're being torn down, don't need a
|
||||
// renderer then
|
||||
if (surface != null) {
|
||||
checkRenderer();
|
||||
}
|
||||
mSurface = surface;
|
||||
exec(CHANGE_SURFACE);
|
||||
}
|
||||
|
||||
public void setSize(int width, int height) {
|
||||
checkRenderer();
|
||||
checkSurface();
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
exec(RESIZE_SURFACE);
|
||||
}
|
||||
|
||||
public void render() {
|
||||
checkRenderer();
|
||||
if (mSurface != null) {
|
||||
exec(RENDER);
|
||||
mSurface.updateTexImage();
|
||||
}
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
mSurface = null;
|
||||
exec(FINISH);
|
||||
try {
|
||||
join();
|
||||
} catch (InterruptedException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
private void exec(int msgid) {
|
||||
synchronized (mLock) {
|
||||
if (mExecMsgId != INVALID) {
|
||||
throw new IllegalArgumentException(
|
||||
"Message already set - multithreaded access?");
|
||||
}
|
||||
mExecMsgId = msgid;
|
||||
mLock.notify();
|
||||
try {
|
||||
mLock.wait();
|
||||
} catch (InterruptedException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleMessageLocked(int what) {
|
||||
switch (what) {
|
||||
case CHANGE_SURFACE:
|
||||
if (mEglHelper.createSurface(mSurface)) {
|
||||
mGL = mEglHelper.createGL();
|
||||
mRenderer.onSurfaceCreated(mGL, mEglHelper.mEglConfig);
|
||||
}
|
||||
break;
|
||||
case RESIZE_SURFACE:
|
||||
mRenderer.onSurfaceChanged(mGL, mWidth, mHeight);
|
||||
break;
|
||||
case RENDER:
|
||||
mRenderer.onDrawFrame(mGL);
|
||||
mEglHelper.swap();
|
||||
break;
|
||||
case FINISH:
|
||||
mEglHelper.destroySurface();
|
||||
mEglHelper.finish();
|
||||
mFinished = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (mLock) {
|
||||
mEglHelper.start();
|
||||
while (!mFinished) {
|
||||
while (mExecMsgId == INVALID) {
|
||||
try {
|
||||
mLock.wait();
|
||||
} catch (InterruptedException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
handleMessageLocked(mExecMsgId);
|
||||
mExecMsgId = INVALID;
|
||||
mLock.notify();
|
||||
}
|
||||
mExecMsgId = FINISH;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package com.android.photos.views;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
@@ -28,11 +26,9 @@ import android.graphics.Paint.Align;
|
||||
import android.graphics.RectF;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.opengl.GLSurfaceView.Renderer;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Choreographer;
|
||||
import android.view.Choreographer.FrameCallback;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.android.gallery3d.glrenderer.BasicTexture;
|
||||
@@ -43,18 +39,10 @@ import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
/**
|
||||
* Shows an image using {@link TiledImageRenderer} using either {@link GLSurfaceView}
|
||||
* or {@link BlockingGLTextureView}.
|
||||
* Shows an image using {@link TiledImageRenderer} using either {@link GLSurfaceView}.
|
||||
*/
|
||||
public class TiledImageView extends FrameLayout {
|
||||
|
||||
private static final boolean USE_TEXTURE_VIEW = false;
|
||||
private static final boolean IS_SUPPORTED =
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
|
||||
private static final boolean USE_CHOREOGRAPHER =
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
|
||||
|
||||
private BlockingGLTextureView mTextureView;
|
||||
private GLSurfaceView mGLSurfaceView;
|
||||
private boolean mInvalPending = false;
|
||||
private FrameCallback mFrameCallback;
|
||||
@@ -79,35 +67,19 @@ public class TiledImageView extends FrameLayout {
|
||||
protected Object mLock = new Object();
|
||||
protected ImageRendererWrapper mRenderer;
|
||||
|
||||
public static boolean isTilingSupported() {
|
||||
return IS_SUPPORTED;
|
||||
}
|
||||
|
||||
public TiledImageView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public TiledImageView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
if (!IS_SUPPORTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
mRenderer = new ImageRendererWrapper();
|
||||
mRenderer.image = new TiledImageRenderer(this);
|
||||
View view;
|
||||
if (USE_TEXTURE_VIEW) {
|
||||
mTextureView = new BlockingGLTextureView(context);
|
||||
mTextureView.setRenderer(new TileRenderer());
|
||||
view = mTextureView;
|
||||
} else {
|
||||
mGLSurfaceView = new GLSurfaceView(context);
|
||||
mGLSurfaceView.setEGLContextClientVersion(2);
|
||||
mGLSurfaceView.setRenderer(new TileRenderer());
|
||||
mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
|
||||
view = mGLSurfaceView;
|
||||
}
|
||||
addView(view, new LayoutParams(
|
||||
mGLSurfaceView = new GLSurfaceView(context);
|
||||
mGLSurfaceView.setEGLContextClientVersion(2);
|
||||
mGLSurfaceView.setRenderer(new TileRenderer());
|
||||
mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
|
||||
addView(mGLSurfaceView, new LayoutParams(
|
||||
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
|
||||
//setTileSource(new ColoredTiles());
|
||||
}
|
||||
@@ -117,22 +89,11 @@ public class TiledImageView extends FrameLayout {
|
||||
super.setVisibility(visibility);
|
||||
// need to update inner view's visibility because it seems like we're causing it to draw
|
||||
// from {@link #dispatchDraw} or {@link #invalidate} even if we are invisible.
|
||||
if (USE_TEXTURE_VIEW) {
|
||||
mTextureView.setVisibility(visibility);
|
||||
} else {
|
||||
mGLSurfaceView.setVisibility(visibility);
|
||||
}
|
||||
mGLSurfaceView.setVisibility(visibility);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (!IS_SUPPORTED) {
|
||||
return;
|
||||
}
|
||||
if (USE_TEXTURE_VIEW) {
|
||||
mTextureView.destroy();
|
||||
} else {
|
||||
mGLSurfaceView.queueEvent(mFreeTextures);
|
||||
}
|
||||
mGLSurfaceView.queueEvent(mFreeTextures);
|
||||
}
|
||||
|
||||
private Runnable mFreeTextures = new Runnable() {
|
||||
@@ -144,27 +105,14 @@ public class TiledImageView extends FrameLayout {
|
||||
};
|
||||
|
||||
public void onPause() {
|
||||
if (!IS_SUPPORTED) {
|
||||
return;
|
||||
}
|
||||
if (!USE_TEXTURE_VIEW) {
|
||||
mGLSurfaceView.onPause();
|
||||
}
|
||||
mGLSurfaceView.onPause();
|
||||
}
|
||||
|
||||
public void onResume() {
|
||||
if (!IS_SUPPORTED) {
|
||||
return;
|
||||
}
|
||||
if (!USE_TEXTURE_VIEW) {
|
||||
mGLSurfaceView.onResume();
|
||||
}
|
||||
mGLSurfaceView.onResume();
|
||||
}
|
||||
|
||||
public void setTileSource(TileSource source, Runnable isReadyCallback) {
|
||||
if (!IS_SUPPORTED) {
|
||||
return;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
mRenderer.source = source;
|
||||
mRenderer.isReadyCallback = isReadyCallback;
|
||||
@@ -181,9 +129,6 @@ public class TiledImageView extends FrameLayout {
|
||||
protected void onLayout(boolean changed, int left, int top, int right,
|
||||
int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
if (!IS_SUPPORTED) {
|
||||
return;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
updateScaleIfNecessaryLocked(mRenderer);
|
||||
}
|
||||
@@ -199,44 +144,11 @@ public class TiledImageView extends FrameLayout {
|
||||
(float) getHeight() / (float) renderer.source.getImageHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
if (!IS_SUPPORTED) {
|
||||
return;
|
||||
}
|
||||
if (USE_TEXTURE_VIEW) {
|
||||
mTextureView.render();
|
||||
}
|
||||
super.dispatchDraw(canvas);
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
public void setTranslationX(float translationX) {
|
||||
if (!IS_SUPPORTED) {
|
||||
return;
|
||||
}
|
||||
super.setTranslationX(translationX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate() {
|
||||
if (!IS_SUPPORTED) {
|
||||
return;
|
||||
}
|
||||
if (USE_TEXTURE_VIEW) {
|
||||
super.invalidate();
|
||||
mTextureView.invalidate();
|
||||
} else {
|
||||
if (USE_CHOREOGRAPHER) {
|
||||
invalOnVsync();
|
||||
} else {
|
||||
mGLSurfaceView.requestRender();
|
||||
}
|
||||
}
|
||||
invalOnVsync();
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
|
||||
private void invalOnVsync() {
|
||||
if (!mInvalPending) {
|
||||
mInvalPending = true;
|
||||
@@ -255,9 +167,6 @@ public class TiledImageView extends FrameLayout {
|
||||
|
||||
private RectF mTempRectF = new RectF();
|
||||
public void positionFromMatrix(Matrix matrix) {
|
||||
if (!IS_SUPPORTED) {
|
||||
return;
|
||||
}
|
||||
if (mRenderer.source != null) {
|
||||
final int rotation = mRenderer.source.getRotation();
|
||||
final boolean swap = !(rotation % 180 == 0);
|
||||
|
||||
Reference in New Issue
Block a user