package com.cooliris.media; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import javax.microedition.khronos.opengles.GL10; import javax.microedition.khronos.opengles.GL11; import android.content.Context; public final class GridDrawManager { public static final int PASS_THUMBNAIL_CONTENT = 0; public static final int PASS_FOCUS_CONTENT = 1; public static final int PASS_FRAME = 2; public static final int PASS_PLACEHOLDER = 3; public static final int PASS_FRAME_PLACEHOLDER = 4; public static final int PASS_TEXT_LABEL = 5; public static final int PASS_SELECTION_LABEL = 6; public static final int PASS_VIDEO_LABEL = 7; public static final int PASS_LOCATION_LABEL = 8; public static final int PASS_MEDIASET_SOURCE_LABEL = 9; private static final MediaItemTexture.Config sThumbnailConfig = new MediaItemTexture.Config(); private final DisplayItem[] mDisplayItems; private final DisplaySlot[] mDisplaySlots; private final DisplayList mDisplayList; private final GridCamera mCamera; private final GridDrawables mDrawables; private IndexRange mBufferedVisibleRange; private IndexRange mVisibleRange; private int mSelectedSlot; private int mCurrentFocusSlot; private DisplayItem[] mItemsDrawn; private int mDrawnCounter; private float mTargetFocusMixRatio = 0.0f; private float mFocusMixRatio = 0.0f; private final FloatAnim mSelectedMixRatio = new FloatAnim(0f); private float mCurrentFocusItemWidth; private float mCurrentFocusItemHeight; private boolean mCurrentFocusIsPressed; private final Texture mNoItemsTexture; private static final Comparator<DisplayItem> sDisplayItemComparator = new Comparator<DisplayItem>() { public int compare(DisplayItem a, DisplayItem b) { if (a == null || b == null) { return 0; } float delta = (a.mAnimatedPosition.z - b.mAnimatedPosition.z); if (delta > 0) { return 1; } else if (delta < 0) { return -1; } else { return 0; } } }; public GridDrawManager(Context context, GridCamera camera, GridDrawables drawables, DisplayList displayList, DisplayItem[] displayItems, DisplaySlot[] displaySlots) { sThumbnailConfig.thumbnailWidth = 128; sThumbnailConfig.thumbnailHeight = 96; mDisplayItems = displayItems; mDisplaySlots = displaySlots; mDisplayList = displayList; mDrawables = drawables; mCamera = camera; mItemsDrawn = new DisplayItem[GridLayer.MAX_ITEMS_DRAWABLE]; StringTexture.Config stc = new StringTexture.Config(); stc.bold = true; stc.fontSize = 16 * Gallery.PIXEL_DENSITY; stc.sizeMode = StringTexture.Config.SIZE_EXACT; stc.overflowMode = StringTexture.Config.OVERFLOW_FADE; mNoItemsTexture = new StringTexture(context.getResources().getString(R.string.no_items), stc); } public void prepareDraw(IndexRange bufferedVisibleRange, IndexRange visibleRange, int selectedSlot, int currentFocusSlot, boolean currentFocusIsPressed) { mBufferedVisibleRange = bufferedVisibleRange; mVisibleRange = visibleRange; mSelectedSlot = selectedSlot; mCurrentFocusSlot = currentFocusSlot; mCurrentFocusIsPressed = currentFocusIsPressed; } public boolean update(float timeElapsed) { mFocusMixRatio = FloatUtils.animate(mFocusMixRatio, mTargetFocusMixRatio, timeElapsed); mTargetFocusMixRatio = 0.0f; if (mFocusMixRatio != mTargetFocusMixRatio || mSelectedMixRatio.isAnimating()) { return true; } return false; } public void drawThumbnails(RenderView view, GL11 gl, int state) { final GridDrawables drawables = mDrawables; final DisplayList displayList = mDisplayList; final DisplayItem[] displayItems = mDisplayItems; final int firstBufferedVisibleSlot = mBufferedVisibleRange.begin; final int lastBufferedVisibleSlot = mBufferedVisibleRange.end; final int firstVisibleSlot = mVisibleRange.begin; final int lastVisibleSlot = mVisibleRange.end; final int selectedSlotIndex = mSelectedSlot; final int currentFocusSlot = mCurrentFocusSlot; final DisplayItem[] itemsDrawn = mItemsDrawn; itemsDrawn[0] = null; // No items drawn yet. int drawnCounter = 0; final GridQuad grid = GridDrawables.sGrid; grid.bindArrays(gl); int numTexturesQueued = 0; Context context = view.getContext(); for (int itrSlotIndex = firstBufferedVisibleSlot; itrSlotIndex <= lastBufferedVisibleSlot; ++itrSlotIndex) { int index = itrSlotIndex; boolean priority = !(index < firstVisibleSlot || index > lastVisibleSlot); int startSlotIndex = 0; for (int j = GridLayer.MAX_DISPLAYED_ITEMS_PER_SLOT - 1; j >= 0; --j) { DisplayItem displayItem = displayItems[(index - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT + j]; if (displayItem == null) { continue; } else { Texture texture = displayItem.getThumbnailImage(context, sThumbnailConfig); if (texture != null && texture.isLoaded() == false) { startSlotIndex = j; break; } } } // Prime the textures in the reverse order. for (int j = 0; j < GridLayer.MAX_DISPLAYED_ITEMS_PER_SLOT; ++j) { DisplayItem displayItem = displayItems[(index - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT + j]; if (displayItem == null) { continue; } else { if (selectedSlotIndex != Shared.INVALID && (index <= selectedSlotIndex - 2 || index >= selectedSlotIndex + 2)) { displayItem.clearScreennailImage(); } Texture texture = displayItem.getThumbnailImage(context, sThumbnailConfig); if (texture != null && !texture.isLoaded() && numTexturesQueued <= 6) { boolean isCached = texture.isCached(); view.prime(texture, priority); view.bind(texture); if (priority && isCached && texture.mState != Texture.STATE_ERROR) ++numTexturesQueued; } } } if (itrSlotIndex == selectedSlotIndex) { continue; } view.prime(drawables.mTexturePlaceholder, true); Texture placeholder = (state == GridLayer.STATE_GRID_VIEW) ? drawables.mTexturePlaceholder : null; final boolean pushDown = (state == GridLayer.STATE_GRID_VIEW || state == GridLayer.STATE_FULL_SCREEN) ? false : true; for (int j = startSlotIndex; j < GridLayer.MAX_DISPLAYED_ITEMS_PER_SLOT; ++j) { DisplayItem displayItem = displayItems[(index - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT + j]; if (displayItem == null) { break; } else { if (currentFocusSlot == index) { displayList.setHasFocus(displayItem, true, pushDown); mTargetFocusMixRatio = 1.0f; } else { displayList.setHasFocus(displayItem, false, pushDown); } Texture texture = displayItem.getThumbnailImage(view.getContext(), sThumbnailConfig); if (texture != null) { if ((!displayItem.isAnimating() || !texture.isLoaded()) && displayItem.getStackIndex() > GridLayer.MAX_ITEMS_PER_SLOT) { displayItem.mAlive = true; continue; } if (index < firstVisibleSlot || index > lastVisibleSlot) { if (view.bind(texture)) { mDisplayList.setAlive(displayItem, true); } continue; } drawDisplayItem(view, gl, displayItem, texture, PASS_THUMBNAIL_CONTENT, placeholder, displayItem.mAnimatedPlaceholderFade); } else { // Move on to the next stack. break; } if (drawnCounter >= GridLayer.MAX_ITEMS_DRAWABLE - 1 || drawnCounter < 0) { break; } // Insert in order of z. itemsDrawn[drawnCounter++] = displayItem; itemsDrawn[drawnCounter] = null; } } } mDrawnCounter = drawnCounter; grid.unbindArrays(gl); } public float getFocusQuadWidth() { return mCurrentFocusItemWidth; } public float getFocusQuadHeight() { return mCurrentFocusItemHeight; } public void drawFocusItems(RenderView view, GL11 gl, float zoomValue, boolean slideshowMode, float timeElapsedSinceView) { int selectedSlotIndex = mSelectedSlot; GridDrawables drawables = mDrawables; GridCamera camera = mCamera; DisplayItem[] displayItems = mDisplayItems; int firstBufferedVisibleSlot = mBufferedVisibleRange.begin; int lastBufferedVisibleSlot = mBufferedVisibleRange.end; boolean isCameraZAnimating = mCamera.isZAnimating(); for (int i = firstBufferedVisibleSlot; i <= lastBufferedVisibleSlot; ++i) { if (selectedSlotIndex != Shared.INVALID && (i >= selectedSlotIndex - 2 && i <= selectedSlotIndex + 2)) { continue; } DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT]; if (displayItem != null) { displayItem.clearScreennailImage(); } } if (selectedSlotIndex != Shared.INVALID) { float camX = camera.mLookAtX * camera.mScale; int centerIndexInDrawnArray = (selectedSlotIndex - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT; if (centerIndexInDrawnArray < 0 || centerIndexInDrawnArray >= displayItems.length) { return; } DisplayItem centerDisplayItem = displayItems[centerIndexInDrawnArray]; if (centerDisplayItem == null || centerDisplayItem.mItemRef.mId == Shared.INVALID) { return; } boolean focusItemTextureLoaded = false; Texture centerTexture = centerDisplayItem.getScreennailImage(view.getContext()); if (centerTexture != null && centerTexture.isLoaded()) { focusItemTextureLoaded = true; } float centerTranslateX = centerDisplayItem.mAnimatedPosition.x; final boolean skipPrevious = centerTranslateX < camX; view.setAlpha(1.0f); gl.glEnable(GL11.GL_BLEND); gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE); float backupImageTheta = 0.0f; for (int i = -1; i <= 1; ++i) { if (slideshowMode && timeElapsedSinceView > 1.0f && i != 0) continue; float viewAspect = camera.mAspectRatio; int selectedSlotToUse = selectedSlotIndex + i; if (selectedSlotToUse >= 0 && selectedSlotToUse <= lastBufferedVisibleSlot) { int indexInDrawnArray = (selectedSlotToUse - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT; if (indexInDrawnArray < 0 || indexInDrawnArray >= displayItems.length) { return; } DisplayItem displayItem = displayItems[indexInDrawnArray]; MediaItem item = displayItem.mItemRef; final Texture thumbnailTexture = displayItem.getThumbnailImage(view.getContext(), sThumbnailConfig); Texture texture = displayItem.getScreennailImage(view.getContext()); if (isCameraZAnimating && (texture == null || !texture.isLoaded())) { texture = thumbnailTexture; mSelectedMixRatio.setValue(0f); mSelectedMixRatio.animateValue(1f, 0.75f, view.getFrameTime()); } Texture hiRes = (zoomValue != 1.0f && i == 0 && item.getMediaType() != MediaItem.MEDIA_TYPE_VIDEO) ? displayItem .getHiResImage(view.getContext()) : null; if (Gallery.PIXEL_DENSITY > 1.0f) { hiRes = texture; } if (i != 0) { displayItem.clearHiResImage(); } if (hiRes != null) { if (!hiRes.isLoaded()) { view.bind(hiRes); view.prime(hiRes, true); } else { texture = hiRes; } } final Texture fsTexture = texture; if (texture == null || !texture.isLoaded()) { if (Math.abs(centerTranslateX - camX) < 0.1f) { if (focusItemTextureLoaded && i != 0) { view.bind(texture); } if (i == 0) { view.bind(texture); view.prime(texture, true); } } texture = thumbnailTexture; if (i == 0) { mSelectedMixRatio.setValue(0f); mSelectedMixRatio.animateValue(1f, 0.75f, view.getFrameTime()); } } if (mCamera.isAnimating() || slideshowMode) { if (!slideshowMode && skipPrevious && i == -1) { continue; } if (!skipPrevious && i == 1) { continue; } } int theta = (int) displayItem.getImageTheta(); // If it is in slideshow mode, we draw the previous item in // the next item's position. if (slideshowMode && timeElapsedSinceView < 1.0f && timeElapsedSinceView != 0) { if (i == -1) { int nextSlotToUse = selectedSlotToUse + 1; if (nextSlotToUse >= 0 && nextSlotToUse <= lastBufferedVisibleSlot) { int nextIndexInDrawnArray = (nextSlotToUse - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT; if (nextIndexInDrawnArray >= 0 && nextIndexInDrawnArray < displayItems.length) { float currentImageTheta = displayItem.mAnimatedImageTheta; displayItem = displayItems[nextIndexInDrawnArray]; backupImageTheta = displayItem.mAnimatedImageTheta; displayItem.mAnimatedImageTheta = currentImageTheta; view.setAlpha(1.0f - timeElapsedSinceView); } } } else if (i == 0) { displayItem.mAnimatedImageTheta = backupImageTheta; view.setAlpha(timeElapsedSinceView); } } if (texture != null) { int vboIndex = i + 1; float alpha = view.getAlpha(); float selectedMixRatio = mSelectedMixRatio.getValue(view.getFrameTime()); if (selectedMixRatio != 1f) { texture = thumbnailTexture; view.setAlpha(alpha * (1.0f - selectedMixRatio)); } GridQuad quad = GridDrawables.sFullscreenGrid[vboIndex]; float u = texture.getNormalizedWidth(); float v = texture.getNormalizedHeight(); float imageWidth = texture.getWidth(); float imageHeight = texture.getHeight(); boolean portrait = ((theta / 90) % 2 == 1); if (portrait) { viewAspect = 1.0f / viewAspect; } quad.resizeQuad(viewAspect, u, v, imageWidth, imageHeight); quad.bindArrays(gl); drawDisplayItem(view, gl, displayItem, texture, PASS_FOCUS_CONTENT, null, 0.0f); quad.unbindArrays(gl); if (selectedMixRatio != 0.0f && selectedMixRatio != 1.0f) { texture = fsTexture; if (texture != null) { float drawAlpha = selectedMixRatio; view.setAlpha(alpha * drawAlpha); u = texture.getNormalizedWidth(); v = texture.getNormalizedHeight(); imageWidth = texture.getWidth(); imageHeight = texture.getHeight(); quad.resizeQuad(viewAspect, u, v, imageWidth, imageHeight); quad.bindArrays(gl); drawDisplayItem(view, gl, displayItem, fsTexture, PASS_FOCUS_CONTENT, null, 1.0f); quad.unbindArrays(gl); } } if (i == 0 || slideshowMode) { mCurrentFocusItemWidth = quad.getWidth(); mCurrentFocusItemHeight = quad.getHeight(); if (portrait) { // Swap these values. float itemWidth = mCurrentFocusItemWidth; mCurrentFocusItemWidth = mCurrentFocusItemHeight; mCurrentFocusItemHeight = itemWidth; } } view.setAlpha(alpha); if (item.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO) { // The play graphic overlay. GridDrawables.sVideoGrid.bindArrays(gl); drawDisplayItem(view, gl, displayItem, drawables.mTextureVideo, PASS_VIDEO_LABEL, null, 0); GridDrawables.sVideoGrid.unbindArrays(gl); } } } } } } public void drawBlendedComponents(RenderView view, GL11 gl, float alpha, int state, int hudMode, float stackMixRatio, float gridMixRatio, MediaBucketList selectedBucketList, MediaBucketList markedBucketList, boolean isFeedLoading) { int firstBufferedVisibleSlot = mBufferedVisibleRange.begin; int lastBufferedVisibleSlot = mBufferedVisibleRange.end; int firstVisibleSlot = mVisibleRange.begin; int lastVisibleSlot = mVisibleRange.end; DisplayItem[] displayItems = mDisplayItems; GridDrawables drawables = mDrawables; // We draw the frames around the drawn items. boolean currentFocusIsPressed = mCurrentFocusIsPressed; if (state != GridLayer.STATE_FULL_SCREEN) { GridDrawables.sFrame.bindArrays(gl); Texture texturePlaceHolder = (state == GridLayer.STATE_GRID_VIEW) ? drawables.mTextureGridFrame : drawables.mTextureFrame; for (int i = firstBufferedVisibleSlot; i <= lastBufferedVisibleSlot; ++i) { if (i < firstVisibleSlot || i > lastVisibleSlot) { continue; } boolean slotIsAlive = false; if (state != GridLayer.STATE_MEDIA_SETS && state != GridLayer.STATE_TIMELINE) { for (int j = 0; j < GridLayer.MAX_DISPLAYED_ITEMS_PER_SLOT; ++j) { DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT + j]; if (displayItem != null) { slotIsAlive |= displayItem.mAlive; } } if (!slotIsAlive) { DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT]; if (displayItem != null) { drawDisplayItem(view, gl, displayItem, texturePlaceHolder, PASS_FRAME_PLACEHOLDER, null, 0); } } } } Texture texturePressed = drawables.mTextureFramePressed; Texture textureFocus = drawables.mTextureFrameFocus; Texture textureGrid = drawables.mTextureGridFrame; Texture texture = drawables.mTextureFrame; int drawnCounter = mDrawnCounter; DisplayItem[] itemsDrawn = mItemsDrawn; if (texture != null) { if (drawnCounter > 0) { Arrays.sort(itemsDrawn, 0, drawnCounter, sDisplayItemComparator); float timeElapsedSinceGridView = gridMixRatio; float timeElapsedSinceStackView = stackMixRatio; for (int i = drawnCounter - 1; i >= 0; --i) { DisplayItem itemDrawn = itemsDrawn[i]; if (itemDrawn == null) { continue; } boolean displayItemPresentInSelectedItems = selectedBucketList.find(itemDrawn.mItemRef); boolean displayItemPresentInMarkedItems = markedBucketList.find(itemDrawn.mItemRef); Texture previousTexture = (displayItemPresentInSelectedItems) ? texturePressed : texture; Texture textureToUse = (itemDrawn.getHasFocus()) ? (currentFocusIsPressed ? texturePressed : textureFocus) : ((displayItemPresentInSelectedItems) ? texturePressed : (displayItemPresentInMarkedItems) ? texture : textureGrid); float ratio = timeElapsedSinceGridView; if (itemDrawn.mAlive) { if (state != GridLayer.STATE_GRID_VIEW) { previousTexture = (displayItemPresentInSelectedItems) ? texturePressed : texture; textureToUse = (itemDrawn.getHasFocus()) ? (currentFocusIsPressed ? texturePressed : textureFocus) : previousTexture; if (timeElapsedSinceStackView == 1.0f) { ratio = mFocusMixRatio; } else { ratio = timeElapsedSinceStackView; previousTexture = textureGrid; } } drawDisplayItem(view, gl, itemDrawn, textureToUse, PASS_FRAME, previousTexture, ratio); } } } } GridDrawables.sFrame.unbindArrays(gl); gl.glDepthFunc(GL10.GL_ALWAYS); if (state == GridLayer.STATE_MEDIA_SETS || state == GridLayer.STATE_TIMELINE) { DisplaySlot[] displaySlots = mDisplaySlots; GridDrawables.sTextGrid.bindArrays(gl); final float textOffsetY = 0.82f; gl.glTranslatef(0.0f, -textOffsetY, 0.0f); HashMap<String, StringTexture> stringTextureTable = GridDrawables.sStringTextureTable; ReverseGeocoder reverseGeocoder = ((Gallery) view.getContext()).getReverseGeocoder(); boolean itemsPresent = false; for (int i = firstBufferedVisibleSlot; i <= lastBufferedVisibleSlot; ++i) { itemsPresent = true; DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT]; if (displayItem != null) { DisplaySlot displaySlot = displaySlots[i - firstBufferedVisibleSlot]; Texture textureString = displaySlot.getTitleImage(stringTextureTable); view.loadTexture(textureString); if (textureString != null) { if (i < firstVisibleSlot || i > lastVisibleSlot) { continue; } drawDisplayItem(view, gl, displayItem, textureString, PASS_TEXT_LABEL, null, 0); } } } if (!itemsPresent && !isFeedLoading) { // Draw the no items texture. int wWidth = view.getWidth(); int wHeight = view.getHeight(); // Size this to be 40 pxls less than screen width mNoItemsTexture.mWidth = wWidth - 40; int x = (int) Math.floor((wWidth / 2) - (mNoItemsTexture.getWidth() / 2)); int y = (int) Math.floor((wHeight / 2) - (mNoItemsTexture.getHeight() / 2)); view.draw2D(mNoItemsTexture, x, y); } float yLocOffset = 0.2f; gl.glTranslatef(0.0f, -yLocOffset, 0.0f); for (int i = firstBufferedVisibleSlot; i <= lastBufferedVisibleSlot; ++i) { DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT]; if (displayItem != null) { DisplaySlot displaySlot = displaySlots[i - firstBufferedVisibleSlot]; StringTexture textureString = displaySlot.getLocationImage(reverseGeocoder, stringTextureTable); if (textureString != null) { view.loadTexture(textureString); drawDisplayItem(view, gl, displayItem, textureString, PASS_TEXT_LABEL, null, 0); } } } if (state == GridLayer.STATE_TIMELINE) { GridDrawables.sLocationGrid.bindArrays(gl); Texture locationTexture = drawables.mTextureLocation; final float yLocationLabelOffset = 0.19f; for (int i = firstBufferedVisibleSlot; i <= lastBufferedVisibleSlot; ++i) { DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT]; if (displayItem != null) { if (displayItem.mAlive == true) { DisplaySlot displaySlot = displaySlots[i - firstBufferedVisibleSlot]; if (displaySlot.hasValidLocation()) { StringTexture textureString = displaySlot.getLocationImage(reverseGeocoder, stringTextureTable); float textWidth = (textureString != null) ? textureString.computeTextWidth() : 0; textWidth *= (mCamera.mOneByScale * 0.5f); if (textWidth == 0.0f) { textWidth -= 0.18f; } textWidth += 0.1f; gl.glTranslatef(textWidth, -yLocationLabelOffset, 0.0f); drawDisplayItem(view, gl, displayItem, locationTexture, PASS_LOCATION_LABEL, null, 0); gl.glTranslatef(-textWidth, yLocationLabelOffset, 0.0f); } } } } GridDrawables.sLocationGrid.unbindArrays(gl); } else if (state == GridLayer.STATE_MEDIA_SETS && stackMixRatio > 0.0f) { GridDrawables.sSourceIconGrid.bindArrays(gl); Texture transparentTexture = drawables.mTextureTransparent; for (int i = firstBufferedVisibleSlot; i <= lastBufferedVisibleSlot; ++i) { DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT]; if (displayItem != null) { if (displayItem.mAlive == true) { DisplaySlot displaySlot = displaySlots[i - firstBufferedVisibleSlot]; Texture locationTexture = view.getResource(drawables .getIconForSet(displaySlot.getMediaSet(), false), false); // Draw the icon at 0.85 alpha over the top item // in the stack. gl.glTranslatef(0.24f, 0.5f, 0); drawDisplayItem(view, gl, displayItem, locationTexture, PASS_MEDIASET_SOURCE_LABEL, transparentTexture, 0.85f); gl.glTranslatef(-0.24f, -0.5f, 0); } } } GridDrawables.sSourceIconGrid.unbindArrays(gl); } gl.glTranslatef(0.0f, yLocOffset, 0.0f); gl.glTranslatef(0.0f, textOffsetY, 0.0f); GridDrawables.sTextGrid.unbindArrays(gl); } if (hudMode == HudLayer.MODE_SELECT && state != GridLayer.STATE_FULL_SCREEN) { Texture textureSelectedOn = drawables.mTextureCheckmarkOn; Texture textureSelectedOff = drawables.mTextureCheckmarkOff; view.prime(textureSelectedOn, true); view.prime(textureSelectedOff, true); GridDrawables.sSelectedGrid.bindArrays(gl); for (int i = firstBufferedVisibleSlot; i <= lastBufferedVisibleSlot; ++i) { DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT]; if (displayItem != null) { Texture textureToUse = selectedBucketList.find(displayItem.mItemRef) ? textureSelectedOn : textureSelectedOff; drawDisplayItem(view, gl, displayItem, textureToUse, PASS_SELECTION_LABEL, null, 0); } } GridDrawables.sSelectedGrid.unbindArrays(gl); } GridDrawables.sVideoGrid.bindArrays(gl); Texture videoTexture = drawables.mTextureVideo; for (int i = firstBufferedVisibleSlot; i <= lastBufferedVisibleSlot; ++i) { DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT]; if (displayItem != null && displayItem.mAlive) { if (displayItem.mItemRef.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO) { drawDisplayItem(view, gl, displayItem, videoTexture, PASS_VIDEO_LABEL, null, 0); } } } GridDrawables.sVideoGrid.unbindArrays(gl); gl.glDepthFunc(GL10.GL_LEQUAL); } } private void drawDisplayItem(RenderView view, GL11 gl, DisplayItem displayItem, Texture texture, int pass, Texture previousTexture, float mixRatio) { GridCamera camera = mCamera; Vector3f animatedPosition = displayItem.mAnimatedPosition; float translateXf = animatedPosition.x * camera.mOneByScale; float translateYf = animatedPosition.y * camera.mOneByScale; float translateZf = -animatedPosition.z; int stackId = displayItem.getStackIndex(); if (pass == PASS_PLACEHOLDER || pass == PASS_FRAME_PLACEHOLDER) { translateZf = -0.04f; } else { if (pass == PASS_FRAME) translateZf += 0.02f; if ((pass == PASS_TEXT_LABEL || pass == PASS_LOCATION_LABEL || pass == PASS_SELECTION_LABEL) && !displayItem.isAlive()) { translateZf = 0.0f; } if (pass == PASS_TEXT_LABEL) { translateZf = 0.0f; } } boolean usingMixedTextures = false; boolean bind = false; if ((pass != PASS_THUMBNAIL_CONTENT) || (stackId < GridLayer.MAX_DISPLAYED_ITEMS_PER_SLOT && texture.isLoaded() && (previousTexture == null || previousTexture .isLoaded()))) { if (mixRatio == 1.0f || previousTexture == null || texture == previousTexture) { bind = view.bind(texture); } else if (mixRatio != 0.0f) { if (!texture.isLoaded() || !previousTexture.isLoaded()) { // Submit the previous texture to the load queue view.bind(previousTexture); bind = view.bind(texture); } else { usingMixedTextures = true; bind = view.bindMixed(previousTexture, texture, mixRatio); } } else { bind = view.bind(previousTexture); } } else if (stackId >= GridLayer.MAX_DISPLAYED_ITEMS_PER_SLOT && pass == PASS_THUMBNAIL_CONTENT) { mDisplayList.setAlive(displayItem, true); } if (!texture.isLoaded() || !bind) { if (pass == PASS_THUMBNAIL_CONTENT) { if (previousTexture != null && previousTexture.isLoaded() && translateZf == 0.0f) { translateZf = -0.08f; bind |= view.bind(previousTexture); } if (!bind) { return; } } else { return; } } else { if (pass == PASS_THUMBNAIL_CONTENT || pass == PASS_FOCUS_CONTENT) { if (!displayItem.mAlive) { mDisplayList.setAlive(displayItem, true); } } } gl.glTranslatef(-translateXf, -translateYf, -translateZf); float theta = (pass == PASS_FOCUS_CONTENT) ? displayItem.mAnimatedImageTheta + displayItem.mAnimatedTheta : displayItem.mAnimatedTheta; if (theta != 0.0f) { gl.glRotatef(theta, 0.0f, 0.0f, 1.0f); } float orientation = 0.0f; if (pass == PASS_THUMBNAIL_CONTENT && displayItem.mAnimatedImageTheta != 0.0f) { orientation = displayItem.mAnimatedImageTheta; } if (pass == PASS_FRAME || pass == PASS_FRAME_PLACEHOLDER) { GridQuadFrame.draw(gl); } else { GridQuad.draw(gl, orientation); } if (theta != 0.0f) { gl.glRotatef(-theta, 0.0f, 0.0f, 1.0f); } gl.glTranslatef(translateXf, translateYf, translateZf); if (usingMixedTextures) { view.unbindMixed(); } } }