summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/glrenderer/TiledTexture.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/glrenderer/TiledTexture.java')
-rw-r--r--src/com/android/gallery3d/glrenderer/TiledTexture.java349
1 files changed, 0 insertions, 349 deletions
diff --git a/src/com/android/gallery3d/glrenderer/TiledTexture.java b/src/com/android/gallery3d/glrenderer/TiledTexture.java
deleted file mode 100644
index 6ca1de088..000000000
--- a/src/com/android/gallery3d/glrenderer/TiledTexture.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * 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.android.gallery3d.glrenderer;
-
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.RectF;
-import android.os.SystemClock;
-
-import com.android.gallery3d.ui.GLRoot;
-import com.android.gallery3d.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
-// so it make the animation more smooth and prevents jank.
-public class TiledTexture implements Texture {
- private static final int CONTENT_SIZE = 254;
- private static final int BORDER_SIZE = 1;
- private static final int TILE_SIZE = CONTENT_SIZE + 2 * BORDER_SIZE;
- private static final int INIT_CAPACITY = 8;
-
- // We are targeting at 60fps, so we have 16ms for each frame.
- // In this 16ms, we use about 4~8 ms to upload tiles.
- private static final long UPLOAD_TILE_LIMIT = 4; // ms
-
- private static Tile sFreeTileHead = null;
- private static final Object sFreeTileLock = new Object();
-
- private static Bitmap sUploadBitmap;
- private static Canvas sCanvas;
- private static Paint sBitmapPaint;
- private static Paint sPaint;
-
- private int mUploadIndex = 0;
-
- private final Tile[] mTiles; // Can be modified in different threads.
- // Should be protected by "synchronized."
- private final int mWidth;
- private final int mHeight;
- private final RectF mSrcRect = new RectF();
- private final RectF mDestRect = new RectF();
-
- public static class Uploader implements OnGLIdleListener {
- private final ArrayDeque<TiledTexture> mTextures =
- new ArrayDeque<TiledTexture>(INIT_CAPACITY);
-
- private final GLRoot mGlRoot;
- private boolean mIsQueued = false;
-
- public Uploader(GLRoot glRoot) {
- mGlRoot = glRoot;
- }
-
- public synchronized void clear() {
- mTextures.clear();
- }
-
- public synchronized void addTexture(TiledTexture t) {
- if (t.isReady()) return;
- mTextures.addLast(t);
-
- if (mIsQueued) return;
- mIsQueued = true;
- mGlRoot.addOnGLIdleListener(this);
- }
-
- @Override
- public boolean onGLIdle(GLCanvas canvas, boolean renderRequested) {
- ArrayDeque<TiledTexture> deque = mTextures;
- synchronized (this) {
- long now = SystemClock.uptimeMillis();
- long dueTime = now + UPLOAD_TILE_LIMIT;
- while (now < dueTime && !deque.isEmpty()) {
- TiledTexture t = deque.peekFirst();
- if (t.uploadNextTile(canvas)) {
- deque.removeFirst();
- mGlRoot.requestRender();
- }
- now = SystemClock.uptimeMillis();
- }
- mIsQueued = !mTextures.isEmpty();
-
- // return true to keep this listener in the queue
- return mIsQueued;
- }
- }
- }
-
- private static class Tile extends UploadedTexture {
- public int offsetX;
- public int offsetY;
- public Bitmap bitmap;
- public Tile nextFreeTile;
- public int contentWidth;
- public int contentHeight;
-
- @Override
- public void setSize(int width, int height) {
- contentWidth = width;
- contentHeight = height;
- mWidth = width + 2 * BORDER_SIZE;
- mHeight = height + 2 * BORDER_SIZE;
- mTextureWidth = TILE_SIZE;
- mTextureHeight = TILE_SIZE;
- }
-
- @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);
- 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);
-
- return sUploadBitmap;
- }
-
- @Override
- protected void onFreeBitmap(Bitmap bitmap) {
- // do nothing
- }
- }
-
- private static void freeTile(Tile tile) {
- tile.invalidateContent();
- tile.bitmap = null;
- synchronized (sFreeTileLock) {
- tile.nextFreeTile = sFreeTileHead;
- sFreeTileHead = tile;
- }
- }
-
- private static Tile obtainTile() {
- synchronized (sFreeTileLock) {
- Tile result = sFreeTileHead;
- if (result == null) return new Tile();
- sFreeTileHead = result.nextFreeTile;
- result.nextFreeTile = null;
- return result;
- }
- }
-
- private boolean uploadNextTile(GLCanvas canvas) {
- if (mUploadIndex == mTiles.length) return true;
-
- synchronized (mTiles) {
- Tile next = mTiles[mUploadIndex++];
-
- // Make sure tile has not already been recycled by the time
- // this is called (race condition in onGLIdle)
- if (next.bitmap != null) {
- boolean hasBeenLoad = next.isLoaded();
- next.updateContent(canvas);
-
- // It will take some time for a texture to be drawn for the first
- // time. When scrolling, we need to draw several tiles on the screen
- // at the same time. It may cause a UI jank even these textures has
- // been uploaded.
- if (!hasBeenLoad) next.draw(canvas, 0, 0);
- }
- }
- return mUploadIndex == mTiles.length;
- }
-
- public TiledTexture(Bitmap bitmap) {
- mWidth = bitmap.getWidth();
- mHeight = bitmap.getHeight();
- ArrayList<Tile> list = new ArrayList<Tile>();
-
- for (int x = 0, w = mWidth; x < w; x += CONTENT_SIZE) {
- for (int y = 0, h = mHeight; y < h; y += CONTENT_SIZE) {
- Tile tile = obtainTile();
- tile.offsetX = x;
- tile.offsetY = y;
- tile.bitmap = bitmap;
- tile.setSize(
- Math.min(CONTENT_SIZE, mWidth - x),
- Math.min(CONTENT_SIZE, mHeight - y));
- list.add(tile);
- }
- }
- mTiles = list.toArray(new Tile[list.size()]);
- }
-
- public boolean isReady() {
- return mUploadIndex == mTiles.length;
- }
-
- // Can be called in UI thread.
- public void recycle() {
- synchronized (mTiles) {
- for (int i = 0, n = mTiles.length; i < n; ++i) {
- freeTile(mTiles[i]);
- }
- }
- }
-
- public static void freeResources() {
- sUploadBitmap = null;
- sCanvas = null;
- sBitmapPaint = null;
- sPaint = null;
- }
-
- public static void prepareResources() {
- sUploadBitmap = Bitmap.createBitmap(TILE_SIZE, TILE_SIZE, Config.ARGB_8888);
- sCanvas = new Canvas(sUploadBitmap);
- sBitmapPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
- sBitmapPaint.setXfermode(new PorterDuffXfermode(Mode.SRC));
- sPaint = new Paint();
- sPaint.setXfermode(new PorterDuffXfermode(Mode.SRC));
- sPaint.setColor(Color.TRANSPARENT);
- }
-
- // We want to draw the "source" on the "target".
- // This method is to find the "output" rectangle which is
- // the corresponding area of the "src".
- // (x,y) target
- // (x0,y0) source +---------------+
- // +----------+ | |
- // | src | | output |
- // | +--+ | linear map | +----+ |
- // | +--+ | ----------> | | | |
- // | | by (scaleX, scaleY) | +----+ |
- // +----------+ | |
- // Texture +---------------+
- // Canvas
- private static void mapRect(RectF output,
- RectF src, float x0, float y0, float x, float y, float scaleX,
- float scaleY) {
- output.set(x + (src.left - x0) * scaleX,
- y + (src.top - y0) * scaleY,
- x + (src.right - x0) * scaleX,
- y + (src.bottom - y0) * scaleY);
- }
-
- // Draws a mixed color of this texture and a specified color onto the
- // a rectangle. The used color is: from * (1 - ratio) + to * ratio.
- public void drawMixed(GLCanvas canvas, int color, float ratio,
- int x, int y, int width, int height) {
- RectF src = mSrcRect;
- RectF dest = mDestRect;
- float scaleX = (float) width / mWidth;
- float scaleY = (float) height / mHeight;
- synchronized (mTiles) {
- for (int i = 0, n = mTiles.length; i < n; ++i) {
- Tile t = mTiles[i];
- src.set(0, 0, t.contentWidth, t.contentHeight);
- src.offset(t.offsetX, t.offsetY);
- mapRect(dest, src, 0, 0, x, y, scaleX, scaleY);
- src.offset(BORDER_SIZE - t.offsetX, BORDER_SIZE - t.offsetY);
- canvas.drawMixed(t, color, ratio, mSrcRect, mDestRect);
- }
- }
- }
-
- // Draws the texture on to the specified rectangle.
- @Override
- public void draw(GLCanvas canvas, int x, int y, int width, int height) {
- RectF src = mSrcRect;
- RectF dest = mDestRect;
- float scaleX = (float) width / mWidth;
- float scaleY = (float) height / mHeight;
- synchronized (mTiles) {
- for (int i = 0, n = mTiles.length; i < n; ++i) {
- Tile t = mTiles[i];
- src.set(0, 0, t.contentWidth, t.contentHeight);
- src.offset(t.offsetX, t.offsetY);
- mapRect(dest, src, 0, 0, x, y, scaleX, scaleY);
- src.offset(BORDER_SIZE - t.offsetX, BORDER_SIZE - t.offsetY);
- canvas.drawTexture(t, mSrcRect, mDestRect);
- }
- }
- }
-
- // Draws a sub region of this texture on to the specified rectangle.
- public void draw(GLCanvas canvas, RectF source, RectF target) {
- RectF src = mSrcRect;
- RectF dest = mDestRect;
- float x0 = source.left;
- float y0 = source.top;
- float x = target.left;
- float y = target.top;
- float scaleX = target.width() / source.width();
- float scaleY = target.height() / source.height();
-
- synchronized (mTiles) {
- for (int i = 0, n = mTiles.length; i < n; ++i) {
- Tile t = mTiles[i];
- src.set(0, 0, t.contentWidth, t.contentHeight);
- src.offset(t.offsetX, t.offsetY);
- if (!src.intersect(source)) continue;
- mapRect(dest, src, x0, y0, x, y, scaleX, scaleY);
- src.offset(BORDER_SIZE - t.offsetX, BORDER_SIZE - t.offsetY);
- canvas.drawTexture(t, src, dest);
- }
- }
- }
-
- @Override
- public int getWidth() {
- return mWidth;
- }
-
- @Override
- public int getHeight() {
- return mHeight;
- }
-
- @Override
- public void draw(GLCanvas canvas, int x, int y) {
- draw(canvas, x, y, mWidth, mHeight);
- }
-
- @Override
- public boolean isOpaque() {
- return false;
- }
-}