blob: 096093caff5151dfd2c1015eddb4b1104529a110 [file] [log] [blame]
John Reck4f02bf42014-01-03 18:09:17 -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
John Reck4f02bf42014-01-03 18:09:17 -080017#include "RenderProxy.h"
18
John Reckba6adf62015-02-19 14:36:50 -080019#include "DeferredLayerUpdater.h"
20#include "DisplayList.h"
21#include "LayerRenderer.h"
John Reck10dd0582016-03-31 16:36:16 -070022#include "Readback.h"
John Reckba6adf62015-02-19 14:36:50 -080023#include "Rect.h"
24#include "renderthread/CanvasContext.h"
25#include "renderthread/RenderTask.h"
26#include "renderthread/RenderThread.h"
27#include "utils/Macros.h"
John Reck4f02bf42014-01-03 18:09:17 -080028
29namespace android {
30namespace uirenderer {
31namespace renderthread {
32
33#define ARGS(method) method ## Args
34
John Reck19b6bcf2014-02-14 20:03:38 -080035#define CREATE_BRIDGE0(name) CREATE_BRIDGE(name,,,,,,,,)
John Reck4f02bf42014-01-03 18:09:17 -080036#define CREATE_BRIDGE1(name, a1) CREATE_BRIDGE(name, a1,,,,,,,)
37#define CREATE_BRIDGE2(name, a1, a2) CREATE_BRIDGE(name, a1,a2,,,,,,)
38#define CREATE_BRIDGE3(name, a1, a2, a3) CREATE_BRIDGE(name, a1,a2,a3,,,,,)
39#define CREATE_BRIDGE4(name, a1, a2, a3, a4) CREATE_BRIDGE(name, a1,a2,a3,a4,,,,)
Chris Craik797b95b2014-05-20 18:10:25 -070040#define CREATE_BRIDGE5(name, a1, a2, a3, a4, a5) CREATE_BRIDGE(name, a1,a2,a3,a4,a5,,,)
Chris Craik058fc642014-07-23 18:19:28 -070041#define CREATE_BRIDGE6(name, a1, a2, a3, a4, a5, a6) CREATE_BRIDGE(name, a1,a2,a3,a4,a5,a6,,)
42#define CREATE_BRIDGE7(name, a1, a2, a3, a4, a5, a6, a7) CREATE_BRIDGE(name, a1,a2,a3,a4,a5,a6,a7,)
John Reck4f02bf42014-01-03 18:09:17 -080043#define CREATE_BRIDGE(name, a1, a2, a3, a4, a5, a6, a7, a8) \
44 typedef struct { \
45 a1; a2; a3; a4; a5; a6; a7; a8; \
46 } ARGS(name); \
47 static void* Bridge_ ## name(ARGS(name)* args)
48
49#define SETUP_TASK(method) \
50 LOG_ALWAYS_FATAL_IF( METHOD_INVOKE_PAYLOAD_SIZE < sizeof(ARGS(method)), \
Mark Salyzyn546f3532014-06-10 12:29:14 -070051 "METHOD_INVOKE_PAYLOAD_SIZE %zu is smaller than sizeof(" #method "Args) %zu", \
John Reck4f02bf42014-01-03 18:09:17 -080052 METHOD_INVOKE_PAYLOAD_SIZE, sizeof(ARGS(method))); \
John Recke2c45522014-04-07 17:31:44 -070053 MethodInvokeRenderTask* task = new MethodInvokeRenderTask((RunnableMethod) Bridge_ ## method); \
John Reck4f02bf42014-01-03 18:09:17 -080054 ARGS(method) *args = (ARGS(method) *) task->payload()
55
John Reck119907c2014-08-14 09:02:01 -070056CREATE_BRIDGE4(createContext, RenderThread* thread, bool translucent,
57 RenderNode* rootRenderNode, IContextFactory* contextFactory) {
58 return new CanvasContext(*args->thread, args->translucent,
59 args->rootRenderNode, args->contextFactory);
John Reck4f02bf42014-01-03 18:09:17 -080060}
61
John Reck119907c2014-08-14 09:02:01 -070062RenderProxy::RenderProxy(bool translucent, RenderNode* rootRenderNode, IContextFactory* contextFactory)
John Reck4f02bf42014-01-03 18:09:17 -080063 : mRenderThread(RenderThread::getInstance())
Chris Craikd41c4d82015-01-05 15:51:13 -080064 , mContext(nullptr) {
John Reck4f02bf42014-01-03 18:09:17 -080065 SETUP_TASK(createContext);
66 args->translucent = translucent;
John Recke45b1fd2014-04-15 09:50:16 -070067 args->rootRenderNode = rootRenderNode;
John Reck3b202512014-06-23 13:13:08 -070068 args->thread = &mRenderThread;
John Reck119907c2014-08-14 09:02:01 -070069 args->contextFactory = contextFactory;
John Reck4f02bf42014-01-03 18:09:17 -080070 mContext = (CanvasContext*) postAndWait(task);
Skuhneea7a7fb2015-08-28 07:10:31 -070071 mDrawFrameTask.setContext(&mRenderThread, mContext, rootRenderNode);
John Reck4f02bf42014-01-03 18:09:17 -080072}
73
74RenderProxy::~RenderProxy() {
75 destroyContext();
76}
77
78CREATE_BRIDGE1(destroyContext, CanvasContext* context) {
79 delete args->context;
Chris Craikd41c4d82015-01-05 15:51:13 -080080 return nullptr;
John Reck4f02bf42014-01-03 18:09:17 -080081}
82
83void RenderProxy::destroyContext() {
84 if (mContext) {
85 SETUP_TASK(destroyContext);
86 args->context = mContext;
Chris Craikd41c4d82015-01-05 15:51:13 -080087 mContext = nullptr;
Skuhneea7a7fb2015-08-28 07:10:31 -070088 mDrawFrameTask.setContext(nullptr, nullptr, nullptr);
John Reck668f0e32014-03-26 15:10:40 -070089 // This is also a fence as we need to be certain that there are no
90 // outstanding mDrawFrame tasks posted before it is destroyed
91 postAndWait(task);
John Reck4f02bf42014-01-03 18:09:17 -080092 }
93}
94
John Reck1125d1f2014-10-23 11:02:19 -070095CREATE_BRIDGE2(setSwapBehavior, CanvasContext* context, SwapBehavior swapBehavior) {
96 args->context->setSwapBehavior(args->swapBehavior);
Chris Craikd41c4d82015-01-05 15:51:13 -080097 return nullptr;
John Reck1125d1f2014-10-23 11:02:19 -070098}
99
100void RenderProxy::setSwapBehavior(SwapBehavior swapBehavior) {
101 SETUP_TASK(setSwapBehavior);
102 args->context = mContext;
103 args->swapBehavior = swapBehavior;
104 post(task);
105}
106
John Reckfe5e7b72014-05-23 17:42:28 -0700107CREATE_BRIDGE1(loadSystemProperties, CanvasContext* context) {
John Recke4280ba2014-05-05 16:39:37 -0700108 bool needsRedraw = false;
109 if (Caches::hasInstance()) {
Chris Craik2507c342015-05-04 14:36:49 -0700110 needsRedraw = Properties::load();
John Recke4280ba2014-05-05 16:39:37 -0700111 }
Chris Craik2507c342015-05-04 14:36:49 -0700112 if (args->context->profiler().consumeProperties()) {
John Reckfe5e7b72014-05-23 17:42:28 -0700113 needsRedraw = true;
114 }
John Recke4280ba2014-05-05 16:39:37 -0700115 return (void*) needsRedraw;
116}
117
118bool RenderProxy::loadSystemProperties() {
119 SETUP_TASK(loadSystemProperties);
John Reckfe5e7b72014-05-23 17:42:28 -0700120 args->context = mContext;
John Recke4280ba2014-05-05 16:39:37 -0700121 return (bool) postAndWait(task);
122}
123
John Reckb36016c2015-03-11 08:50:53 -0700124CREATE_BRIDGE2(setName, CanvasContext* context, const char* name) {
125 args->context->setName(std::string(args->name));
126 return nullptr;
127}
128
129void RenderProxy::setName(const char* name) {
130 SETUP_TASK(setName);
131 args->context = mContext;
132 args->name = name;
Chris Craik2507c342015-05-04 14:36:49 -0700133 postAndWait(task); // block since name/value pointers owned by caller
John Reckb36016c2015-03-11 08:50:53 -0700134}
135
John Reckf6481082016-02-02 15:18:23 -0800136CREATE_BRIDGE2(initialize, CanvasContext* context, Surface* surface) {
137 args->context->initialize(args->surface);
Thomas Buhot0bcd0cb2015-12-04 12:18:03 +0100138 return nullptr;
John Reck4f02bf42014-01-03 18:09:17 -0800139}
140
John Reckf6481082016-02-02 15:18:23 -0800141void RenderProxy::initialize(const sp<Surface>& surface) {
John Reck4f02bf42014-01-03 18:09:17 -0800142 SETUP_TASK(initialize);
143 args->context = mContext;
John Reckf6481082016-02-02 15:18:23 -0800144 args->surface = surface.get();
Thomas Buhot0bcd0cb2015-12-04 12:18:03 +0100145 post(task);
John Reck4f02bf42014-01-03 18:09:17 -0800146}
147
John Reckf6481082016-02-02 15:18:23 -0800148CREATE_BRIDGE2(updateSurface, CanvasContext* context, Surface* surface) {
149 args->context->updateSurface(args->surface);
Chris Craikd41c4d82015-01-05 15:51:13 -0800150 return nullptr;
John Reck4f02bf42014-01-03 18:09:17 -0800151}
152
John Reckf6481082016-02-02 15:18:23 -0800153void RenderProxy::updateSurface(const sp<Surface>& surface) {
John Reck4f02bf42014-01-03 18:09:17 -0800154 SETUP_TASK(updateSurface);
155 args->context = mContext;
John Reckf6481082016-02-02 15:18:23 -0800156 args->surface = surface.get();
John Reckf7d9c1d2014-04-09 10:01:03 -0700157 postAndWait(task);
158}
159
John Reckf6481082016-02-02 15:18:23 -0800160CREATE_BRIDGE2(pauseSurface, CanvasContext* context, Surface* surface) {
161 return (void*) args->context->pauseSurface(args->surface);
John Reckf7d9c1d2014-04-09 10:01:03 -0700162}
163
John Reckf6481082016-02-02 15:18:23 -0800164bool RenderProxy::pauseSurface(const sp<Surface>& surface) {
John Reckf7d9c1d2014-04-09 10:01:03 -0700165 SETUP_TASK(pauseSurface);
166 args->context = mContext;
John Reckf6481082016-02-02 15:18:23 -0800167 args->surface = surface.get();
John Reck01a5ea32014-12-03 13:01:07 -0800168 return (bool) postAndWait(task);
John Reck4f02bf42014-01-03 18:09:17 -0800169}
170
Alan Viverette50210d92015-05-14 18:05:36 -0700171CREATE_BRIDGE6(setup, CanvasContext* context, int width, int height,
172 float lightRadius, uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
173 args->context->setup(args->width, args->height, args->lightRadius,
Chris Craik058fc642014-07-23 18:19:28 -0700174 args->ambientShadowAlpha, args->spotShadowAlpha);
Chris Craikd41c4d82015-01-05 15:51:13 -0800175 return nullptr;
John Reck4f02bf42014-01-03 18:09:17 -0800176}
177
Alan Viverette50210d92015-05-14 18:05:36 -0700178void RenderProxy::setup(int width, int height, float lightRadius,
John Reckb36016c2015-03-11 08:50:53 -0700179 uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
John Reck4f02bf42014-01-03 18:09:17 -0800180 SETUP_TASK(setup);
181 args->context = mContext;
182 args->width = width;
183 args->height = height;
Chris Craik797b95b2014-05-20 18:10:25 -0700184 args->lightRadius = lightRadius;
Chris Craik058fc642014-07-23 18:19:28 -0700185 args->ambientShadowAlpha = ambientShadowAlpha;
186 args->spotShadowAlpha = spotShadowAlpha;
John Reck4f02bf42014-01-03 18:09:17 -0800187 post(task);
188}
189
Alan Viverette50210d92015-05-14 18:05:36 -0700190CREATE_BRIDGE2(setLightCenter, CanvasContext* context, Vector3 lightCenter) {
191 args->context->setLightCenter(args->lightCenter);
192 return nullptr;
193}
194
195void RenderProxy::setLightCenter(const Vector3& lightCenter) {
196 SETUP_TASK(setLightCenter);
197 args->context = mContext;
198 args->lightCenter = lightCenter;
199 post(task);
200}
201
John Reck63a06672014-05-07 13:45:54 -0700202CREATE_BRIDGE2(setOpaque, CanvasContext* context, bool opaque) {
203 args->context->setOpaque(args->opaque);
Chris Craikd41c4d82015-01-05 15:51:13 -0800204 return nullptr;
John Reck63a06672014-05-07 13:45:54 -0700205}
206
207void RenderProxy::setOpaque(bool opaque) {
208 SETUP_TASK(setOpaque);
209 args->context = mContext;
210 args->opaque = opaque;
211 post(task);
212}
213
John Reckba6adf62015-02-19 14:36:50 -0800214int64_t* RenderProxy::frameInfo() {
215 return mDrawFrameTask.frameInfo();
216}
217
John Reck51f2d602016-04-06 07:50:47 -0700218int RenderProxy::syncAndDrawFrame(TreeObserver* observer) {
219 return mDrawFrameTask.drawFrame(observer);
John Reck4f02bf42014-01-03 18:09:17 -0800220}
221
John Reck51f2d602016-04-06 07:50:47 -0700222CREATE_BRIDGE2(destroy, CanvasContext* context, TreeObserver* observer) {
223 args->context->destroy(args->observer);
Chris Craikd41c4d82015-01-05 15:51:13 -0800224 return nullptr;
John Reck4f02bf42014-01-03 18:09:17 -0800225}
226
John Reck51f2d602016-04-06 07:50:47 -0700227void RenderProxy::destroy(TreeObserver* observer) {
John Reck17035b02014-09-03 07:39:53 -0700228 SETUP_TASK(destroy);
John Reck4f02bf42014-01-03 18:09:17 -0800229 args->context = mContext;
John Reck51f2d602016-04-06 07:50:47 -0700230 args->observer = observer;
John Reckfae904d2014-04-14 11:01:57 -0700231 // destroyCanvasAndSurface() needs a fence as when it returns the
232 // underlying BufferQueue is going to be released from under
233 // the render thread.
234 postAndWait(task);
John Reck4f02bf42014-01-03 18:09:17 -0800235}
236
John Reck3b202512014-06-23 13:13:08 -0700237CREATE_BRIDGE2(invokeFunctor, RenderThread* thread, Functor* functor) {
238 CanvasContext::invokeFunctor(*args->thread, args->functor);
Chris Craikd41c4d82015-01-05 15:51:13 -0800239 return nullptr;
John Reck0d1f6342014-03-28 20:30:27 -0700240}
241
242void RenderProxy::invokeFunctor(Functor* functor, bool waitForCompletion) {
John Reckd3d8daf2014-04-10 15:00:13 -0700243 ATRACE_CALL();
John Reck3b202512014-06-23 13:13:08 -0700244 RenderThread& thread = RenderThread::getInstance();
John Reck0d1f6342014-03-28 20:30:27 -0700245 SETUP_TASK(invokeFunctor);
John Reck3b202512014-06-23 13:13:08 -0700246 args->thread = &thread;
John Reck0d1f6342014-03-28 20:30:27 -0700247 args->functor = functor;
248 if (waitForCompletion) {
John Reck3b202512014-06-23 13:13:08 -0700249 // waitForCompletion = true is expected to be fairly rare and only
250 // happen in destruction. Thus it should be fine to temporarily
251 // create a Mutex
John Reck0e89e2b2014-10-31 14:49:06 -0700252 staticPostAndWait(task);
John Reck0d1f6342014-03-28 20:30:27 -0700253 } else {
John Reck3b202512014-06-23 13:13:08 -0700254 thread.queue(task);
John Reck0d1f6342014-03-28 20:30:27 -0700255 }
256}
257
John Reckfc53ef272014-02-11 10:40:25 -0800258CREATE_BRIDGE2(runWithGlContext, CanvasContext* context, RenderTask* task) {
259 args->context->runWithGlContext(args->task);
Chris Craikd41c4d82015-01-05 15:51:13 -0800260 return nullptr;
John Reckfc53ef272014-02-11 10:40:25 -0800261}
262
263void RenderProxy::runWithGlContext(RenderTask* gltask) {
264 SETUP_TASK(runWithGlContext);
265 args->context = mContext;
266 args->task = gltask;
267 postAndWait(task);
268}
269
John Reckc36df952015-07-29 10:09:36 -0700270CREATE_BRIDGE1(createTextureLayer, CanvasContext* context) {
John Reck1949e792014-04-08 15:18:56 -0700271 Layer* layer = args->context->createTextureLayer();
Chris Craikd41c4d82015-01-05 15:51:13 -0800272 if (!layer) return nullptr;
John Reckc36df952015-07-29 10:09:36 -0700273 return new DeferredLayerUpdater(layer);
John Reck19b6bcf2014-02-14 20:03:38 -0800274}
275
276DeferredLayerUpdater* RenderProxy::createTextureLayer() {
277 SETUP_TASK(createTextureLayer);
John Reck1949e792014-04-08 15:18:56 -0700278 args->context = mContext;
John Reck19b6bcf2014-02-14 20:03:38 -0800279 void* retval = postAndWait(task);
280 DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval);
John Reck19b6bcf2014-02-14 20:03:38 -0800281 return layer;
282}
283
John Reck51f2d602016-04-06 07:50:47 -0700284CREATE_BRIDGE3(buildLayer, CanvasContext* context, RenderNode* node, TreeObserver* observer) {
285 args->context->buildLayer(args->node, args->observer);
Chris Craikd41c4d82015-01-05 15:51:13 -0800286 return nullptr;
John Reck3e824952014-08-20 10:08:39 -0700287}
288
John Reck51f2d602016-04-06 07:50:47 -0700289void RenderProxy::buildLayer(RenderNode* node, TreeObserver* observer) {
John Reck3e824952014-08-20 10:08:39 -0700290 SETUP_TASK(buildLayer);
291 args->context = mContext;
292 args->node = node;
John Reck51f2d602016-04-06 07:50:47 -0700293 args->observer = observer;
John Reck3e824952014-08-20 10:08:39 -0700294 postAndWait(task);
295}
296
John Reck19b6bcf2014-02-14 20:03:38 -0800297CREATE_BRIDGE3(copyLayerInto, CanvasContext* context, DeferredLayerUpdater* layer,
298 SkBitmap* bitmap) {
299 bool success = args->context->copyLayerInto(args->layer, args->bitmap);
300 return (void*) success;
301}
302
John Reck3731dc22015-04-13 15:20:29 -0700303bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap) {
John Reck19b6bcf2014-02-14 20:03:38 -0800304 SETUP_TASK(copyLayerInto);
305 args->context = mContext;
306 args->layer = layer;
John Reck3731dc22015-04-13 15:20:29 -0700307 args->bitmap = &bitmap;
John Reck19b6bcf2014-02-14 20:03:38 -0800308 return (bool) postAndWait(task);
309}
310
John Reckd72e0a32014-05-29 18:56:11 -0700311void RenderProxy::pushLayerUpdate(DeferredLayerUpdater* layer) {
312 mDrawFrameTask.pushLayerUpdate(layer);
313}
314
315void RenderProxy::cancelLayerUpdate(DeferredLayerUpdater* layer) {
316 mDrawFrameTask.removeLayerUpdate(layer);
John Reck19b6bcf2014-02-14 20:03:38 -0800317}
318
John Reck918ad522014-06-27 14:45:25 -0700319CREATE_BRIDGE1(detachSurfaceTexture, DeferredLayerUpdater* layer) {
320 args->layer->detachSurfaceTexture();
Chris Craikd41c4d82015-01-05 15:51:13 -0800321 return nullptr;
John Reck918ad522014-06-27 14:45:25 -0700322}
323
324void RenderProxy::detachSurfaceTexture(DeferredLayerUpdater* layer) {
325 SETUP_TASK(detachSurfaceTexture);
326 args->layer = layer;
327 postAndWait(task);
328}
329
John Reck51f2d602016-04-06 07:50:47 -0700330CREATE_BRIDGE2(destroyHardwareResources, CanvasContext* context, TreeObserver* observer) {
331 args->context->destroyHardwareResources(args->observer);
Chris Craikd41c4d82015-01-05 15:51:13 -0800332 return nullptr;
John Recke1628b72014-05-23 15:11:19 -0700333}
334
John Reck51f2d602016-04-06 07:50:47 -0700335void RenderProxy::destroyHardwareResources(TreeObserver* observer) {
John Reckf47a5942014-06-30 16:20:04 -0700336 SETUP_TASK(destroyHardwareResources);
John Recke1628b72014-05-23 15:11:19 -0700337 args->context = mContext;
John Reck51f2d602016-04-06 07:50:47 -0700338 args->observer = observer;
339 postAndWait(task);
John Recke1628b72014-05-23 15:11:19 -0700340}
341
Chris Craik2507c342015-05-04 14:36:49 -0700342CREATE_BRIDGE2(trimMemory, RenderThread* thread, int level) {
John Reckf47a5942014-06-30 16:20:04 -0700343 CanvasContext::trimMemory(*args->thread, args->level);
Chris Craikd41c4d82015-01-05 15:51:13 -0800344 return nullptr;
John Reckf47a5942014-06-30 16:20:04 -0700345}
346
347void RenderProxy::trimMemory(int level) {
John Reckcd3a22c2014-08-06 13:33:59 -0700348 // Avoid creating a RenderThread to do a trimMemory.
349 if (RenderThread::hasInstance()) {
350 RenderThread& thread = RenderThread::getInstance();
Chris Craik2507c342015-05-04 14:36:49 -0700351 SETUP_TASK(trimMemory);
John Reckcd3a22c2014-08-06 13:33:59 -0700352 args->thread = &thread;
353 args->level = level;
354 thread.queue(task);
355 }
John Reckf47a5942014-06-30 16:20:04 -0700356}
357
Chris Craik2507c342015-05-04 14:36:49 -0700358CREATE_BRIDGE2(overrideProperty, const char* name, const char* value) {
359 Properties::overrideProperty(args->name, args->value);
360 return nullptr;
361}
362
363void RenderProxy::overrideProperty(const char* name, const char* value) {
Chris Craik2507c342015-05-04 14:36:49 -0700364 SETUP_TASK(overrideProperty);
365 args->name = name;
366 args->value = value;
367 staticPostAndWait(task); // expensive, but block here since name/value pointers owned by caller
368}
369
John Reck28ad7b52014-04-07 16:59:25 -0700370CREATE_BRIDGE0(fence) {
371 // Intentionally empty
Chris Craikd41c4d82015-01-05 15:51:13 -0800372 return nullptr;
John Reck28ad7b52014-04-07 16:59:25 -0700373}
374
Andreas Gampe64bb4132014-11-22 00:35:09 +0000375template <typename T>
376void UNUSED(T t) {}
377
John Reck28ad7b52014-04-07 16:59:25 -0700378void RenderProxy::fence() {
379 SETUP_TASK(fence);
Andreas Gampe1e196742014-11-10 15:23:43 -0800380 UNUSED(args);
John Reck28ad7b52014-04-07 16:59:25 -0700381 postAndWait(task);
382}
383
Thomas Buhotc0a0e1a2016-01-18 10:31:58 +0100384void RenderProxy::staticFence() {
385 SETUP_TASK(fence);
386 UNUSED(args);
387 staticPostAndWait(task);
388}
389
John Reckf47a5942014-06-30 16:20:04 -0700390CREATE_BRIDGE1(stopDrawing, CanvasContext* context) {
391 args->context->stopDrawing();
Chris Craikd41c4d82015-01-05 15:51:13 -0800392 return nullptr;
John Reckf47a5942014-06-30 16:20:04 -0700393}
394
395void RenderProxy::stopDrawing() {
396 SETUP_TASK(stopDrawing);
397 args->context = mContext;
398 postAndWait(task);
399}
400
John Recka5dda642014-05-22 15:43:54 -0700401CREATE_BRIDGE1(notifyFramePending, CanvasContext* context) {
402 args->context->notifyFramePending();
Chris Craikd41c4d82015-01-05 15:51:13 -0800403 return nullptr;
John Recka5dda642014-05-22 15:43:54 -0700404}
405
406void RenderProxy::notifyFramePending() {
407 SETUP_TASK(notifyFramePending);
408 args->context = mContext;
409 mRenderThread.queueAtFront(task);
410}
411
John Reck7f2e5e32015-05-05 11:00:53 -0700412CREATE_BRIDGE4(dumpProfileInfo, CanvasContext* context, RenderThread* thread,
413 int fd, int dumpFlags) {
John Reckfe5e7b72014-05-23 17:42:28 -0700414 args->context->profiler().dumpData(args->fd);
Chris Craik53e51e42015-06-01 10:35:35 -0700415 if (args->dumpFlags & DumpFlags::FrameStats) {
John Reckba6adf62015-02-19 14:36:50 -0800416 args->context->dumpFrames(args->fd);
417 }
Chris Craik53e51e42015-06-01 10:35:35 -0700418 if (args->dumpFlags & DumpFlags::Reset) {
John Reckba6adf62015-02-19 14:36:50 -0800419 args->context->resetFrameStats();
420 }
John Recka41f2442016-04-07 16:36:57 -0700421 if (args->dumpFlags & DumpFlags::JankStats) {
422 args->thread->jankTracker().dump(args->fd);
423 }
Chris Craikd41c4d82015-01-05 15:51:13 -0800424 return nullptr;
John Reckfe5e7b72014-05-23 17:42:28 -0700425}
426
John Reckba6adf62015-02-19 14:36:50 -0800427void RenderProxy::dumpProfileInfo(int fd, int dumpFlags) {
John Reckfe5e7b72014-05-23 17:42:28 -0700428 SETUP_TASK(dumpProfileInfo);
429 args->context = mContext;
John Reck7f2e5e32015-05-05 11:00:53 -0700430 args->thread = &mRenderThread;
John Reckfe5e7b72014-05-23 17:42:28 -0700431 args->fd = fd;
John Reckba6adf62015-02-19 14:36:50 -0800432 args->dumpFlags = dumpFlags;
John Reckfe5e7b72014-05-23 17:42:28 -0700433 postAndWait(task);
434}
435
John Reck7f2e5e32015-05-05 11:00:53 -0700436CREATE_BRIDGE1(resetProfileInfo, CanvasContext* context) {
437 args->context->resetFrameStats();
438 return nullptr;
439}
440
441void RenderProxy::resetProfileInfo() {
442 SETUP_TASK(resetProfileInfo);
443 args->context = mContext;
444 postAndWait(task);
445}
446
John Reckba6adf62015-02-19 14:36:50 -0800447CREATE_BRIDGE2(dumpGraphicsMemory, int fd, RenderThread* thread) {
448 args->thread->jankTracker().dump(args->fd);
449
Chris Craik2ae07332015-01-21 14:22:39 -0800450 FILE *file = fdopen(args->fd, "a");
451 if (Caches::hasInstance()) {
452 String8 cachesLog;
453 Caches::getInstance().dumpMemoryUsage(cachesLog);
454 fprintf(file, "\nCaches:\n%s\n", cachesLog.string());
455 } else {
456 fprintf(file, "\nNo caches instance.\n");
457 }
Chris Craikff3edce2016-01-14 10:04:08 -0800458#if HWUI_NEW_OPS
459 fprintf(file, "\nPipeline=FrameBuilder\n");
460#else
461 fprintf(file, "\nPipeline=OpenGLRenderer\n");
462#endif
Chris Craik2ae07332015-01-21 14:22:39 -0800463 fflush(file);
Chris Craikd41c4d82015-01-05 15:51:13 -0800464 return nullptr;
John Reck0e89e2b2014-10-31 14:49:06 -0700465}
466
Chris Craik2ae07332015-01-21 14:22:39 -0800467void RenderProxy::dumpGraphicsMemory(int fd) {
youngmin0822.leec80c9ad2015-03-20 21:22:32 +0900468 if (!RenderThread::hasInstance()) return;
Chris Craik2ae07332015-01-21 14:22:39 -0800469 SETUP_TASK(dumpGraphicsMemory);
John Reck0e89e2b2014-10-31 14:49:06 -0700470 args->fd = fd;
John Reckba6adf62015-02-19 14:36:50 -0800471 args->thread = &RenderThread::getInstance();
John Reck0e89e2b2014-10-31 14:49:06 -0700472 staticPostAndWait(task);
473}
474
Skuhneea7a7fb2015-08-28 07:10:31 -0700475CREATE_BRIDGE4(setTextureAtlas, RenderThread* thread, GraphicBuffer* buffer, int64_t* map,
476 size_t size) {
John Reck3b202512014-06-23 13:13:08 -0700477 CanvasContext::setTextureAtlas(*args->thread, args->buffer, args->map, args->size);
Chris Craikd41c4d82015-01-05 15:51:13 -0800478 args->buffer->decStrong(nullptr);
479 return nullptr;
John Reck3b202512014-06-23 13:13:08 -0700480}
481
482void RenderProxy::setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t size) {
483 SETUP_TASK(setTextureAtlas);
484 args->thread = &mRenderThread;
485 args->buffer = buffer.get();
Chris Craikd41c4d82015-01-05 15:51:13 -0800486 args->buffer->incStrong(nullptr);
John Reck3b202512014-06-23 13:13:08 -0700487 args->map = map;
488 args->size = size;
489 post(task);
490}
491
John Reckedc524c2015-03-18 15:24:33 -0700492CREATE_BRIDGE2(setProcessStatsBuffer, RenderThread* thread, int fd) {
493 args->thread->jankTracker().switchStorageToAshmem(args->fd);
494 close(args->fd);
495 return nullptr;
496}
497
498void RenderProxy::setProcessStatsBuffer(int fd) {
499 SETUP_TASK(setProcessStatsBuffer);
500 args->thread = &mRenderThread;
501 args->fd = dup(fd);
502 post(task);
503}
504
Skuhneea7a7fb2015-08-28 07:10:31 -0700505CREATE_BRIDGE3(addRenderNode, CanvasContext* context, RenderNode* node, bool placeFront) {
506 args->context->addRenderNode(args->node, args->placeFront);
507 return nullptr;
508}
509
510void RenderProxy::addRenderNode(RenderNode* node, bool placeFront) {
511 SETUP_TASK(addRenderNode);
512 args->context = mContext;
513 args->node = node;
514 args->placeFront = placeFront;
515 post(task);
516}
517
518CREATE_BRIDGE2(removeRenderNode, CanvasContext* context, RenderNode* node) {
519 args->context->removeRenderNode(args->node);
520 return nullptr;
521}
522
523void RenderProxy::removeRenderNode(RenderNode* node) {
524 SETUP_TASK(removeRenderNode);
525 args->context = mContext;
526 args->node = node;
527 post(task);
528}
529
530CREATE_BRIDGE2(drawRenderNode, CanvasContext* context, RenderNode* node) {
531 args->context->prepareAndDraw(args->node);
532 return nullptr;
533}
534
535void RenderProxy::drawRenderNode(RenderNode* node) {
536 SETUP_TASK(drawRenderNode);
537 args->context = mContext;
538 args->node = node;
539 // Be pseudo-thread-safe and don't use any member variables
540 staticPostAndWait(task);
541}
542
Skuhneb8160872015-09-22 09:51:39 -0700543CREATE_BRIDGE5(setContentDrawBounds, CanvasContext* context, int left, int top,
Skuhneea7a7fb2015-08-28 07:10:31 -0700544 int right, int bottom) {
Skuhneb8160872015-09-22 09:51:39 -0700545 args->context->setContentDrawBounds(args->left, args->top, args->right, args->bottom);
Skuhneea7a7fb2015-08-28 07:10:31 -0700546 return nullptr;
547}
548
Skuhneb8160872015-09-22 09:51:39 -0700549void RenderProxy::setContentDrawBounds(int left, int top, int right, int bottom) {
550 SETUP_TASK(setContentDrawBounds);
Skuhneea7a7fb2015-08-28 07:10:31 -0700551 args->context = mContext;
552 args->left = left;
553 args->top = top;
554 args->right = right;
555 args->bottom = bottom;
556 staticPostAndWait(task);
557}
558
John Recke248bd12015-08-05 13:53:53 -0700559CREATE_BRIDGE1(serializeDisplayListTree, CanvasContext* context) {
560 args->context->serializeDisplayListTree();
561 return nullptr;
562}
563
564void RenderProxy::serializeDisplayListTree() {
565 SETUP_TASK(serializeDisplayListTree);
566 args->context = mContext;
567 post(task);
568}
569
Andres Morales910beb82016-02-02 16:19:40 -0800570CREATE_BRIDGE2(addFrameMetricsObserver, CanvasContext* context,
571 FrameMetricsObserver* frameStatsObserver) {
572 args->context->addFrameMetricsObserver(args->frameStatsObserver);
Andres Morales06f5bc72015-12-15 15:21:31 -0800573 if (args->frameStatsObserver != nullptr) {
574 args->frameStatsObserver->decStrong(args->context);
575 }
576 return nullptr;
577}
578
Andres Morales910beb82016-02-02 16:19:40 -0800579void RenderProxy::addFrameMetricsObserver(FrameMetricsObserver* observer) {
580 SETUP_TASK(addFrameMetricsObserver);
Andres Morales06f5bc72015-12-15 15:21:31 -0800581 args->context = mContext;
582 args->frameStatsObserver = observer;
583 if (observer != nullptr) {
584 observer->incStrong(mContext);
585 }
586 post(task);
587}
588
Andres Morales910beb82016-02-02 16:19:40 -0800589CREATE_BRIDGE2(removeFrameMetricsObserver, CanvasContext* context,
590 FrameMetricsObserver* frameStatsObserver) {
591 args->context->removeFrameMetricsObserver(args->frameStatsObserver);
Andres Morales06f5bc72015-12-15 15:21:31 -0800592 if (args->frameStatsObserver != nullptr) {
593 args->frameStatsObserver->decStrong(args->context);
594 }
595 return nullptr;
596}
597
Andres Morales910beb82016-02-02 16:19:40 -0800598void RenderProxy::removeFrameMetricsObserver(FrameMetricsObserver* observer) {
599 SETUP_TASK(removeFrameMetricsObserver);
Andres Morales06f5bc72015-12-15 15:21:31 -0800600 args->context = mContext;
601 args->frameStatsObserver = observer;
602 if (observer != nullptr) {
603 observer->incStrong(mContext);
604 }
605 post(task);
606}
607
John Reck10dd0582016-03-31 16:36:16 -0700608CREATE_BRIDGE3(copySurfaceInto, RenderThread* thread,
609 Surface* surface, SkBitmap* bitmap) {
610 return (void*) Readback::copySurfaceInto(*args->thread,
611 *args->surface, args->bitmap);
612}
613
614bool RenderProxy::copySurfaceInto(sp<Surface>& surface, SkBitmap* bitmap) {
615 SETUP_TASK(copySurfaceInto);
616 args->bitmap = bitmap;
617 args->surface = surface.get();
618 args->thread = &RenderThread::getInstance();
619 return (bool) staticPostAndWait(task);
620}
621
John Reck4f02bf42014-01-03 18:09:17 -0800622void RenderProxy::post(RenderTask* task) {
623 mRenderThread.queue(task);
624}
625
626void* RenderProxy::postAndWait(MethodInvokeRenderTask* task) {
627 void* retval;
628 task->setReturnPtr(&retval);
John Reckcba287b2015-11-10 12:52:44 -0800629 SignalingRenderTask syncTask(task, &mSyncMutex, &mSyncCondition);
630 AutoMutex _lock(mSyncMutex);
631 mRenderThread.queue(&syncTask);
632 mSyncCondition.wait(mSyncMutex);
John Reck4f02bf42014-01-03 18:09:17 -0800633 return retval;
634}
635
John Reck0e89e2b2014-10-31 14:49:06 -0700636void* RenderProxy::staticPostAndWait(MethodInvokeRenderTask* task) {
637 RenderThread& thread = RenderThread::getInstance();
638 void* retval;
639 task->setReturnPtr(&retval);
Chris Craik0a24b142015-10-19 17:10:19 -0700640 thread.queueAndWait(task);
John Reck0e89e2b2014-10-31 14:49:06 -0700641 return retval;
642}
643
John Reck4f02bf42014-01-03 18:09:17 -0800644} /* namespace renderthread */
645} /* namespace uirenderer */
646} /* namespace android */