1 package com.cooliris.media;
3 import java.util.Arrays;
4 import java.util.Comparator;
5 import java.util.HashMap;
7 import javax.microedition.khronos.opengles.GL10;
8 import javax.microedition.khronos.opengles.GL11;
10 import android.content.Context;
12 public final class GridDrawManager {
13 public static final int PASS_THUMBNAIL_CONTENT = 0;
14 public static final int PASS_FOCUS_CONTENT = 1;
15 public static final int PASS_FRAME = 2;
16 public static final int PASS_PLACEHOLDER = 3;
17 public static final int PASS_FRAME_PLACEHOLDER = 4;
18 public static final int PASS_TEXT_LABEL = 5;
19 public static final int PASS_SELECTION_LABEL = 6;
20 public static final int PASS_VIDEO_LABEL = 7;
21 public static final int PASS_LOCATION_LABEL = 8;
22 public static final int PASS_MEDIASET_SOURCE_LABEL = 9;
24 private static final MediaItemTexture.Config sThumbnailConfig = new MediaItemTexture.Config();
25 private final DisplayItem[] mDisplayItems;
26 private final DisplaySlot[] mDisplaySlots;
27 private final DisplayList mDisplayList;
28 private final GridCamera mCamera;
29 private final GridDrawables mDrawables;
30 private IndexRange mBufferedVisibleRange;
31 private IndexRange mVisibleRange;
32 private int mSelectedSlot;
33 private int mCurrentFocusSlot;
34 private DisplayItem[] mItemsDrawn;
35 private int mDrawnCounter;
36 private float mTargetFocusMixRatio = 0.0f;
37 private float mFocusMixRatio = 0.0f;
38 private final FloatAnim mSelectedMixRatio = new FloatAnim(0f);
39 private float mCurrentFocusItemWidth;
40 private float mCurrentFocusItemHeight;
41 private boolean mCurrentFocusIsPressed;
42 private final Texture mNoItemsTexture;
44 private static final Comparator<DisplayItem> sDisplayItemComparator = new Comparator<DisplayItem>() {
45 public int compare(DisplayItem a, DisplayItem b) {
46 if (a == null || b == null) {
49 float delta = (a.mAnimatedPosition.z - b.mAnimatedPosition.z);
52 } else if (delta < 0) {
60 public GridDrawManager(Context context, GridCamera camera, GridDrawables drawables, DisplayList displayList,
61 DisplayItem[] displayItems, DisplaySlot[] displaySlots) {
62 sThumbnailConfig.thumbnailWidth = 128;
63 sThumbnailConfig.thumbnailHeight = 96;
64 mDisplayItems = displayItems;
65 mDisplaySlots = displaySlots;
66 mDisplayList = displayList;
67 mDrawables = drawables;
69 mItemsDrawn = new DisplayItem[GridLayer.MAX_ITEMS_DRAWABLE];
71 StringTexture.Config stc = new StringTexture.Config();
73 stc.fontSize = 16 * Gallery.PIXEL_DENSITY;
74 stc.sizeMode = StringTexture.Config.SIZE_EXACT;
75 stc.overflowMode = StringTexture.Config.OVERFLOW_FADE;
76 mNoItemsTexture = new StringTexture(context.getResources().getString(R.string.no_items), stc);
80 public void prepareDraw(IndexRange bufferedVisibleRange, IndexRange visibleRange, int selectedSlot, int currentFocusSlot,
81 boolean currentFocusIsPressed) {
82 mBufferedVisibleRange = bufferedVisibleRange;
83 mVisibleRange = visibleRange;
84 mSelectedSlot = selectedSlot;
85 mCurrentFocusSlot = currentFocusSlot;
86 mCurrentFocusIsPressed = currentFocusIsPressed;
89 public boolean update(float timeElapsed) {
90 mFocusMixRatio = FloatUtils.animate(mFocusMixRatio, mTargetFocusMixRatio, timeElapsed);
91 mTargetFocusMixRatio = 0.0f;
92 if (mFocusMixRatio != mTargetFocusMixRatio || mSelectedMixRatio.isAnimating()) {
98 public void drawThumbnails(RenderView view, GL11 gl, int state) {
99 final GridDrawables drawables = mDrawables;
100 final DisplayList displayList = mDisplayList;
101 final DisplayItem[] displayItems = mDisplayItems;
102 final int firstBufferedVisibleSlot = mBufferedVisibleRange.begin;
103 final int lastBufferedVisibleSlot = mBufferedVisibleRange.end;
104 final int firstVisibleSlot = mVisibleRange.begin;
105 final int lastVisibleSlot = mVisibleRange.end;
106 final int selectedSlotIndex = mSelectedSlot;
107 final int currentFocusSlot = mCurrentFocusSlot;
108 final DisplayItem[] itemsDrawn = mItemsDrawn;
109 itemsDrawn[0] = null; // No items drawn yet.
110 int drawnCounter = 0;
111 final GridQuad grid = GridDrawables.sGrid;
113 int numTexturesQueued = 0;
114 Context context = view.getContext();
115 for (int itrSlotIndex = firstBufferedVisibleSlot; itrSlotIndex <= lastBufferedVisibleSlot; ++itrSlotIndex) {
116 int index = itrSlotIndex;
117 boolean priority = !(index < firstVisibleSlot || index > lastVisibleSlot);
118 int startSlotIndex = 0;
119 for (int j = GridLayer.MAX_DISPLAYED_ITEMS_PER_SLOT - 1; j >= 0; --j) {
120 DisplayItem displayItem = displayItems[(index - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT + j];
121 if (displayItem == null) {
124 Texture texture = displayItem.getThumbnailImage(context, sThumbnailConfig);
125 if (texture != null && texture.isLoaded() == false) {
131 // Prime the textures in the reverse order.
132 for (int j = 0; j < GridLayer.MAX_DISPLAYED_ITEMS_PER_SLOT; ++j) {
133 DisplayItem displayItem = displayItems[(index - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT + j];
134 if (displayItem == null) {
137 if (selectedSlotIndex != Shared.INVALID && (index <= selectedSlotIndex - 2 || index >= selectedSlotIndex + 2)) {
138 displayItem.clearScreennailImage();
140 Texture texture = displayItem.getThumbnailImage(context, sThumbnailConfig);
141 if (texture != null && !texture.isLoaded() && numTexturesQueued <= 6) {
142 boolean isCached = texture.isCached();
144 view.prime(texture, priority);
146 if (priority && isCached && texture.mState != Texture.STATE_ERROR)
151 if (itrSlotIndex == selectedSlotIndex) {
154 view.prime(drawables.mTexturePlaceholder, true);
155 Texture placeholder = (state == GridLayer.STATE_GRID_VIEW) ? drawables.mTexturePlaceholder : null;
156 final boolean pushDown = (state == GridLayer.STATE_GRID_VIEW || state == GridLayer.STATE_FULL_SCREEN) ? false : true;
157 for (int j = startSlotIndex; j < GridLayer.MAX_DISPLAYED_ITEMS_PER_SLOT; ++j) {
158 DisplayItem displayItem = displayItems[(index - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT + j];
159 if (displayItem == null) {
162 if (currentFocusSlot == index) {
163 displayList.setHasFocus(displayItem, true, pushDown);
164 mTargetFocusMixRatio = 1.0f;
166 displayList.setHasFocus(displayItem, false, pushDown);
168 Texture texture = displayItem.getThumbnailImage(view.getContext(), sThumbnailConfig);
169 if (texture != null) {
170 if ((!displayItem.isAnimating() || !texture.isLoaded())
171 && displayItem.getStackIndex() > GridLayer.MAX_ITEMS_PER_SLOT) {
172 displayItem.mAlive = true;
175 if (index < firstVisibleSlot || index > lastVisibleSlot) {
176 if (view.bind(texture)) {
177 mDisplayList.setAlive(displayItem, true);
181 drawDisplayItem(view, gl, displayItem, texture, PASS_THUMBNAIL_CONTENT, placeholder,
182 displayItem.mAnimatedPlaceholderFade);
184 // Move on to the next stack.
187 if (drawnCounter >= GridLayer.MAX_ITEMS_DRAWABLE - 1 || drawnCounter < 0) {
190 // Insert in order of z.
191 itemsDrawn[drawnCounter++] = displayItem;
192 itemsDrawn[drawnCounter] = null;
196 mDrawnCounter = drawnCounter;
197 grid.unbindArrays(gl);
200 public float getFocusQuadWidth() {
201 return mCurrentFocusItemWidth;
204 public float getFocusQuadHeight() {
205 return mCurrentFocusItemHeight;
208 public void drawFocusItems(RenderView view, GL11 gl, float zoomValue, boolean slideshowMode, float timeElapsedSinceView) {
209 int selectedSlotIndex = mSelectedSlot;
210 GridDrawables drawables = mDrawables;
211 GridCamera camera = mCamera;
212 DisplayItem[] displayItems = mDisplayItems;
213 int firstBufferedVisibleSlot = mBufferedVisibleRange.begin;
214 int lastBufferedVisibleSlot = mBufferedVisibleRange.end;
215 boolean isCameraZAnimating = mCamera.isZAnimating();
216 for (int i = firstBufferedVisibleSlot; i <= lastBufferedVisibleSlot; ++i) {
217 if (selectedSlotIndex != Shared.INVALID && (i >= selectedSlotIndex - 2 && i <= selectedSlotIndex + 2)) {
220 DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT];
221 if (displayItem != null) {
222 displayItem.clearScreennailImage();
225 if (selectedSlotIndex != Shared.INVALID) {
226 float camX = camera.mLookAtX * camera.mScale;
227 int centerIndexInDrawnArray = (selectedSlotIndex - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT;
228 if (centerIndexInDrawnArray < 0 || centerIndexInDrawnArray >= displayItems.length) {
231 DisplayItem centerDisplayItem = displayItems[centerIndexInDrawnArray];
232 if (centerDisplayItem == null || centerDisplayItem.mItemRef.mId == Shared.INVALID) {
235 boolean focusItemTextureLoaded = false;
236 Texture centerTexture = centerDisplayItem.getScreennailImage(view.getContext());
237 if (centerTexture != null && centerTexture.isLoaded()) {
238 focusItemTextureLoaded = true;
240 float centerTranslateX = centerDisplayItem.mAnimatedPosition.x;
241 final boolean skipPrevious = centerTranslateX < camX;
243 gl.glEnable(GL11.GL_BLEND);
244 gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE);
245 float backupImageTheta = 0.0f;
246 for (int i = -1; i <= 1; ++i) {
247 if (slideshowMode && timeElapsedSinceView > 1.0f && i != 0)
249 float viewAspect = camera.mAspectRatio;
250 int selectedSlotToUse = selectedSlotIndex + i;
251 if (selectedSlotToUse >= 0 && selectedSlotToUse <= lastBufferedVisibleSlot) {
252 int indexInDrawnArray = (selectedSlotToUse - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT;
253 if (indexInDrawnArray < 0 || indexInDrawnArray >= displayItems.length) {
256 DisplayItem displayItem = displayItems[indexInDrawnArray];
257 MediaItem item = displayItem.mItemRef;
258 final Texture thumbnailTexture = displayItem.getThumbnailImage(view.getContext(), sThumbnailConfig);
259 Texture texture = displayItem.getScreennailImage(view.getContext());
260 if (isCameraZAnimating && (texture == null || !texture.isLoaded())) {
261 texture = thumbnailTexture;
262 mSelectedMixRatio.setValue(0f);
263 mSelectedMixRatio.animateValue(1f, 0.75f, view.getFrameTime());
265 Texture hiRes = (zoomValue != 1.0f && i == 0 && item.getMediaType() != MediaItem.MEDIA_TYPE_VIDEO) ? displayItem
266 .getHiResImage(view.getContext())
268 if (Gallery.PIXEL_DENSITY > 1.0f) {
272 displayItem.clearHiResImage();
275 if (!hiRes.isLoaded()) {
277 view.prime(hiRes, true);
282 final Texture fsTexture = texture;
283 if (texture == null || !texture.isLoaded()) {
284 if (Math.abs(centerTranslateX - camX) < 0.1f) {
285 if (focusItemTextureLoaded && i != 0) {
290 view.prime(texture, true);
293 texture = thumbnailTexture;
295 mSelectedMixRatio.setValue(0f);
296 mSelectedMixRatio.animateValue(1f, 0.75f, view.getFrameTime());
299 if (mCamera.isAnimating() || slideshowMode) {
300 if (!slideshowMode && skipPrevious && i == -1) {
303 if (!skipPrevious && i == 1) {
307 int theta = (int) displayItem.getImageTheta();
308 // If it is in slideshow mode, we draw the previous item in
309 // the next item's position.
310 if (slideshowMode && timeElapsedSinceView < 1.0f && timeElapsedSinceView != 0) {
312 int nextSlotToUse = selectedSlotToUse + 1;
313 if (nextSlotToUse >= 0 && nextSlotToUse <= lastBufferedVisibleSlot) {
314 int nextIndexInDrawnArray = (nextSlotToUse - firstBufferedVisibleSlot)
315 * GridLayer.MAX_ITEMS_PER_SLOT;
316 if (nextIndexInDrawnArray >= 0 && nextIndexInDrawnArray < displayItems.length) {
317 float currentImageTheta = displayItem.mAnimatedImageTheta;
318 displayItem = displayItems[nextIndexInDrawnArray];
319 backupImageTheta = displayItem.mAnimatedImageTheta;
320 displayItem.mAnimatedImageTheta = currentImageTheta;
321 view.setAlpha(1.0f - timeElapsedSinceView);
325 displayItem.mAnimatedImageTheta = backupImageTheta;
326 view.setAlpha(timeElapsedSinceView);
329 if (texture != null) {
330 int vboIndex = i + 1;
331 float alpha = view.getAlpha();
332 float selectedMixRatio = mSelectedMixRatio.getValue(view.getFrameTime());
333 if (selectedMixRatio != 1f) {
334 texture = thumbnailTexture;
335 view.setAlpha(alpha * (1.0f - selectedMixRatio));
337 GridQuad quad = GridDrawables.sFullscreenGrid[vboIndex];
338 float u = texture.getNormalizedWidth();
339 float v = texture.getNormalizedHeight();
340 float imageWidth = texture.getWidth();
341 float imageHeight = texture.getHeight();
342 boolean portrait = ((theta / 90) % 2 == 1);
344 viewAspect = 1.0f / viewAspect;
346 quad.resizeQuad(viewAspect, u, v, imageWidth, imageHeight);
348 drawDisplayItem(view, gl, displayItem, texture, PASS_FOCUS_CONTENT, null, 0.0f);
349 quad.unbindArrays(gl);
350 if (selectedMixRatio != 0.0f && selectedMixRatio != 1.0f) {
352 if (texture != null) {
353 float drawAlpha = selectedMixRatio;
354 view.setAlpha(alpha * drawAlpha);
355 u = texture.getNormalizedWidth();
356 v = texture.getNormalizedHeight();
357 imageWidth = texture.getWidth();
358 imageHeight = texture.getHeight();
359 quad.resizeQuad(viewAspect, u, v, imageWidth, imageHeight);
361 drawDisplayItem(view, gl, displayItem, fsTexture, PASS_FOCUS_CONTENT, null, 1.0f);
362 quad.unbindArrays(gl);
365 if (i == 0 || slideshowMode) {
366 mCurrentFocusItemWidth = quad.getWidth();
367 mCurrentFocusItemHeight = quad.getHeight();
369 // Swap these values.
370 float itemWidth = mCurrentFocusItemWidth;
371 mCurrentFocusItemWidth = mCurrentFocusItemHeight;
372 mCurrentFocusItemHeight = itemWidth;
375 view.setAlpha(alpha);
376 if (item.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO) {
377 // The play graphic overlay.
378 GridDrawables.sVideoGrid.bindArrays(gl);
379 drawDisplayItem(view, gl, displayItem, drawables.mTextureVideo, PASS_VIDEO_LABEL, null, 0);
380 GridDrawables.sVideoGrid.unbindArrays(gl);
388 public void drawBlendedComponents(RenderView view, GL11 gl, float alpha, int state, int hudMode, float stackMixRatio,
389 float gridMixRatio, MediaBucketList bucketList, boolean isFeedLoading) {
390 int firstBufferedVisibleSlot = mBufferedVisibleRange.begin;
391 int lastBufferedVisibleSlot = mBufferedVisibleRange.end;
392 int firstVisibleSlot = mVisibleRange.begin;
393 int lastVisibleSlot = mVisibleRange.end;
394 DisplayItem[] displayItems = mDisplayItems;
395 GridDrawables drawables = mDrawables;
397 // We draw the frames around the drawn items.
398 boolean currentFocusIsPressed = mCurrentFocusIsPressed;
399 if (state != GridLayer.STATE_FULL_SCREEN) {
400 GridDrawables.sFrame.bindArrays(gl);
401 Texture texturePlaceHolder = (state == GridLayer.STATE_GRID_VIEW) ? drawables.mTextureGridFrame
402 : drawables.mTextureFrame;
403 for (int i = firstBufferedVisibleSlot; i <= lastBufferedVisibleSlot; ++i) {
404 if (i < firstVisibleSlot || i > lastVisibleSlot) {
407 boolean slotIsAlive = false;
408 if (state != GridLayer.STATE_MEDIA_SETS && state != GridLayer.STATE_TIMELINE) {
409 for (int j = 0; j < GridLayer.MAX_DISPLAYED_ITEMS_PER_SLOT; ++j) {
410 DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT + j];
411 if (displayItem != null) {
412 slotIsAlive |= displayItem.mAlive;
416 DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT];
417 if (displayItem != null) {
418 drawDisplayItem(view, gl, displayItem, texturePlaceHolder, PASS_FRAME_PLACEHOLDER, null, 0);
423 Texture texturePressed = drawables.mTextureFramePressed;
424 Texture textureFocus = drawables.mTextureFrameFocus;
425 Texture textureGrid = drawables.mTextureGridFrame;
426 Texture texture = drawables.mTextureFrame;
428 int drawnCounter = mDrawnCounter;
429 DisplayItem[] itemsDrawn = mItemsDrawn;
430 if (texture != null) {
431 if (drawnCounter > 0) {
432 Arrays.sort(itemsDrawn, 0, drawnCounter, sDisplayItemComparator);
433 float timeElapsedSinceGridView = gridMixRatio;
434 float timeElapsedSinceStackView = stackMixRatio;
435 for (int i = drawnCounter - 1; i >= 0; --i) {
436 DisplayItem itemDrawn = itemsDrawn[i];
437 if (itemDrawn == null) {
440 boolean displayItemPresentInSelectedItems = bucketList.find(itemDrawn.mItemRef);
441 Texture previousTexture = (displayItemPresentInSelectedItems) ? texturePressed : texture;
442 Texture textureToUse = (itemDrawn.getHasFocus()) ? (currentFocusIsPressed ? texturePressed : textureFocus)
443 : ((displayItemPresentInSelectedItems) ? texturePressed : textureGrid);
444 float ratio = timeElapsedSinceGridView;
445 if (itemDrawn.mAlive) {
446 if (state != GridLayer.STATE_GRID_VIEW) {
447 previousTexture = (displayItemPresentInSelectedItems) ? texturePressed : texture;
448 textureToUse = (itemDrawn.getHasFocus()) ? (currentFocusIsPressed ? texturePressed : textureFocus)
450 if (timeElapsedSinceStackView == 1.0f) {
451 ratio = mFocusMixRatio;
453 ratio = timeElapsedSinceStackView;
454 previousTexture = textureGrid;
457 drawDisplayItem(view, gl, itemDrawn, textureToUse, PASS_FRAME, previousTexture, ratio);
462 GridDrawables.sFrame.unbindArrays(gl);
463 gl.glDepthFunc(GL10.GL_ALWAYS);
464 if (state == GridLayer.STATE_MEDIA_SETS || state == GridLayer.STATE_TIMELINE) {
465 DisplaySlot[] displaySlots = mDisplaySlots;
466 GridDrawables.sTextGrid.bindArrays(gl);
467 final float textOffsetY = 0.82f;
468 gl.glTranslatef(0.0f, -textOffsetY, 0.0f);
469 HashMap<String, StringTexture> stringTextureTable = GridDrawables.sStringTextureTable;
470 ReverseGeocoder reverseGeocoder = ((Gallery) view.getContext()).getReverseGeocoder();
472 boolean itemsPresent = false;
474 for (int i = firstBufferedVisibleSlot; i <= lastBufferedVisibleSlot; ++i) {
476 DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT];
477 if (displayItem != null) {
478 DisplaySlot displaySlot = displaySlots[i - firstBufferedVisibleSlot];
479 Texture textureString = displaySlot.getTitleImage(stringTextureTable);
480 view.loadTexture(textureString);
481 if (textureString != null) {
482 if (i < firstVisibleSlot || i > lastVisibleSlot) {
485 drawDisplayItem(view, gl, displayItem, textureString, PASS_TEXT_LABEL, null, 0);
491 if (!itemsPresent && !isFeedLoading) {
492 // Draw the no items texture.
493 int wWidth = view.getWidth();
494 int wHeight = view.getHeight();
496 // Size this to be 40 pxls less than screen width
497 mNoItemsTexture.mWidth = wWidth - 40;
499 int x = (int) Math.floor((wWidth / 2) - (mNoItemsTexture.getWidth() / 2));
500 int y = (int) Math.floor((wHeight / 2) - (mNoItemsTexture.getHeight() / 2));
501 view.draw2D(mNoItemsTexture, x, y);
504 float yLocOffset = 0.2f;
505 gl.glTranslatef(0.0f, -yLocOffset, 0.0f);
506 for (int i = firstBufferedVisibleSlot; i <= lastBufferedVisibleSlot; ++i) {
507 DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT];
508 if (displayItem != null) {
509 DisplaySlot displaySlot = displaySlots[i - firstBufferedVisibleSlot];
510 StringTexture textureString = displaySlot.getLocationImage(reverseGeocoder, stringTextureTable);
511 if (textureString != null) {
512 drawDisplayItem(view, gl, displayItem, textureString, PASS_TEXT_LABEL, null, 0);
516 if (state == GridLayer.STATE_TIMELINE) {
517 GridDrawables.sLocationGrid.bindArrays(gl);
518 Texture locationTexture = drawables.mTextureLocation;
519 final float yLocationLabelOffset = 0.19f;
520 for (int i = firstBufferedVisibleSlot; i <= lastBufferedVisibleSlot; ++i) {
521 DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT];
522 if (displayItem != null) {
523 if (displayItem.mAlive == true) {
524 DisplaySlot displaySlot = displaySlots[i - firstBufferedVisibleSlot];
525 if (displaySlot.hasValidLocation()) {
526 StringTexture textureString = displaySlot.getLocationImage(reverseGeocoder, stringTextureTable);
527 float textWidth = (textureString != null) ? textureString.computeTextWidth() : 0;
528 textWidth *= (mCamera.mOneByScale * 0.5f);
529 if (textWidth == 0.0f) {
533 gl.glTranslatef(textWidth, -yLocationLabelOffset, 0.0f);
534 drawDisplayItem(view, gl, displayItem, locationTexture, PASS_LOCATION_LABEL, null, 0);
535 gl.glTranslatef(-textWidth, yLocationLabelOffset, 0.0f);
541 GridDrawables.sLocationGrid.unbindArrays(gl);
542 } else if (state == GridLayer.STATE_MEDIA_SETS && stackMixRatio > 0.0f) {
543 GridDrawables.sSourceIconGrid.bindArrays(gl);
544 Texture transparentTexture = drawables.mTextureTransparent;
545 for (int i = firstBufferedVisibleSlot; i <= lastBufferedVisibleSlot; ++i) {
546 DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT];
547 if (displayItem != null) {
548 if (displayItem.mAlive == true) {
549 DisplaySlot displaySlot = displaySlots[i - firstBufferedVisibleSlot];
550 Texture locationTexture = view.getResource(drawables
551 .getIconForSet(displaySlot.getMediaSet(), false), false);
553 // Draw the icon at 0.85 alpha over the top item in the stack.
554 gl.glTranslatef(0.24f, 0.5f, 0);
555 drawDisplayItem(view, gl, displayItem, locationTexture, PASS_MEDIASET_SOURCE_LABEL,
556 transparentTexture, 0.85f);
557 gl.glTranslatef(-0.24f, -0.5f, 0);
561 GridDrawables.sSourceIconGrid.unbindArrays(gl);
563 gl.glTranslatef(0.0f, yLocOffset, 0.0f);
564 gl.glTranslatef(0.0f, textOffsetY, 0.0f);
565 GridDrawables.sTextGrid.unbindArrays(gl);
567 if (hudMode == HudLayer.MODE_SELECT && state != GridLayer.STATE_FULL_SCREEN) {
568 Texture textureSelectedOn = drawables.mTextureCheckmarkOn;
569 Texture textureSelectedOff = drawables.mTextureCheckmarkOff;
570 view.prime(textureSelectedOn, true);
571 view.prime(textureSelectedOff, true);
572 GridDrawables.sSelectedGrid.bindArrays(gl);
573 for (int i = firstBufferedVisibleSlot; i <= lastBufferedVisibleSlot; ++i) {
574 DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT];
575 if (displayItem != null) {
576 Texture textureToUse = bucketList.find(displayItem.mItemRef) ? textureSelectedOn : textureSelectedOff;
577 drawDisplayItem(view, gl, displayItem, textureToUse, PASS_SELECTION_LABEL, null, 0);
580 GridDrawables.sSelectedGrid.unbindArrays(gl);
582 GridDrawables.sVideoGrid.bindArrays(gl);
583 Texture videoTexture = drawables.mTextureVideo;
584 for (int i = firstBufferedVisibleSlot; i <= lastBufferedVisibleSlot; ++i) {
585 DisplayItem displayItem = displayItems[(i - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT];
586 if (displayItem != null && displayItem.mAlive) {
587 if (displayItem.mItemRef.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO) {
588 drawDisplayItem(view, gl, displayItem, videoTexture, PASS_VIDEO_LABEL, null, 0);
592 GridDrawables.sVideoGrid.unbindArrays(gl);
593 gl.glDepthFunc(GL10.GL_LEQUAL);
597 private void drawDisplayItem(RenderView view, GL11 gl, DisplayItem displayItem, Texture texture, int pass,
598 Texture previousTexture, float mixRatio) {
599 GridCamera camera = mCamera;
600 Vector3f animatedPosition = displayItem.mAnimatedPosition;
601 float translateXf = animatedPosition.x * camera.mOneByScale;
602 float translateYf = animatedPosition.y * camera.mOneByScale;
603 float translateZf = -animatedPosition.z;
604 int stackId = displayItem.getStackIndex();
605 if (pass == PASS_PLACEHOLDER || pass == PASS_FRAME_PLACEHOLDER) {
606 translateZf = -0.04f;
608 if (pass == PASS_FRAME)
609 translateZf += 0.02f;
610 if ((pass == PASS_TEXT_LABEL || pass == PASS_LOCATION_LABEL || pass == PASS_SELECTION_LABEL) && !displayItem.isAlive()) {
613 if (pass == PASS_TEXT_LABEL) {
617 boolean usingMixedTextures = false;
618 boolean bind = false;
619 if ((pass != PASS_THUMBNAIL_CONTENT)
620 || (stackId < GridLayer.MAX_DISPLAYED_ITEMS_PER_SLOT && texture.isLoaded() && (previousTexture == null || previousTexture
622 if (mixRatio == 1.0f || previousTexture == null || texture == previousTexture) {
623 bind = view.bind(texture);
624 } else if (mixRatio != 0.0f) {
625 if (!texture.isLoaded() || !previousTexture.isLoaded()) {
626 // Submit the previous texture to the load queue
627 view.bind(previousTexture);
628 bind = view.bind(texture);
630 usingMixedTextures = true;
631 bind = view.bindMixed(previousTexture, texture, mixRatio);
634 bind = view.bind(previousTexture);
636 } else if (stackId >= GridLayer.MAX_DISPLAYED_ITEMS_PER_SLOT && pass == PASS_THUMBNAIL_CONTENT) {
637 mDisplayList.setAlive(displayItem, true);
639 if (!texture.isLoaded() || !bind) {
640 if (pass == PASS_THUMBNAIL_CONTENT) {
641 if (previousTexture != null && previousTexture.isLoaded() && translateZf == 0.0f) {
642 translateZf = -0.08f;
643 bind |= view.bind(previousTexture);
652 if (pass == PASS_THUMBNAIL_CONTENT || pass == PASS_FOCUS_CONTENT) {
653 if (!displayItem.mAlive) {
654 mDisplayList.setAlive(displayItem, true);
658 gl.glTranslatef(-translateXf, -translateYf, -translateZf);
659 float theta = (pass == PASS_FOCUS_CONTENT) ? displayItem.mAnimatedImageTheta + displayItem.mAnimatedTheta
660 : displayItem.mAnimatedTheta;
662 gl.glRotatef(theta, 0.0f, 0.0f, 1.0f);
664 float orientation = 0.0f;
665 if (pass == PASS_THUMBNAIL_CONTENT && displayItem.mAnimatedImageTheta != 0.0f) {
666 orientation = displayItem.mAnimatedImageTheta;
668 if (pass == PASS_FRAME || pass == PASS_FRAME_PLACEHOLDER) {
669 GridQuadFrame.draw(gl);
671 GridQuad.draw(gl, orientation);
674 gl.glRotatef(-theta, 0.0f, 0.0f, 1.0f);
676 gl.glTranslatef(translateXf, translateYf, translateZf);
677 if (usingMixedTextures) {