OSDN Git Service

Remove dependencies on FloatMath
[android-x86/packages-apps-Gallery2.git] / src / com / android / gallery3d / ui / TileImageView.java
index 5ce06be..1103ed8 100644 (file)
 
 package com.android.gallery3d.ui;
 
+import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.RectF;
-import android.util.FloatMath;
+import android.support.v4.util.LongSparseArray;
+import android.util.DisplayMetrics;
+import android.view.WindowManager;
 
 import com.android.gallery3d.app.GalleryContext;
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.common.LongSparseArray;
 import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.data.BitmapPool;
 import com.android.gallery3d.data.DecodeUtils;
+import com.android.photos.data.GalleryBitmapPool;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.UploadedTexture;
 import com.android.gallery3d.util.Future;
-import com.android.gallery3d.util.GalleryUtils;
 import com.android.gallery3d.util.ThreadPool;
 import com.android.gallery3d.util.ThreadPool.CancelListener;
 import com.android.gallery3d.util.ThreadPool.JobContext;
@@ -41,15 +43,10 @@ public class TileImageView extends GLView {
 
     @SuppressWarnings("unused")
     private static final String TAG = "TileImageView";
-
-    // TILE_SIZE must be 2^N - 2. We put one pixel border in each side of the
-    // texture to avoid seams between tiles.
-    private static int TILE_SIZE;
-    private static final int TILE_BORDER = 1;
-    private static int BITMAP_SIZE;
     private static final int UPLOAD_LIMIT = 1;
 
-    private static BitmapPool sTilePool;
+    // TILE_SIZE must be 2^N
+    private static int sTileSize;
 
     /*
      *  This is the tile state in the CPU side.
@@ -76,7 +73,7 @@ public class TileImageView extends GLView {
     private static final int STATE_RECYCLING = 0x20;
     private static final int STATE_RECYCLED = 0x40;
 
-    private Model mModel;
+    private TileSource mModel;
     private ScreenNail mScreenNail;
     protected int mLevelCount;  // cache the value of mScaledBitmaps.length
 
@@ -125,7 +122,7 @@ public class TileImageView extends GLView {
     private final ThreadPool mThreadPool;
     private boolean mBackgroundTileUploaded;
 
-    public static interface Model {
+    public static interface TileSource {
         public int getLevelCount();
         public ScreenNail getScreenNail();
         public int getImageWidth();
@@ -133,8 +130,7 @@ public class TileImageView extends GLView {
 
         // The tile returned by this method can be specified this way: Assuming
         // the image size is (width, height), first take the intersection of (0,
-        // 0) - (width, height) and (x, y) - (x + tileSize, y + tileSize). Then
-        // extend this intersection region by borderSize pixels on each side. If
+        // 0) - (width, height) and (x, y) - (x + tileSize, y + tileSize). If
         // in extending the region, we found some part of the region are outside
         // the image, those pixels are filled with black.
         //
@@ -143,28 +139,30 @@ public class TileImageView extends GLView {
         // still refers to the coordinate on the original image.
         //
         // The method would be called in another thread.
-        public Bitmap getTile(int level, int x, int y, int tileSize,
-                int borderSize, BitmapPool pool);
+        public Bitmap getTile(int level, int x, int y, int tileSize);
+    }
+
+    public static boolean isHighResolution(Context context) {
+        DisplayMetrics metrics = new DisplayMetrics();
+        WindowManager wm = (WindowManager)
+                context.getSystemService(Context.WINDOW_SERVICE);
+        wm.getDefaultDisplay().getMetrics(metrics);
+        return metrics.heightPixels > 2048 ||  metrics.widthPixels > 2048;
     }
 
     public TileImageView(GalleryContext context) {
         mThreadPool = context.getThreadPool();
         mTileDecoder = mThreadPool.submit(new TileDecoder());
-        if (TILE_SIZE == 0) {
-            if (GalleryUtils.isHighResolution(context.getAndroidContext())) {
-                TILE_SIZE = 510 ;
+        if (sTileSize == 0) {
+            if (isHighResolution(context.getAndroidContext())) {
+                sTileSize = 512 ;
             } else {
-                TILE_SIZE = 254;
+                sTileSize = 256;
             }
-            BITMAP_SIZE = TILE_SIZE + TILE_BORDER * 2;
-            sTilePool =
-                    ApiHelper.HAS_REUSING_BITMAP_IN_BITMAP_REGION_DECODER
-                    ? new BitmapPool(BITMAP_SIZE, BITMAP_SIZE, 128)
-                    : null;
         }
     }
 
-    public void setModel(Model model) {
+    public void setModel(TileSource model) {
         mModel = model;
         if (model != null) notifyModelInvalidated();
     }
@@ -266,7 +264,7 @@ public class TileImageView extends GLView {
         }
 
         for (int i = fromLevel; i < endLevel; ++i) {
-            int size = TILE_SIZE << i;
+            int size = sTileSize << i;
             Rect r = range[i - fromLevel];
             for (int y = r.top, bottom = r.bottom; y < bottom; y += size) {
                 for (int x = r.left, right = r.right; x < right; x += size) {
@@ -314,13 +312,13 @@ public class TileImageView extends GLView {
         int height = (int) Math.ceil(Math.max(
                 Math.abs(sin * w + cos * h), Math.abs(sin * w - cos * h)));
 
-        int left = (int) FloatMath.floor(cX - width / (2f * scale));
-        int top = (int) FloatMath.floor(cY - height / (2f * scale));
-        int right = (int) FloatMath.ceil(left + width / scale);
-        int bottom = (int) FloatMath.ceil(top + height / scale);
+        int left = (int) Math.floor(cX - width / (2f * scale));
+        int top = (int) Math.floor(cY - height / (2f * scale));
+        int right = (int) Math.ceil(left + width / scale);
+        int bottom = (int) Math.ceil(top + height / scale);
 
         // align the rectangle to tile boundary
-        int size = TILE_SIZE << level;
+        int size = sTileSize << level;
         left = Math.max(0, size * (left / size));
         top = Math.max(0, size * (top / size));
         right = Math.min(mImageWidth, right);
@@ -392,7 +390,6 @@ public class TileImageView extends GLView {
             }
         }
         setScreenNail(null);
-        if (sTilePool != null) sTilePool.clear();
     }
 
     public void prepareTextures() {
@@ -431,7 +428,7 @@ public class TileImageView extends GLView {
                     mScreenNail.noDraw();
                 }
 
-                int size = (TILE_SIZE << level);
+                int size = (sTileSize << level);
                 float length = size * mScale;
                 Rect r = mTileRange;
 
@@ -462,8 +459,8 @@ public class TileImageView extends GLView {
     }
 
     private boolean isScreenNailAnimating() {
-        return (mScreenNail instanceof BitmapScreenNail)
-                && ((BitmapScreenNail) mScreenNail).isAnimating();
+        return (mScreenNail instanceof TiledScreenNail)
+                && ((TiledScreenNail) mScreenNail).isAnimating();
     }
 
     private void uploadBackgroundTiles(GLCanvas canvas) {
@@ -501,7 +498,7 @@ public class TileImageView extends GLView {
             if (tile.mTileState == STATE_RECYCLING) {
                 tile.mTileState = STATE_RECYCLED;
                 if (tile.mDecodedTile != null) {
-                    if (sTilePool != null) sTilePool.recycle(tile.mDecodedTile);
+                    GalleryBitmapPool.getInstance().put(tile.mDecodedTile);
                     tile.mDecodedTile = null;
                 }
                 mRecycledQueue.push(tile);
@@ -529,7 +526,7 @@ public class TileImageView extends GLView {
         }
         tile.mTileState = STATE_RECYCLED;
         if (tile.mDecodedTile != null) {
-            if (sTilePool != null) sTilePool.recycle(tile.mDecodedTile);
+            GalleryBitmapPool.getInstance().put(tile.mDecodedTile);
             tile.mDecodedTile = null;
         }
         mRecycledQueue.push(tile);
@@ -575,8 +572,10 @@ public class TileImageView extends GLView {
                 }
                 if (tile == null) break;
                 if (!tile.isContentValid()) {
+                    boolean hasBeenLoaded = tile.isLoaded();
                     Utils.assertTrue(tile.mTileState == STATE_DECODED);
                     tile.updateContent(canvas);
+                    if (!hasBeenLoaded) tile.draw(canvas, 0, 0);
                     --quota;
                 }
             }
@@ -592,7 +591,7 @@ public class TileImageView extends GLView {
         RectF source = mSourceRect;
         RectF target = mTargetRect;
         target.set(x, y, x + length, y + length);
-        source.set(0, 0, TILE_SIZE, TILE_SIZE);
+        source.set(0, 0, sTileSize, sTileSize);
 
         Tile tile = getTile(tx, ty, level);
         if (tile != null) {
@@ -612,7 +611,7 @@ public class TileImageView extends GLView {
             if (drawTile(tile, canvas, source, target)) return;
         }
         if (mScreenNail != null) {
-            int size = TILE_SIZE << level;
+            int size = sTileSize << level;
             float scaleX = (float) mScreenNail.getWidth() / mImageWidth;
             float scaleY = (float) mScreenNail.getHeight() / mImageHeight;
             source.set(tx * scaleX, ty * scaleY, (tx + size) * scaleX,
@@ -621,13 +620,10 @@ public class TileImageView extends GLView {
         }
     }
 
-    // TODO: avoid drawing the unused part of the textures.
     static boolean drawTile(
             Tile tile, GLCanvas canvas, RectF source, RectF target) {
         while (true) {
             if (tile.isContentValid()) {
-                // offset source rectangle for the texture border.
-                source.offset(TILE_BORDER, TILE_BORDER);
                 canvas.drawTexture(tile, source, target);
                 return true;
             }
@@ -639,15 +635,15 @@ public class TileImageView extends GLView {
                 source.left /= 2f;
                 source.right /= 2f;
             } else {
-                source.left = (TILE_SIZE + source.left) / 2f;
-                source.right = (TILE_SIZE + source.right) / 2f;
+                source.left = (sTileSize + source.left) / 2f;
+                source.right = (sTileSize + source.right) / 2f;
             }
             if (tile.mY == parent.mY) {
                 source.top /= 2f;
                 source.bottom /= 2f;
             } else {
-                source.top = (TILE_SIZE + source.top) / 2f;
-                source.bottom = (TILE_SIZE + source.bottom) / 2f;
+                source.top = (sTileSize + source.top) / 2f;
+                source.bottom = (sTileSize + source.bottom) / 2f;
             }
             tile = parent;
         }
@@ -669,7 +665,7 @@ public class TileImageView extends GLView {
 
         @Override
         protected void onFreeBitmap(Bitmap bitmap) {
-            if (sTilePool != null) sTilePool.recycle(bitmap);
+            GalleryBitmapPool.getInstance().put(bitmap);
         }
 
         boolean decode() {
@@ -677,7 +673,7 @@ public class TileImageView extends GLView {
             // by (1 << mTilelevel) from a region in the original image.
             try {
                 mDecodedTile = DecodeUtils.ensureGLCompatibleBitmap(mModel.getTile(
-                        mTileLevel, mX, mY, TILE_SIZE, TILE_BORDER, sTilePool));
+                        mTileLevel, mX, mY, sTileSize));
             } catch (Throwable t) {
                 Log.w(TAG, "fail to decode tile", t);
             }
@@ -690,9 +686,9 @@ public class TileImageView extends GLView {
 
             // We need to override the width and height, so that we won't
             // draw beyond the boundaries.
-            int rightEdge = ((mImageWidth - mX) >> mTileLevel) + TILE_BORDER;
-            int bottomEdge = ((mImageHeight - mY) >> mTileLevel) + TILE_BORDER;
-            setSize(Math.min(BITMAP_SIZE, rightEdge), Math.min(BITMAP_SIZE, bottomEdge));
+            int rightEdge = ((mImageWidth - mX) >> mTileLevel);
+            int bottomEdge = ((mImageHeight - mY) >> mTileLevel);
+            setSize(Math.min(sTileSize, rightEdge), Math.min(sTileSize, bottomEdge));
 
             Bitmap bitmap = mDecodedTile;
             mDecodedTile = null;
@@ -706,12 +702,12 @@ public class TileImageView extends GLView {
         // boundary).
         @Override
         public int getTextureWidth() {
-            return TILE_SIZE + TILE_BORDER * 2;
+            return sTileSize;
         }
 
         @Override
         public int getTextureHeight() {
-            return TILE_SIZE + TILE_BORDER * 2;
+            return sTileSize;
         }
 
         public void update(int x, int y, int level) {
@@ -723,7 +719,7 @@ public class TileImageView extends GLView {
 
         public Tile getParentTile() {
             if (mTileLevel + 1 == mLevelCount) return null;
-            int size = TILE_SIZE << (mTileLevel + 1);
+            int size = sTileSize << (mTileLevel + 1);
             int x = size * (mX / size);
             int y = size * (mY / size);
             return getTile(x, y, mTileLevel + 1);
@@ -732,7 +728,7 @@ public class TileImageView extends GLView {
         @Override
         public String toString() {
             return String.format("tile(%s, %s, %s / %s)",
-                    mX / TILE_SIZE, mY / TILE_SIZE, mLevel, mLevelCount);
+                    mX / sTileSize, mY / sTileSize, mLevel, mLevelCount);
         }
     }