• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.replica.replicaisland;
18 
19 
20 /**
21  * Manages a double-buffered queue of renderable objects.  The game thread submits drawable objects
22  * to the the active render queue while the render thread consumes drawables from the alternate
23  * queue.  When both threads complete a frame the queues are swapped.  Note that this class can
24  * manage any number (>=2) of render queues, but increasing the number over two means that the game
25  * logic will be running significantly ahead of the rendering thread, which may make the user feel
26  * that the controls are "loose."
27  */
28 public class RenderSystem extends BaseObject {
29     private static final int TEXTURE_SORT_BUCKET_SIZE = 1000;
30     private RenderElementPool mElementPool;
31     private ObjectManager[] mRenderQueues;
32     private int mQueueIndex;
33 
34     private final static int DRAW_QUEUE_COUNT = 2;
35     private final static int MAX_RENDER_OBJECTS_PER_FRAME = 384;
36     private final static int MAX_RENDER_OBJECTS = MAX_RENDER_OBJECTS_PER_FRAME * DRAW_QUEUE_COUNT;
37 
RenderSystem()38     public RenderSystem() {
39         super();
40         mElementPool = new RenderElementPool(MAX_RENDER_OBJECTS);
41         mRenderQueues = new ObjectManager[DRAW_QUEUE_COUNT];
42         for (int x = 0; x < DRAW_QUEUE_COUNT; x++) {
43             mRenderQueues[x] = new PhasedObjectManager(MAX_RENDER_OBJECTS_PER_FRAME);
44         }
45         mQueueIndex = 0;
46     }
47 
48     @Override
reset()49     public void reset() {
50 
51     }
52 
scheduleForDraw(DrawableObject object, Vector2 position, int priority, boolean cameraRelative)53     public void scheduleForDraw(DrawableObject object, Vector2 position, int priority, boolean cameraRelative) {
54         RenderElement element = mElementPool.allocate();
55         if (element != null) {
56             element.set(object, position, priority, cameraRelative);
57             mRenderQueues[mQueueIndex].add(element);
58         }
59     }
60 
clearQueue(FixedSizeArray<BaseObject> objects)61     private void clearQueue(FixedSizeArray<BaseObject> objects) {
62         final int count = objects.getCount();
63         final Object[] objectArray = objects.getArray();
64         final RenderElementPool elementPool = mElementPool;
65         for (int i = count - 1; i >= 0; i--) {
66             RenderElement element = (RenderElement)objectArray[i];
67             elementPool.release(element);
68             objects.removeLast();
69         }
70 
71     }
72 
swap(GameRenderer renderer, float cameraX, float cameraY)73     public void swap(GameRenderer renderer, float cameraX, float cameraY) {
74         mRenderQueues[mQueueIndex].commitUpdates();
75 
76         // This code will block if the previous queue is still being executed.
77         renderer.setDrawQueue(mRenderQueues[mQueueIndex], cameraX, cameraY);
78 
79         final int lastQueue = (mQueueIndex == 0) ? DRAW_QUEUE_COUNT - 1 : mQueueIndex - 1;
80 
81         // Clear the old queue.
82         FixedSizeArray<BaseObject> objects = mRenderQueues[lastQueue].getObjects();
83         clearQueue(objects);
84 
85         mQueueIndex = (mQueueIndex + 1) % DRAW_QUEUE_COUNT;
86     }
87 
88     /* Empties all draw queues and disconnects the game thread from the renderer. */
emptyQueues(GameRenderer renderer)89     public void emptyQueues(GameRenderer renderer) {
90         renderer.setDrawQueue(null, 0.0f, 0.0f);
91         for (int x = 0; x < DRAW_QUEUE_COUNT; x++) {
92             mRenderQueues[x].commitUpdates();
93             FixedSizeArray<BaseObject> objects = mRenderQueues[x].getObjects();
94             clearQueue(objects);
95 
96         }
97     }
98 
99     public class RenderElement extends PhasedObject {
RenderElement()100         public RenderElement() {
101             super();
102         }
103 
set(DrawableObject drawable, Vector2 position, int priority, boolean isCameraRelative)104         public void set(DrawableObject drawable, Vector2 position, int priority, boolean isCameraRelative) {
105             mDrawable = drawable;
106             x = position.x;
107             y = position.y;
108             cameraRelative = isCameraRelative;
109             final int sortBucket = priority * TEXTURE_SORT_BUCKET_SIZE;
110             int sortOffset = 0;
111             if (drawable != null) {
112                 Texture tex = drawable.getTexture();
113                 if (tex != null) {
114                     sortOffset = (tex.resource % TEXTURE_SORT_BUCKET_SIZE) * Utils.sign(priority);
115                 }
116             }
117             setPhase(sortBucket + sortOffset);
118         }
119 
reset()120         public void reset() {
121             mDrawable = null;
122             x = 0.0f;
123             y = 0.0f;
124             cameraRelative = false;
125         }
126 
127         public DrawableObject mDrawable;
128         public float x;
129         public float y;
130         public boolean cameraRelative;
131     }
132 
133     protected class RenderElementPool extends TObjectPool<RenderElement> {
134 
RenderElementPool(int max)135         RenderElementPool(int max) {
136             super(max);
137         }
138 
139         @Override
release(Object element)140         public void release(Object element) {
141             RenderElement renderable = (RenderElement)element;
142             // if this drawable came out of a pool, make sure it is returned to that pool.
143             final ObjectPool pool = renderable.mDrawable.getParentPool();
144             if (pool != null) {
145             	pool.release(renderable.mDrawable);
146             }
147             // reset on release
148             renderable.reset();
149             super.release(element);
150         }
151 
152         @Override
fill()153         protected void fill() {
154             for (int x = 0; x < getSize(); x++) {
155                 getAvailable().add(new RenderElement());
156             }
157         }
158     }
159 }
160