blob: 2c9f1d97543ae12592595d65cde668f332f8f084 [file] [log] [blame]
John Reckcec24ae2013-11-05 13:27:50 -08001/*
2 * Copyright (C) 2013 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
17package android.view;
18
19import android.graphics.Rect;
20import android.graphics.SurfaceTexture;
John Reckcec24ae2013-11-05 13:27:50 -080021import android.os.SystemClock;
22import android.os.Trace;
John Reckcec24ae2013-11-05 13:27:50 -080023import android.view.Surface.OutOfResourcesException;
24import android.view.View.AttachInfo;
25
26import java.io.PrintWriter;
John Reckcec24ae2013-11-05 13:27:50 -080027
28/**
29 * Hardware renderer that proxies the rendering to a render thread. Most calls
John Reck4f02bf42014-01-03 18:09:17 -080030 * are currently synchronous.
31 * TODO: Make draw() async.
32 * TODO: Figure out how to share the DisplayList between two threads (global lock?)
John Reckcec24ae2013-11-05 13:27:50 -080033 *
34 * The UI thread can block on the RenderThread, but RenderThread must never
35 * block on the UI thread.
36 *
John Reck4f02bf42014-01-03 18:09:17 -080037 * ThreadedRenderer creates an instance of RenderProxy. RenderProxy in turn creates
38 * and manages a CanvasContext on the RenderThread. The CanvasContext is fully managed
39 * by the lifecycle of the RenderProxy.
40 *
John Reckcec24ae2013-11-05 13:27:50 -080041 * Note that although currently the EGL context & surfaces are created & managed
42 * by the render thread, the goal is to move that into a shared structure that can
43 * be managed by both threads. EGLSurface creation & deletion should ideally be
44 * done on the UI thread and not the RenderThread to avoid stalling the
45 * RenderThread with surface buffer allocation.
46 *
47 * @hide
48 */
49public class ThreadedRenderer extends HardwareRenderer {
50 private static final String LOGTAG = "ThreadedRenderer";
51
John Reck4f02bf42014-01-03 18:09:17 -080052 private static final Rect NULL_RECT = new Rect(-1, -1, -1, -1);
John Reckcec24ae2013-11-05 13:27:50 -080053
John Reckcec24ae2013-11-05 13:27:50 -080054 private int mWidth, mHeight;
John Reck4f02bf42014-01-03 18:09:17 -080055 private long mNativeProxy;
John Reckcec24ae2013-11-05 13:27:50 -080056
John Reck3dfe19f2013-12-13 14:25:19 -080057 ThreadedRenderer(boolean translucent) {
John Reck4f02bf42014-01-03 18:09:17 -080058 mNativeProxy = nCreateProxy(translucent);
59 setEnabled(mNativeProxy != 0);
John Reckcec24ae2013-11-05 13:27:50 -080060 }
61
62 @Override
63 void destroy(boolean full) {
John Reck4f02bf42014-01-03 18:09:17 -080064 nDestroyCanvas(mNativeProxy);
John Reckcec24ae2013-11-05 13:27:50 -080065 }
66
67 @Override
68 boolean initialize(Surface surface) throws OutOfResourcesException {
John Reck4f02bf42014-01-03 18:09:17 -080069 return nInitialize(mNativeProxy, surface);
John Reckcec24ae2013-11-05 13:27:50 -080070 }
71
72 @Override
73 void updateSurface(Surface surface) throws OutOfResourcesException {
John Reck4f02bf42014-01-03 18:09:17 -080074 nUpdateSurface(mNativeProxy, surface);
John Reckcec24ae2013-11-05 13:27:50 -080075 }
76
77 @Override
78 void destroyLayers(View view) {
79 throw new NoSuchMethodError();
80 }
81
82 @Override
83 void destroyHardwareResources(View view) {
John Reck4f02bf42014-01-03 18:09:17 -080084 // TODO: canvas.clearLayerUpdates()
85 destroyResources(view);
86 // TODO: GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
87 }
88
89 private static void destroyResources(View view) {
90 view.destroyHardwareResources();
91
92 if (view instanceof ViewGroup) {
93 ViewGroup group = (ViewGroup) view;
94
95 int count = group.getChildCount();
96 for (int i = 0; i < count; i++) {
97 destroyResources(group.getChildAt(i));
98 }
99 }
John Reckcec24ae2013-11-05 13:27:50 -0800100 }
101
102 @Override
103 void invalidate(Surface surface) {
John Reck4f02bf42014-01-03 18:09:17 -0800104 updateSurface(surface);
John Reckcec24ae2013-11-05 13:27:50 -0800105 }
106
107 @Override
108 boolean validate() {
109 // TODO Remove users of this API
110 return false;
111 }
112
113 @Override
114 boolean safelyRun(Runnable action) {
John Reck4f02bf42014-01-03 18:09:17 -0800115 // TODO:
116 return false;
John Reckcec24ae2013-11-05 13:27:50 -0800117 }
118
119 @Override
120 void setup(int width, int height) {
121 mWidth = width;
122 mHeight = height;
John Reck4f02bf42014-01-03 18:09:17 -0800123 nSetup(mNativeProxy, width, height);
John Reckcec24ae2013-11-05 13:27:50 -0800124 }
125
126 @Override
127 int getWidth() {
128 return mWidth;
129 }
130
131 @Override
132 int getHeight() {
133 return mHeight;
134 }
135
136 @Override
137 void dumpGfxInfo(PrintWriter pw) {
138 // TODO Auto-generated method stub
139 }
140
141 @Override
142 long getFrameCount() {
143 // TODO Auto-generated method stub
144 return 0;
145 }
146
147 @Override
148 boolean loadSystemProperties() {
John Reck4f02bf42014-01-03 18:09:17 -0800149 return false;
John Reckcec24ae2013-11-05 13:27:50 -0800150 }
151
152 @Override
153 void pushLayerUpdate(HardwareLayer layer) {
154 throw new NoSuchMethodError();
155 }
156
157 @Override
158 void cancelLayerUpdate(HardwareLayer layer) {
159 throw new NoSuchMethodError();
160 }
161
162 @Override
163 void flushLayerUpdates() {
164 throw new NoSuchMethodError();
165 }
166
John Reckcec24ae2013-11-05 13:27:50 -0800167 /**
168 * TODO: Remove
169 * Temporary hack to allow RenderThreadTest prototype app to trigger
170 * replaying a DisplayList after modifying the displaylist properties
171 *
172 * @hide */
173 public void repeatLastDraw() {
John Reckcec24ae2013-11-05 13:27:50 -0800174 }
175
176 @Override
177 void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks, Rect dirty) {
John Reckcec24ae2013-11-05 13:27:50 -0800178 attachInfo.mIgnoreDirtyState = true;
179 attachInfo.mDrawingTime = SystemClock.uptimeMillis();
180 view.mPrivateFlags |= View.PFLAG_DRAWN;
181
182 view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
183 == View.PFLAG_INVALIDATED;
184 view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
185
186 Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
187 DisplayList displayList = view.getDisplayList();
188 Trace.traceEnd(Trace.TRACE_TAG_VIEW);
189
190 view.mRecreateDisplayList = false;
191
John Reck4f02bf42014-01-03 18:09:17 -0800192 if (dirty == null) {
193 dirty = NULL_RECT;
194 }
195 nDrawDisplayList(mNativeProxy, displayList.getNativeDisplayList(),
196 dirty.left, dirty.top, dirty.right, dirty.bottom);
John Reckcec24ae2013-11-05 13:27:50 -0800197 }
198
199 @Override
200 HardwareLayer createHardwareLayer(boolean isOpaque) {
201 throw new NoSuchMethodError();
202 }
203
204 @Override
205 HardwareLayer createHardwareLayer(int width, int height, boolean isOpaque) {
206 throw new NoSuchMethodError();
207 }
208
209 @Override
210 SurfaceTexture createSurfaceTexture(HardwareLayer layer) {
211 throw new NoSuchMethodError();
212 }
213
214 @Override
215 void setSurfaceTexture(HardwareLayer layer, SurfaceTexture surfaceTexture) {
216 throw new NoSuchMethodError();
217 }
218
219 @Override
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000220 void detachFunctor(long functor) {
John Reck4f02bf42014-01-03 18:09:17 -0800221 nDetachFunctor(mNativeProxy, functor);
John Reckcec24ae2013-11-05 13:27:50 -0800222 }
223
224 @Override
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000225 void attachFunctor(AttachInfo attachInfo, long functor) {
John Reck4f02bf42014-01-03 18:09:17 -0800226 nAttachFunctor(mNativeProxy, functor);
John Reckcec24ae2013-11-05 13:27:50 -0800227 }
228
229 @Override
230 void setName(String name) {
John Reckcec24ae2013-11-05 13:27:50 -0800231 }
232
John Reck4f02bf42014-01-03 18:09:17 -0800233 @Override
234 protected void finalize() throws Throwable {
235 try {
236 nDeleteProxy(mNativeProxy);
237 } finally {
238 super.finalize();
John Reckcec24ae2013-11-05 13:27:50 -0800239 }
240 }
241
242 /** @hide */
243 public static native void postToRenderThread(Runnable runnable);
John Reck4f02bf42014-01-03 18:09:17 -0800244
245 private static native long nCreateProxy(boolean translucent);
246 private static native void nDeleteProxy(long nativeProxy);
247
248 private static native boolean nInitialize(long nativeProxy, Surface window);
249 private static native void nUpdateSurface(long nativeProxy, Surface window);
250 private static native void nSetup(long nativeProxy, int width, int height);
251 private static native void nDrawDisplayList(long nativeProxy, long displayList,
252 int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom);
253 private static native void nDestroyCanvas(long nativeProxy);
254
255 private static native void nAttachFunctor(long nativeProxy, long functor);
256 private static native void nDetachFunctor(long nativeProxy, long functor);
John Reckcec24ae2013-11-05 13:27:50 -0800257}