diff options
Diffstat (limited to 'src/org/cyanogenmod/wallpapers/photophase/PhotoFrame.java')
-rw-r--r-- | src/org/cyanogenmod/wallpapers/photophase/PhotoFrame.java | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/src/org/cyanogenmod/wallpapers/photophase/PhotoFrame.java b/src/org/cyanogenmod/wallpapers/photophase/PhotoFrame.java new file mode 100644 index 0000000..78fc265 --- /dev/null +++ b/src/org/cyanogenmod/wallpapers/photophase/PhotoFrame.java @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2013 The CyanogenMod 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 org.cyanogenmod.wallpapers.photophase; + +import android.content.Context; +import android.graphics.RectF; +import android.opengl.GLES20; + +import org.cyanogenmod.wallpapers.photophase.utils.GLESUtil; +import org.cyanogenmod.wallpapers.photophase.utils.GLESUtil.GLColor; +import org.cyanogenmod.wallpapers.photophase.utils.GLESUtil.GLESTextureInfo; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; + + +/** + * A GLES square geometry that represents one photo frame for show in the wallpaper. + */ +public class PhotoFrame implements TextureRequestor { + + /** + * @hide + */ + public static final int COORDS_PER_VERTER = 3; + + // The default texture coordinates (fit to frame) + private static final float[] DEFAULT_TEXTURE_COORDS = { + 0.0f, 1.0f, + 1.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 0.0f + }; + + + private final TextureManager mTextureManager; + + private final float[] mFrameVertex, mPhotoVertex; + private final float mFrameWidth, mFrameHeight; + private final float mPhotoWidth, mPhotoHeight; + + + private FloatBuffer mPositionBuffer; + private FloatBuffer mTextureBuffer; + + private GLESTextureInfo mTextureInfo; + + private final GLColor mBackgroundColor; + + private boolean mLoaded; + + private final Object mSync = new Object(); + + /** + * Constructor of <code>PhotoFrame</code>. + * + * @param ctx The current context + * @param textureManager The texture manager + * @param frameVertex A 4 dimension array with the coordinates per vertex plus padding + * @param photoVertex A 4 dimension array with the coordinates per vertex without padding + * @param color Background color + */ + public PhotoFrame(Context ctx, TextureManager textureManager, + float[] frameVertex, float[] photoVertex, GLColor color) { + super(); + mLoaded = false; + mBackgroundColor = color; + mTextureManager = textureManager; + + // Save dimensions + mFrameVertex = frameVertex; + mFrameWidth = frameVertex[6] - frameVertex[4]; + mFrameHeight = frameVertex[1] - frameVertex[5]; + mPhotoVertex = photoVertex; + mPhotoWidth = photoVertex[6] - photoVertex[4]; + mPhotoHeight = photoVertex[5] - photoVertex[1]; + + // Initialize vertex byte buffer for shape coordinates + ByteBuffer bb = ByteBuffer.allocateDirect(photoVertex.length * 4); // (# of coordinate values * 4 bytes per float) + bb.order(ByteOrder.nativeOrder()); + mPositionBuffer = bb.asFloatBuffer(); + mPositionBuffer.put(photoVertex); + mPositionBuffer.position(0); + + // Load the texture + mTextureInfo = null; + + // Request a new image for this frame + textureManager.request(this); + } + + /** + * {@inheritDoc} + */ + @Override + public RectF getRequestorDimensions() { + return new RectF(0, 0, mPhotoWidth, mPhotoHeight); + } + + /** + * {@inheritDoc} + */ + @Override + public void setTextureHandle(GLESTextureInfo ti) { + // If the picture is invalid request a new texture + if (ti == null || ti.handle <= 0) { + mTextureManager.request(this); + return; + } + + // Full frame picture + setTextureHandle(ti, DEFAULT_TEXTURE_COORDS); + mLoaded = true; + } + + /** + * Internal method that expose the texture coordinates to set + * + * @param ti The texture info + * @param textureCoords The texture coordinates + */ + private void setTextureHandle(GLESTextureInfo ti, final float[] textureCoords) { + // Recycle the previous handle + if (mTextureInfo != null) { + if (GLES20.glIsTexture(mTextureInfo.handle)) { + int[] textures = new int[]{mTextureInfo.handle}; + GLES20.glDeleteTextures(1, textures, 0); + GLESUtil.glesCheckError("glDeleteTextures"); + } + if (mTextureInfo.bitmap != null) { + mTextureInfo.bitmap.recycle(); + mTextureInfo.bitmap = null; + } + } + + // Initialize vertex byte buffer for shape coordinates + ByteBuffer bb = ByteBuffer.allocateDirect(textureCoords.length * 4); // (# of coordinate values * 4 bytes per float) + bb.order(ByteOrder.nativeOrder()); + synchronized (mSync) { + // Swap buffers + mTextureBuffer = bb.asFloatBuffer(); + mTextureBuffer.put(textureCoords); + mTextureBuffer.position(0); + } + mTextureInfo = ti; + } + + /** + * Method that returns the frame vertex + * + * @return float[] The frame vertex + */ + public float[] getFrameVertex() { + return mFrameVertex; + } + + /** + * Method that returns the frame width + * + * @return float The frame width + */ + public float getFrameWidth() { + return mFrameWidth; + } + + /** + * Method that returns the frame height + * + * @return float The frame height + */ + public float getFrameHeight() { + return mFrameHeight; + } + + /** + * Method that returns the photo vertex + * + * @return float[] The photo vertex + */ + public float[] getPhotoVertex() { + return mPhotoVertex; + } + + /** + * Method that returns the photo width + * + * @return float The photo width + */ + public float getPhotoWidth() { + return mPhotoWidth; + } + + /** + * Method that returns the photo height + * + * @return float The photo height + */ + public float getPhotoHeight() { + return mPhotoHeight; + } + + /** + * Method that returns the position vertex buffer + * + * @return FloatBuffer The position vertex buffer + */ + public FloatBuffer getPositionBuffer() { + return mPositionBuffer; + } + + /** + * Method that returns the texture buffer + * + * @return FloatBuffer The texture buffer + */ + public FloatBuffer getTextureBuffer() { + synchronized (mSync) { + return mTextureBuffer; + } + } + + /** + * Method that returns the texture handle + * + * @return int The texture handle + */ + public int getTextureHandle() { + if (mTextureInfo != null) { + return mTextureInfo.handle; + } + return -1; + } + + /** + * Method that returns the texture info + * + * @return GLESTextureInfo The texture info + */ + public GLESTextureInfo getTextureInfo() { + return mTextureInfo; + } + + /** + * Method that returns the background color of the frame + * + * @return GLColor The background color + */ + public GLColor getBackgroundColor() { + return mBackgroundColor; + } + + /** + * Method that returns if the frame is loaded (has its picture loaded) + * + * @return boolean If the frame is loaded (has its picture loaded) + */ + public boolean isLoaded() { + return mLoaded; + } + + /** + * Request a recycle of the references of the object + */ + public void recycle() { + if (mTextureInfo != null && mTextureInfo.handle != 0) { + int[] textures = new int[]{mTextureInfo.handle}; + GLES20.glDeleteTextures(1, textures, 0); + GLESUtil.glesCheckError("glDeleteTextures"); + } + mTextureInfo = null; + + if (mPositionBuffer != null) { + mPositionBuffer.clear(); + } + if (mTextureBuffer != null) { + mTextureBuffer.clear(); + } + mPositionBuffer = null; + mTextureBuffer = null; + } +} |