更新 Gallery2 部分

This commit is contained in:
seven332 committed 2014-08-23 13:39:48 +08:00
1 parent 570796a610
commit fb8bc2c364
25 files changed
+269 -386

No files matched your search

@@ -0,0 +1,176 @@
/*
* Copyright (C) 2012 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.hippo.ehviewer.gallery.anim;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import com.hippo.ehviewer.gallery.glrenderer.GLCanvas;
import com.hippo.ehviewer.gallery.glrenderer.RawTexture;
import com.hippo.ehviewer.gallery.ui.GLView;
public class StateTransitionAnimation extends Animation {
public static class Spec {
public static final Spec OUTGOING;
public static final Spec INCOMING;
public static final Spec PHOTO_INCOMING;
private static final Interpolator DEFAULT_INTERPOLATOR =
new DecelerateInterpolator();
public int duration = 330;
public float backgroundAlphaFrom = 0;
public float backgroundAlphaTo = 0;
public float backgroundScaleFrom = 0;
public float backgroundScaleTo = 0;
public float contentAlphaFrom = 1;
public float contentAlphaTo = 1;
public float contentScaleFrom = 1;
public float contentScaleTo = 1;
public float overlayAlphaFrom = 0;
public float overlayAlphaTo = 0;
public float overlayScaleFrom = 0;
public float overlayScaleTo = 0;
public Interpolator interpolator = DEFAULT_INTERPOLATOR;
static {
OUTGOING = new Spec();
OUTGOING.backgroundAlphaFrom = 0.5f;
OUTGOING.backgroundAlphaTo = 0f;
OUTGOING.backgroundScaleFrom = 1f;
OUTGOING.backgroundScaleTo = 0f;
OUTGOING.contentAlphaFrom = 0.5f;
OUTGOING.contentAlphaTo = 1f;
OUTGOING.contentScaleFrom = 3f;
OUTGOING.contentScaleTo = 1f;
INCOMING = new Spec();
INCOMING.overlayAlphaFrom = 1f;
INCOMING.overlayAlphaTo = 0f;
INCOMING.overlayScaleFrom = 1f;
INCOMING.overlayScaleTo = 3f;
INCOMING.contentAlphaFrom = 0f;
INCOMING.contentAlphaTo = 1f;
INCOMING.contentScaleFrom = 0.25f;
INCOMING.contentScaleTo = 1f;
PHOTO_INCOMING = INCOMING;
}
private static Spec specForTransition(Transition t) {
switch (t) {
case Outgoing:
return Spec.OUTGOING;
case Incoming:
return Spec.INCOMING;
case PhotoIncoming:
return Spec.PHOTO_INCOMING;
case None:
default:
return null;
}
}
}
public static enum Transition { None, Outgoing, Incoming, PhotoIncoming }
private final Spec mTransitionSpec;
private float mCurrentContentScale;
private float mCurrentContentAlpha;
private float mCurrentBackgroundScale;
private float mCurrentBackgroundAlpha;
private float mCurrentOverlayScale;
private float mCurrentOverlayAlpha;
private RawTexture mOldScreenTexture;
public StateTransitionAnimation(Transition t, RawTexture oldScreen) {
this(Spec.specForTransition(t), oldScreen);
}
public StateTransitionAnimation(Spec spec, RawTexture oldScreen) {
mTransitionSpec = spec != null ? spec : Spec.OUTGOING;
setDuration(mTransitionSpec.duration);
setInterpolator(mTransitionSpec.interpolator);
mOldScreenTexture = oldScreen;
}
@Override
public boolean calculate(long currentTimeMillis) {
boolean retval = super.calculate(currentTimeMillis);
if (!isActive()) {
if (mOldScreenTexture != null) {
mOldScreenTexture.recycle();
mOldScreenTexture = null;
}
}
return retval;
}
@Override
protected void onCalculate(float progress) {
mCurrentContentScale = mTransitionSpec.contentScaleFrom
+ (mTransitionSpec.contentScaleTo - mTransitionSpec.contentScaleFrom) * progress;
mCurrentContentAlpha = mTransitionSpec.contentAlphaFrom
+ (mTransitionSpec.contentAlphaTo - mTransitionSpec.contentAlphaFrom) * progress;
mCurrentBackgroundAlpha = mTransitionSpec.backgroundAlphaFrom
+ (mTransitionSpec.backgroundAlphaTo - mTransitionSpec.backgroundAlphaFrom)
* progress;
mCurrentBackgroundScale = mTransitionSpec.backgroundScaleFrom
+ (mTransitionSpec.backgroundScaleTo - mTransitionSpec.backgroundScaleFrom)
* progress;
mCurrentOverlayScale = mTransitionSpec.overlayScaleFrom
+ (mTransitionSpec.overlayScaleTo - mTransitionSpec.overlayScaleFrom) * progress;
mCurrentOverlayAlpha = mTransitionSpec.overlayAlphaFrom
+ (mTransitionSpec.overlayAlphaTo - mTransitionSpec.overlayAlphaFrom) * progress;
}
private void applyOldTexture(GLView view, GLCanvas canvas, float alpha, float scale, boolean clear) {
if (mOldScreenTexture == null)
return;
if (clear) canvas.clearBuffer(view.getBackgroundColor());
canvas.save();
canvas.setAlpha(alpha);
int xOffset = view.getWidth() / 2;
int yOffset = view.getHeight() / 2;
canvas.translate(xOffset, yOffset);
canvas.scale(scale, scale, 1);
mOldScreenTexture.draw(canvas, -xOffset, -yOffset);
canvas.restore();
}
public void applyBackground(GLView view, GLCanvas canvas) {
if (mCurrentBackgroundAlpha > 0f) {
applyOldTexture(view, canvas, mCurrentBackgroundAlpha, mCurrentBackgroundScale, true);
}
}
public void applyContentTransform(GLView view, GLCanvas canvas) {
int xOffset = view.getWidth() / 2;
int yOffset = view.getHeight() / 2;
canvas.translate(xOffset, yOffset);
canvas.scale(mCurrentContentScale, mCurrentContentScale, 1);
canvas.translate(-xOffset, -yOffset);
canvas.setAlpha(mCurrentContentAlpha);
}
public void applyOverlay(GLView view, GLCanvas canvas) {
if (mCurrentOverlayAlpha > 0f) {
applyOldTexture(view, canvas, mCurrentOverlayAlpha, mCurrentOverlayScale, false);
}
}
}
@@ -19,8 +19,8 @@ package com.hippo.ehviewer.gallery.glrenderer;
import java.util.WeakHashMap;
import android.graphics.RectF;
import android.util.Log;
import com.hippo.ehviewer.util.Log;
import com.hippo.ehviewer.util.MathUtils;
// BasicTexture is a Texture corresponds to a real GL texture.
@@ -28,7 +28,6 @@ import com.hippo.ehviewer.util.MathUtils;
// If a BasicTexture is loaded into GL memory, it has a GL texture id.
public abstract class BasicTexture implements Texture {
@SuppressWarnings("unused")
private static final String TAG = "BasicTexture";
protected static final int UNSPECIFIED = -1;
@@ -53,6 +52,7 @@ public abstract class BasicTexture implements Texture {
protected GLCanvas mCanvasRef = null;
private static WeakHashMap<BasicTexture, Object> sAllTextures
= new WeakHashMap<BasicTexture, Object>();
@SuppressWarnings("rawtypes")
private static ThreadLocal sInFinalizer = new ThreadLocal();
protected BasicTexture(GLCanvas canvas, int id, int state) {
@@ -185,6 +185,7 @@ public abstract class BasicTexture implements Texture {
}
@Override
@SuppressWarnings("unchecked")
protected void finalize() {
sInFinalizer.set(BasicTexture.class);
recycle();
@@ -16,9 +16,8 @@
package com.hippo.ehviewer.gallery.glrenderer;
import android.graphics.Bitmap;
import junit.framework.Assert;
import android.graphics.Bitmap;
// BitmapTexture is a texture whose content is specified by a fixed Bitmap.
//
@@ -34,8 +34,8 @@ abstract class CanvasTexture extends UploadedTexture {
setOpaque(false);
}
@SuppressLint("WrongCall")
@Override
@SuppressLint("WrongCall")
protected Bitmap onGetBitmap() {
Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, mConfig);
mCanvas = new Canvas(bitmap);
@@ -20,7 +20,7 @@ package com.hippo.ehviewer.gallery.glrenderer;
// Before drawing, setSize() should be called.
public class ExtTexture extends BasicTexture {
private int mTarget;
private final int mTarget;
public ExtTexture(GLCanvas canvas, int target) {
GLId glId = canvas.getGLId();
@@ -20,8 +20,6 @@ import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.RectF;
import javax.microedition.khronos.opengles.GL11;
//
// GLCanvas gives a convenient interface to draw using OpenGL.
//
@@ -179,18 +177,6 @@ public interface GLCanvas {
public abstract void texSubImage2D(BasicTexture texture, int xOffset, int yOffset,
Bitmap bitmap,
int format, int type);
/**
* Calls glTexSubImage2D to upload a bitmap to the texture.
*
* @param texture The target texture to write to.
* @param xOffset Specifies a texel offset in the x direction within the
* texture array.
* @param yOffset Specifies a texel offset in the y direction within the
* texture array.
*/
public abstract void texSubImage2D(BasicTexture texture, int xOffset, int yOffset,
Bitmap bitmap);
/**
* Generates buffers and uploads the buffer data.
@@ -28,19 +28,19 @@ import javax.microedition.khronos.opengles.GL11Ext;
import javax.microedition.khronos.opengles.GL11ExtensionPack;
import junit.framework.Assert;
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.RectF;
import android.opengl.GLU;
import android.opengl.GLUtils;
import android.opengl.Matrix;
import android.util.Log;
import com.hippo.ehviewer.util.IntArray;
import com.hippo.ehviewer.util.Log;
import com.hippo.ehviewer.util.Utils;
public class GLES11Canvas implements GLCanvas {
@SuppressWarnings("unused")
private static final String TAG = "GLCanvasImp";
private static final float OPAQUE_ALPHA = 0.95f;
@@ -557,7 +557,6 @@ public class GLES11Canvas implements GLCanvas {
mGLState.setBlendEnabled(mBlendEnabled && (!from.isOpaque()
|| !Utils.isOpaque(toColor) || alpha < OPAQUE_ALPHA));
final GL11 gl = mGL;
if (!bindTexture(from)) return;
// Interpolate the RGB and alpha values between both textures.
@@ -591,7 +590,6 @@ public class GLES11Canvas implements GLCanvas {
private int mTextureTarget = GL11.GL_TEXTURE_2D;
private boolean mBlendEnabled = true;
private float mLineWidth = 1.0f;
private final boolean mLineSmooth = false;
public GLState(GL11 gl) {
mGL = gl;
@@ -817,6 +815,7 @@ public class GLES11Canvas implements GLCanvas {
}
@Override
@SuppressLint("DefaultLocale")
public void dumpStatisticsAndClear() {
String line = String.format(
"MESH:%d, TEX_OES:%d, TEX_RECT:%d, FILL_RECT:%d, LINE:%d",
@@ -959,13 +958,6 @@ public class GLES11Canvas implements GLCanvas {
GLUtils.texSubImage2D(target, 0, xOffset, yOffset, bitmap, format, type);
}
@Override
public void texSubImage2D(BasicTexture texture, int xOffset, int yOffset, Bitmap bitmap) {
int target = texture.getTarget();
mGL.glBindTexture(target, texture.getId());
GLUtils.texSubImage2D(target, 0, xOffset, yOffset, bitmap);
}
@Override
public int uploadBuffer(FloatBuffer buf) {
return uploadBuffer(buf, Float.SIZE / Byte.SIZE);
@@ -22,15 +22,16 @@ import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.RectF;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import android.opengl.Matrix;
import android.util.Log;
import com.hippo.ehviewer.util.IntArray;
import com.hippo.ehviewer.util.Log;
public class GLES20Canvas implements GLCanvas {
// ************** Constants **********************
@@ -818,6 +819,7 @@ public class GLES20Canvas implements GLCanvas {
}
@Override
@SuppressLint("DefaultLocale")
public void dumpStatisticsAndClear() {
String line = String.format("MESH:%d, TEX_RECT:%d, FILL_RECT:%d, LINE:%d", mCountDrawMesh,
mCountTextureRect, mCountFillRect, mCountDrawLine);
@@ -938,14 +940,6 @@ public class GLES20Canvas implements GLCanvas {
GLUtils.texSubImage2D(target, 0, xOffset, yOffset, bitmap, format, type);
}
@Override
public void texSubImage2D(BasicTexture texture, int xOffset, int yOffset, Bitmap bitmap) {
int target = texture.getTarget();
GLES20.glBindTexture(target, texture.getId());
checkError();
GLUtils.texSubImage2D(target, 0, xOffset, yOffset, bitmap);
}
@Override
public int uploadBuffer(FloatBuffer buf) {
return uploadBuffer(buf, FLOAT_SIZE);
@@ -1,10 +1,10 @@
package com.hippo.ehviewer.gallery.glrenderer;
import android.opengl.GLES20;
import javax.microedition.khronos.opengles.GL11;
import javax.microedition.khronos.opengles.GL11ExtensionPack;
import android.opengl.GLES20;
public class GLES20IdImpl implements GLId {
private final int[] mTempIntArray = new int[1];
@@ -21,14 +21,12 @@ import junit.framework.Assert;
public class GLPaint {
private float mLineWidth = 1f;
private int mColor = 0;
public GLPaint() {}
public GLPaint(int color, float width) {
public GLPaint(int color, float lineWidth) {
setColor(color);
setLineWidth(width);
setLineWidth(lineWidth);
}
public void setColor(int color) {
mColor = color;
}
@@ -16,11 +16,11 @@
package com.hippo.ehviewer.gallery.glrenderer;
import android.graphics.Rect;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import android.graphics.Rect;
// See "frameworks/base/include/utils/ResourceTypes.h" for the format of
// NinePatch chunk.
class NinePatchChunk {
@@ -81,6 +81,7 @@ public class NinePatchTexture extends ResourceTexture {
private static final int CACHE_SIZE = 16;
private static final int CACHE_SIZE_START_MOVE = CACHE_SIZE / 2;
private final int[] mKey = new int[CACHE_SIZE];
@SuppressWarnings("unchecked")
private final V[] mValue = (V[]) new Object[CACHE_SIZE];
private int mCount; // number of items in this cache
@@ -16,10 +16,10 @@
package com.hippo.ehviewer.gallery.glrenderer;
import com.hippo.ehviewer.util.Log;
import javax.microedition.khronos.opengles.GL11;
import android.util.Log;
public class RawTexture extends BasicTexture {
private static final String TAG = "RawTexture";
@@ -16,12 +16,11 @@
package com.hippo.ehviewer.gallery.glrenderer;
import junit.framework.Assert;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import junit.framework.Assert;
// ResourceTexture is a texture whose Bitmap is decoded from a resource.
// By default ResourceTexture is not opaque.
public class ResourceTexture extends UploadedTexture {
@@ -23,7 +23,6 @@ import android.graphics.Paint.FontMetricsInt;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.FloatMath;
// StringTexture is a texture shows the content of a specified String.
//
@@ -72,7 +71,7 @@ public class StringTexture extends CanvasTexture {
private static StringTexture newInstance(String text, TextPaint paint) {
FontMetricsInt metrics = paint.getFontMetricsInt();
int width = (int) FloatMath.ceil(paint.measureText(text));
int width = (int)Math.ceil(paint.measureText(text));
int height = metrics.bottom - metrics.top;
// The texture size needs to be at least 1x1.
if (width <= 0) width = 1;
@@ -16,11 +16,11 @@
package com.hippo.ehviewer.gallery.glrenderer;
import java.util.ArrayDeque;
import com.hippo.ehviewer.gallery.ui.GLRoot;
import com.hippo.ehviewer.gallery.ui.GLRoot.OnGLIdleListener;
import java.util.ArrayDeque;
public class TextureUploader implements OnGLIdleListener {
private static final int INIT_CAPACITY = 64;
private static final int QUOTA_PER_FRAME = 1;
@@ -16,6 +16,9 @@
package com.hippo.ehviewer.gallery.glrenderer;
import java.util.ArrayDeque;
import java.util.ArrayList;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
@@ -29,9 +32,6 @@ import android.os.SystemClock;
import com.hippo.ehviewer.gallery.ui.GLRoot;
import com.hippo.ehviewer.gallery.ui.GLRoot.OnGLIdleListener;
import java.util.ArrayDeque;
import java.util.ArrayList;
// This class is similar to BitmapTexture, except the bitmap is
// split into tiles. By doing so, we may increase the time required to
// upload the whole bitmap but we reduce the time of uploading each tile
@@ -129,18 +129,25 @@ public class TiledTexture implements Texture {
@Override
protected Bitmap onGetBitmap() {
int x = BORDER_SIZE - offsetX;
int y = BORDER_SIZE - offsetY;
int r = bitmap.getWidth() + x;
int b = bitmap.getHeight() + y;
sCanvas.drawBitmap(bitmap, x, y, sBitmapPaint);
// make a local copy of the reference to the bitmap,
// since it might be null'd in a different thread. b/8694871
Bitmap localBitmapRef = bitmap;
bitmap = null;
// draw borders if need
if (x > 0) sCanvas.drawLine(x - 1, 0, x - 1, TILE_SIZE, sPaint);
if (y > 0) sCanvas.drawLine(0, y - 1, TILE_SIZE, y - 1, sPaint);
if (r < CONTENT_SIZE) sCanvas.drawLine(r, 0, r, TILE_SIZE, sPaint);
if (b < CONTENT_SIZE) sCanvas.drawLine(0, b, TILE_SIZE, b, sPaint);
if (localBitmapRef != null) {
int x = BORDER_SIZE - offsetX;
int y = BORDER_SIZE - offsetY;
int r = localBitmapRef.getWidth() + x;
int b = localBitmapRef.getHeight() + y;
sCanvas.drawBitmap(localBitmapRef, x, y, sBitmapPaint);
localBitmapRef = null;
// draw borders if need
if (x > 0) sCanvas.drawLine(x - 1, 0, x - 1, TILE_SIZE, sPaint);
if (y > 0) sCanvas.drawLine(0, y - 1, TILE_SIZE, y - 1, sPaint);
if (r < CONTENT_SIZE) sCanvas.drawLine(r, 0, r, TILE_SIZE, sPaint);
if (b < CONTENT_SIZE) sCanvas.drawLine(0, b, TILE_SIZE, b, sPaint);
}
return sUploadBitmap;
}
@@ -143,9 +143,8 @@ public abstract class UploadedTexture extends BasicTexture {
}
private void freeBitmap() {
//Assert.assertTrue(mBitmap != null);
if (mBitmap != null)
onFreeBitmap(mBitmap);
Assert.assertTrue(mBitmap != null);
onFreeBitmap(mBitmap);
mBitmap = null;
}
@@ -210,10 +209,12 @@ public abstract class UploadedTexture extends BasicTexture {
private void uploadToCanvas(GLCanvas canvas) {
Bitmap bitmap = getBitmap();
if (bitmap != null && !bitmap.isRecycled()) {
if (bitmap != null) {
try {
int bWidth = bitmap.getWidth();
int bHeight = bitmap.getHeight();
int width = bWidth + mBorder * 2;
int height = bHeight + mBorder * 2;
int texWidth = getTextureWidth();
int texHeight = getTextureHeight();
@@ -25,7 +25,7 @@ public class DownUpDetector {
}
private boolean mStillDown;
private DownUpListener mListener;
private final DownUpListener mListener;
public DownUpDetector(DownUpListener listener) {
mListener = listener;
@@ -25,7 +25,6 @@ import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Matrix;
@@ -39,12 +38,12 @@ import android.view.MotionEvent;
import android.view.SurfaceHolder;
import com.hippo.ehviewer.gallery.anim.CanvasAnimation;
import com.hippo.ehviewer.gallery.common.ApiHelper;
import com.hippo.ehviewer.gallery.glrenderer.BasicTexture;
import com.hippo.ehviewer.gallery.glrenderer.GLCanvas;
import com.hippo.ehviewer.gallery.glrenderer.GLES11Canvas;
import com.hippo.ehviewer.gallery.glrenderer.GLES20Canvas;
import com.hippo.ehviewer.gallery.glrenderer.UploadedTexture;
import com.hippo.ehviewer.gallery.util.ApiHelper;
import com.hippo.ehviewer.gallery.util.GalleryUtils;
import com.hippo.ehviewer.gallery.util.MotionEventHelper;
import com.hippo.ehviewer.util.Log;
@@ -71,9 +70,6 @@ public class GLRootView extends GLSurfaceView
private static final boolean DEBUG_DRAWING_STAT = false;
private static final boolean DEBUG_PROFILE = false;
private static final boolean DEBUG_PROFILE_SLOW_ONLY = false;
private static final int FLAG_INITIALIZED = 1;
private static final int FLAG_NEED_LAYOUT = 2;
@@ -106,14 +102,13 @@ public class GLRootView extends GLSurfaceView
mRenderLock.newCondition();
private boolean mFreeze;
private long mLastDrawFinishTime;
private boolean mInDownState = false;
//private boolean mFirstDraw = true;
public GLRootView(Context context) {
this(context, null);
}
@SuppressWarnings("deprecation")
public GLRootView(Context context, AttributeSet attrs) {
super(context, attrs);
mFlags |= FLAG_INITIALIZED;
@@ -179,8 +174,8 @@ public class GLRootView extends GLSurfaceView
superRequestRender();
}
@SuppressLint("NewApi")
@Override
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void requestRender() {
if (DEBUG_INVALIDATE) {
StackTraceElement e = Thread.currentThread().getStackTrace()[4];
@@ -296,7 +291,7 @@ public class GLRootView extends GLSurfaceView
mRenderLock.unlock();
}
if (DEBUG_FPS || DEBUG_PROFILE) {
if (DEBUG_FPS) {
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
} else {
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
@@ -314,6 +309,7 @@ public class GLRootView extends GLSurfaceView
+ ", gl10: " + gl1.toString());
Process.setThreadPriority(Process.THREAD_PRIORITY_DISPLAY);
GalleryUtils.setRenderThread();
GL11 gl = (GL11) gl1;
Utils.assertTrue(mGL == gl);
@@ -347,21 +343,6 @@ public class GLRootView extends GLSurfaceView
} finally {
mRenderLock.unlock();
}
/*
// We put a black cover View in front of the SurfaceView and hide it
// after the first draw. This prevents the SurfaceView being transparent
// before the first draw.
if (mFirstDraw) {
mFirstDraw = false;
post(new Runnable() {
@Override
public void run() {
View root = getRootView();
View cover = root.findViewById(R.id.gl_root_cover);
cover.setVisibility(GONE);
}
});
}*/
}
private void onDrawFrameLocked(GL10 gl) {
@@ -385,6 +366,9 @@ public class GLRootView extends GLSurfaceView
rotateCanvas(-mCompensation);
if (mContentView != null) {
mContentView.render(mCanvas);
} else {
// Make sure we always draw something to prevent displaying garbage
mCanvas.clearBuffer();
}
mCanvas.restore();
@@ -544,6 +528,7 @@ public class GLRootView extends GLSurfaceView
}
@Override
@SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void setLightsOutMode(boolean enabled) {
if (!ApiHelper.HAS_SET_SYSTEM_UI_VISIBILITY) return;
@@ -24,6 +24,7 @@ import android.os.SystemClock;
import android.view.MotionEvent;
import com.hippo.ehviewer.gallery.anim.CanvasAnimation;
import com.hippo.ehviewer.gallery.anim.StateTransitionAnimation;
import com.hippo.ehviewer.gallery.glrenderer.GLCanvas;
import com.hippo.ehviewer.util.Log;
import com.hippo.ehviewer.util.Utils;
@@ -81,6 +82,7 @@ public class GLView {
protected int mScrollWidth = 0;
private float [] mBackgroundColor;
private StateTransitionAnimation mTransition;
public void startAnimation(CanvasAnimation animation) {
GLRoot root = getGLRoot();
@@ -222,12 +224,28 @@ public class GLView {
}
protected void render(GLCanvas canvas) {
boolean transitionActive = false;
if (mTransition != null && mTransition.calculate(AnimationTime.get())) {
invalidate();
transitionActive = mTransition.isActive();
}
renderBackground(canvas);
canvas.save();
if (transitionActive) {
mTransition.applyContentTransform(this, canvas);
}
for (int i = 0, n = getComponentCount(); i < n; ++i) {
renderChild(canvas, getComponent(i));
}
canvas.restore();
if (transitionActive) {
mTransition.applyOverlay(this, canvas);
}
}
public void setIntroAnimation(StateTransitionAnimation intro) {
mTransition = intro;
if (mTransition != null) mTransition.start();
}
public float [] getBackgroundColor() {
@@ -242,6 +260,10 @@ public class GLView {
if (mBackgroundColor != null) {
view.clearBuffer(mBackgroundColor);
}
if (mTransition != null && mTransition.isActive()) {
mTransition.applyBackground(this, view);
return;
}
}
protected void renderChild(GLCanvas canvas, GLView component) {
@@ -14,7 +14,9 @@
* limitations under the License.
*/
package com.hippo.ehviewer.gallery.common;
package com.hippo.ehviewer.gallery.util;
import java.lang.reflect.Field;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
@@ -24,8 +26,6 @@ import android.provider.MediaStore.MediaColumns;
import android.view.View;
import android.view.WindowManager;
import java.lang.reflect.Field;
public class ApiHelper {
public static interface VERSION_CODES {
// These value are copied from Build.VERSION_CODES
@@ -113,9 +113,6 @@ public class ApiHelper {
public static final boolean HAS_MEDIA_ACTION_SOUND =
Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
public static final boolean HAS_OLD_PANORAMA =
Build.VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH;
public static final boolean HAS_TIME_LAPSE_RECORDING =
Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
@@ -128,9 +125,6 @@ public class ApiHelper {
public static final boolean HAS_CAMERA_METERING_AREA =
Build.VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH;
public static final boolean HAS_FINE_RESOLUTION_QUALITY_LEVELS =
Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
public static final boolean HAS_MOTION_EVENT_TRANSFORM =
Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
@@ -42,10 +42,6 @@ public class GalleryUtils {
sCurrentThread = Thread.currentThread();
}
public static boolean isRenderThread() {
return sCurrentThread == Thread.currentThread();
}
public static void assertNotInRenderThread() {
if (!sWarned) {
if (Thread.currentThread() == sCurrentThread) {
@@ -15,14 +15,12 @@
*/
package com.hippo.ehviewer.gallery.util;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.graphics.Matrix;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords;
import com.hippo.ehviewer.gallery.common.ApiHelper;
public final class MotionEventHelper {
private MotionEventHelper() {}
@@ -36,6 +34,7 @@ public final class MotionEventHelper {
}
}
@SuppressLint("Recycle")
@TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
private static MotionEvent transformEventNew(MotionEvent e, Matrix m) {
MotionEvent newEvent = MotionEvent.obtain(e);
@@ -44,6 +43,7 @@ public final class MotionEventHelper {
}
// This is copied from Input.cpp in the android framework.
@SuppressLint("Recycle")
private static MotionEvent transformEventOld(MotionEvent e, Matrix m) {
long downTime = e.getDownTime();
long eventTime = e.getEventTime();
@@ -73,6 +73,7 @@ public final class MotionEventHelper {
m, pointerCoords[i].orientation);
}
@SuppressWarnings("deprecation")
MotionEvent n = MotionEvent.obtain(downTime, eventTime, action,
pointerCount, pointerIds, pointerCoords, metaState, xPrecision,
yPrecision, deviceId, edgeFlags, source, flags);
@@ -104,8 +105,8 @@ public final class MotionEventHelper {
// angle from vertical. Coordinate system: down is increasing Y, right is
// increasing X.
float[] v = new float[2];
v[0] = FloatMath.sin(angleRadians);
v[1] = -FloatMath.cos(angleRadians);
v[0] = (float)Math.sin(angleRadians);
v[1] = -(float)Math.cos(angleRadians);
m.mapVectors(v);
// Derive the transformed vector's clockwise angle from vertical.
-268
View File
@@ -1,268 +0,0 @@
/*
* Copyright (C) 2010 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.hippo.ehviewer.util;
import com.hippo.ehviewer.util.Log;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPool {
@SuppressWarnings("unused")
private static final String TAG = "ThreadPool";
private static final int CORE_POOL_SIZE = 4;
private static final int MAX_POOL_SIZE = 8;
private static final int KEEP_ALIVE_TIME = 10; // 10 seconds
// Resource type
public static final int MODE_NONE = 0;
public static final int MODE_CPU = 1;
public static final int MODE_NETWORK = 2;
public static final JobContext JOB_CONTEXT_STUB = new JobContextStub();
ResourceCounter mCpuCounter = new ResourceCounter(2);
ResourceCounter mNetworkCounter = new ResourceCounter(2);
// A Job is like a Callable, but it has an addition JobContext parameter.
public interface Job<T> {
public T run(JobContext jc);
}
public interface JobContext {
boolean isCancelled();
void setCancelListener(CancelListener listener);
boolean setMode(int mode);
}
private static class JobContextStub implements JobContext {
@Override
public boolean isCancelled() {
return false;
}
@Override
public void setCancelListener(CancelListener listener) {
}
@Override
public boolean setMode(int mode) {
return true;
}
}
public interface CancelListener {
public void onCancel();
}
private static class ResourceCounter {
public int value;
public ResourceCounter(int v) {
value = v;
}
}
private final Executor mExecutor;
public ThreadPool() {
this(CORE_POOL_SIZE, MAX_POOL_SIZE);
}
public ThreadPool(int initPoolSize, int maxPoolSize) {
mExecutor = new ThreadPoolExecutor(
initPoolSize, maxPoolSize, KEEP_ALIVE_TIME,
TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(),
new PriorityThreadFactory("thread-pool",
android.os.Process.THREAD_PRIORITY_DEFAULT));
}
// Submit a job to the thread pool. The listener will be called when the
// job is finished (or cancelled).
public <T> Future<T> submit(Job<T> job, FutureListener<T> listener) {
Worker<T> w = new Worker<T>(job, listener);
mExecutor.execute(w);
return w;
}
public <T> Future<T> submit(Job<T> job) {
return submit(job, null);
}
private class Worker<T> implements Runnable, Future<T>, JobContext {
@SuppressWarnings("hiding")
private static final String TAG = "Worker";
private Job<T> mJob;
private FutureListener<T> mListener;
private CancelListener mCancelListener;
private ResourceCounter mWaitOnResource;
private volatile boolean mIsCancelled;
private boolean mIsDone;
private T mResult;
private int mMode;
public Worker(Job<T> job, FutureListener<T> listener) {
mJob = job;
mListener = listener;
}
// This is called by a thread in the thread pool.
@Override
public void run() {
T result = null;
// A job is in CPU mode by default. setMode returns false
// if the job is cancelled.
if (setMode(MODE_CPU)) {
try {
result = mJob.run(this);
} catch (Throwable ex) {
Log.w(TAG, "Exception in running a job", ex);
}
}
synchronized(this) {
setMode(MODE_NONE);
mResult = result;
mIsDone = true;
notifyAll();
}
if (mListener != null) mListener.onFutureDone(this);
}
// Below are the methods for Future.
@Override
public synchronized void cancel() {
if (mIsCancelled) return;
mIsCancelled = true;
if (mWaitOnResource != null) {
synchronized (mWaitOnResource) {
mWaitOnResource.notifyAll();
}
}
if (mCancelListener != null) {
mCancelListener.onCancel();
}
}
@Override
public boolean isCancelled() {
return mIsCancelled;
}
@Override
public synchronized boolean isDone() {
return mIsDone;
}
@Override
public synchronized T get() {
while (!mIsDone) {
try {
wait();
} catch (Exception ex) {
Log.w(TAG, "ingore exception", ex);
// ignore.
}
}
return mResult;
}
@Override
public void waitDone() {
get();
}
// Below are the methods for JobContext (only called from the
// thread running the job)
@Override
public synchronized void setCancelListener(CancelListener listener) {
mCancelListener = listener;
if (mIsCancelled && mCancelListener != null) {
mCancelListener.onCancel();
}
}
@Override
public boolean setMode(int mode) {
// Release old resource
ResourceCounter rc = modeToCounter(mMode);
if (rc != null) releaseResource(rc);
mMode = MODE_NONE;
// Acquire new resource
rc = modeToCounter(mode);
if (rc != null) {
if (!acquireResource(rc)) {
return false;
}
mMode = mode;
}
return true;
}
private ResourceCounter modeToCounter(int mode) {
if (mode == MODE_CPU) {
return mCpuCounter;
} else if (mode == MODE_NETWORK) {
return mNetworkCounter;
} else {
return null;
}
}
private boolean acquireResource(ResourceCounter counter) {
while (true) {
synchronized (this) {
if (mIsCancelled) {
mWaitOnResource = null;
return false;
}
mWaitOnResource = counter;
}
synchronized (counter) {
if (counter.value > 0) {
counter.value--;
break;
} else {
try {
counter.wait();
} catch (InterruptedException ex) {
// ignore.
}
}
}
}
synchronized (this) {
mWaitOnResource = null;
}
return true;
}
private void releaseResource(ResourceCounter counter) {
synchronized (counter) {
counter.value++;
counter.notifyAll();
}
}
}
}