更新 Gallery2 部分
This commit is contained in:
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) {
|
||||
|
||||
+3
-9
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user