1 /*
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
17 #include "RenderProxy.h"
18
19 #include "DeferredLayerUpdater.h"
20 #include "DisplayList.h"
21 #include "LayerRenderer.h"
22 #include "Readback.h"
23 #include "Rect.h"
24 #include "renderthread/CanvasContext.h"
25 #include "renderthread/RenderTask.h"
26 #include "renderthread/RenderThread.h"
27 #include "utils/Macros.h"
28
29 namespace android {
30 namespace uirenderer {
31 namespace renderthread {
32
33 #define ARGS(method) method ## Args
34
35 #define CREATE_BRIDGE0(name) CREATE_BRIDGE(name,,,,,,,,)
36 #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,,,,)
40 #define CREATE_BRIDGE5(name, a1, a2, a3, a4, a5) CREATE_BRIDGE(name, a1,a2,a3,a4,a5,,,)
41 #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,)
43 #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)), \
51 "METHOD_INVOKE_PAYLOAD_SIZE %zu is smaller than sizeof(" #method "Args) %zu", \
52 METHOD_INVOKE_PAYLOAD_SIZE, sizeof(ARGS(method))); \
53 MethodInvokeRenderTask* task = new MethodInvokeRenderTask((RunnableMethod) Bridge_ ## method); \
54 ARGS(method) *args = (ARGS(method) *) task->payload()
55
CREATE_BRIDGE4(createContext,RenderThread * thread,bool translucent,RenderNode * rootRenderNode,IContextFactory * contextFactory)56 CREATE_BRIDGE4(createContext, RenderThread* thread, bool translucent,
57 RenderNode* rootRenderNode, IContextFactory* contextFactory) {
58 return new CanvasContext(*args->thread, args->translucent,
59 args->rootRenderNode, args->contextFactory);
60 }
61
RenderProxy(bool translucent,RenderNode * rootRenderNode,IContextFactory * contextFactory)62 RenderProxy::RenderProxy(bool translucent, RenderNode* rootRenderNode, IContextFactory* contextFactory)
63 : mRenderThread(RenderThread::getInstance())
64 , mContext(nullptr) {
65 SETUP_TASK(createContext);
66 args->translucent = translucent;
67 args->rootRenderNode = rootRenderNode;
68 args->thread = &mRenderThread;
69 args->contextFactory = contextFactory;
70 mContext = (CanvasContext*) postAndWait(task);
71 mDrawFrameTask.setContext(&mRenderThread, mContext, rootRenderNode);
72 }
73
~RenderProxy()74 RenderProxy::~RenderProxy() {
75 destroyContext();
76 }
77
CREATE_BRIDGE1(destroyContext,CanvasContext * context)78 CREATE_BRIDGE1(destroyContext, CanvasContext* context) {
79 delete args->context;
80 return nullptr;
81 }
82
destroyContext()83 void RenderProxy::destroyContext() {
84 if (mContext) {
85 SETUP_TASK(destroyContext);
86 args->context = mContext;
87 mContext = nullptr;
88 mDrawFrameTask.setContext(nullptr, nullptr, nullptr);
89 // 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);
92 }
93 }
94
CREATE_BRIDGE2(setSwapBehavior,CanvasContext * context,SwapBehavior swapBehavior)95 CREATE_BRIDGE2(setSwapBehavior, CanvasContext* context, SwapBehavior swapBehavior) {
96 args->context->setSwapBehavior(args->swapBehavior);
97 return nullptr;
98 }
99
setSwapBehavior(SwapBehavior swapBehavior)100 void RenderProxy::setSwapBehavior(SwapBehavior swapBehavior) {
101 SETUP_TASK(setSwapBehavior);
102 args->context = mContext;
103 args->swapBehavior = swapBehavior;
104 post(task);
105 }
106
CREATE_BRIDGE1(loadSystemProperties,CanvasContext * context)107 CREATE_BRIDGE1(loadSystemProperties, CanvasContext* context) {
108 bool needsRedraw = false;
109 if (Caches::hasInstance()) {
110 needsRedraw = Properties::load();
111 }
112 if (args->context->profiler().consumeProperties()) {
113 needsRedraw = true;
114 }
115 return (void*) needsRedraw;
116 }
117
loadSystemProperties()118 bool RenderProxy::loadSystemProperties() {
119 SETUP_TASK(loadSystemProperties);
120 args->context = mContext;
121 return (bool) postAndWait(task);
122 }
123
CREATE_BRIDGE2(setName,CanvasContext * context,const char * name)124 CREATE_BRIDGE2(setName, CanvasContext* context, const char* name) {
125 args->context->setName(std::string(args->name));
126 return nullptr;
127 }
128
setName(const char * name)129 void RenderProxy::setName(const char* name) {
130 SETUP_TASK(setName);
131 args->context = mContext;
132 args->name = name;
133 postAndWait(task); // block since name/value pointers owned by caller
134 }
135
CREATE_BRIDGE2(initialize,CanvasContext * context,Surface * surface)136 CREATE_BRIDGE2(initialize, CanvasContext* context, Surface* surface) {
137 args->context->initialize(args->surface);
138 return nullptr;
139 }
140
initialize(const sp<Surface> & surface)141 void RenderProxy::initialize(const sp<Surface>& surface) {
142 SETUP_TASK(initialize);
143 args->context = mContext;
144 args->surface = surface.get();
145 post(task);
146 }
147
CREATE_BRIDGE2(updateSurface,CanvasContext * context,Surface * surface)148 CREATE_BRIDGE2(updateSurface, CanvasContext* context, Surface* surface) {
149 args->context->updateSurface(args->surface);
150 return nullptr;
151 }
152
updateSurface(const sp<Surface> & surface)153 void RenderProxy::updateSurface(const sp<Surface>& surface) {
154 SETUP_TASK(updateSurface);
155 args->context = mContext;
156 args->surface = surface.get();
157 postAndWait(task);
158 }
159
CREATE_BRIDGE2(pauseSurface,CanvasContext * context,Surface * surface)160 CREATE_BRIDGE2(pauseSurface, CanvasContext* context, Surface* surface) {
161 return (void*) args->context->pauseSurface(args->surface);
162 }
163
pauseSurface(const sp<Surface> & surface)164 bool RenderProxy::pauseSurface(const sp<Surface>& surface) {
165 SETUP_TASK(pauseSurface);
166 args->context = mContext;
167 args->surface = surface.get();
168 return (bool) postAndWait(task);
169 }
170
CREATE_BRIDGE2(setStopped,CanvasContext * context,bool stopped)171 CREATE_BRIDGE2(setStopped, CanvasContext* context, bool stopped) {
172 args->context->setStopped(args->stopped);
173 return nullptr;
174 }
175
setStopped(bool stopped)176 void RenderProxy::setStopped(bool stopped) {
177 SETUP_TASK(setStopped);
178 args->context = mContext;
179 args->stopped = stopped;
180 postAndWait(task);
181 }
182
CREATE_BRIDGE6(setup,CanvasContext * context,int width,int height,float lightRadius,uint8_t ambientShadowAlpha,uint8_t spotShadowAlpha)183 CREATE_BRIDGE6(setup, CanvasContext* context, int width, int height,
184 float lightRadius, uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
185 args->context->setup(args->width, args->height, args->lightRadius,
186 args->ambientShadowAlpha, args->spotShadowAlpha);
187 return nullptr;
188 }
189
setup(int width,int height,float lightRadius,uint8_t ambientShadowAlpha,uint8_t spotShadowAlpha)190 void RenderProxy::setup(int width, int height, float lightRadius,
191 uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
192 SETUP_TASK(setup);
193 args->context = mContext;
194 args->width = width;
195 args->height = height;
196 args->lightRadius = lightRadius;
197 args->ambientShadowAlpha = ambientShadowAlpha;
198 args->spotShadowAlpha = spotShadowAlpha;
199 post(task);
200 }
201
CREATE_BRIDGE2(setLightCenter,CanvasContext * context,Vector3 lightCenter)202 CREATE_BRIDGE2(setLightCenter, CanvasContext* context, Vector3 lightCenter) {
203 args->context->setLightCenter(args->lightCenter);
204 return nullptr;
205 }
206
setLightCenter(const Vector3 & lightCenter)207 void RenderProxy::setLightCenter(const Vector3& lightCenter) {
208 SETUP_TASK(setLightCenter);
209 args->context = mContext;
210 args->lightCenter = lightCenter;
211 post(task);
212 }
213
CREATE_BRIDGE2(setOpaque,CanvasContext * context,bool opaque)214 CREATE_BRIDGE2(setOpaque, CanvasContext* context, bool opaque) {
215 args->context->setOpaque(args->opaque);
216 return nullptr;
217 }
218
setOpaque(bool opaque)219 void RenderProxy::setOpaque(bool opaque) {
220 SETUP_TASK(setOpaque);
221 args->context = mContext;
222 args->opaque = opaque;
223 post(task);
224 }
225
frameInfo()226 int64_t* RenderProxy::frameInfo() {
227 return mDrawFrameTask.frameInfo();
228 }
229
syncAndDrawFrame(TreeObserver * observer)230 int RenderProxy::syncAndDrawFrame(TreeObserver* observer) {
231 return mDrawFrameTask.drawFrame(observer);
232 }
233
CREATE_BRIDGE2(destroy,CanvasContext * context,TreeObserver * observer)234 CREATE_BRIDGE2(destroy, CanvasContext* context, TreeObserver* observer) {
235 args->context->destroy(args->observer);
236 return nullptr;
237 }
238
destroy(TreeObserver * observer)239 void RenderProxy::destroy(TreeObserver* observer) {
240 SETUP_TASK(destroy);
241 args->context = mContext;
242 args->observer = observer;
243 // destroyCanvasAndSurface() needs a fence as when it returns the
244 // underlying BufferQueue is going to be released from under
245 // the render thread.
246 postAndWait(task);
247 }
248
CREATE_BRIDGE2(invokeFunctor,RenderThread * thread,Functor * functor)249 CREATE_BRIDGE2(invokeFunctor, RenderThread* thread, Functor* functor) {
250 CanvasContext::invokeFunctor(*args->thread, args->functor);
251 return nullptr;
252 }
253
invokeFunctor(Functor * functor,bool waitForCompletion)254 void RenderProxy::invokeFunctor(Functor* functor, bool waitForCompletion) {
255 ATRACE_CALL();
256 RenderThread& thread = RenderThread::getInstance();
257 SETUP_TASK(invokeFunctor);
258 args->thread = &thread;
259 args->functor = functor;
260 if (waitForCompletion) {
261 // waitForCompletion = true is expected to be fairly rare and only
262 // happen in destruction. Thus it should be fine to temporarily
263 // create a Mutex
264 staticPostAndWait(task);
265 } else {
266 thread.queue(task);
267 }
268 }
269
CREATE_BRIDGE2(runWithGlContext,CanvasContext * context,RenderTask * task)270 CREATE_BRIDGE2(runWithGlContext, CanvasContext* context, RenderTask* task) {
271 args->context->runWithGlContext(args->task);
272 return nullptr;
273 }
274
runWithGlContext(RenderTask * gltask)275 void RenderProxy::runWithGlContext(RenderTask* gltask) {
276 SETUP_TASK(runWithGlContext);
277 args->context = mContext;
278 args->task = gltask;
279 postAndWait(task);
280 }
281
CREATE_BRIDGE1(createTextureLayer,CanvasContext * context)282 CREATE_BRIDGE1(createTextureLayer, CanvasContext* context) {
283 Layer* layer = args->context->createTextureLayer();
284 if (!layer) return nullptr;
285 return new DeferredLayerUpdater(layer);
286 }
287
createTextureLayer()288 DeferredLayerUpdater* RenderProxy::createTextureLayer() {
289 SETUP_TASK(createTextureLayer);
290 args->context = mContext;
291 void* retval = postAndWait(task);
292 DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval);
293 return layer;
294 }
295
CREATE_BRIDGE3(buildLayer,CanvasContext * context,RenderNode * node,TreeObserver * observer)296 CREATE_BRIDGE3(buildLayer, CanvasContext* context, RenderNode* node, TreeObserver* observer) {
297 args->context->buildLayer(args->node, args->observer);
298 return nullptr;
299 }
300
buildLayer(RenderNode * node,TreeObserver * observer)301 void RenderProxy::buildLayer(RenderNode* node, TreeObserver* observer) {
302 SETUP_TASK(buildLayer);
303 args->context = mContext;
304 args->node = node;
305 args->observer = observer;
306 postAndWait(task);
307 }
308
CREATE_BRIDGE3(copyLayerInto,CanvasContext * context,DeferredLayerUpdater * layer,SkBitmap * bitmap)309 CREATE_BRIDGE3(copyLayerInto, CanvasContext* context, DeferredLayerUpdater* layer,
310 SkBitmap* bitmap) {
311 bool success = args->context->copyLayerInto(args->layer, args->bitmap);
312 return (void*) success;
313 }
314
copyLayerInto(DeferredLayerUpdater * layer,SkBitmap & bitmap)315 bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap) {
316 SETUP_TASK(copyLayerInto);
317 args->context = mContext;
318 args->layer = layer;
319 args->bitmap = &bitmap;
320 return (bool) postAndWait(task);
321 }
322
pushLayerUpdate(DeferredLayerUpdater * layer)323 void RenderProxy::pushLayerUpdate(DeferredLayerUpdater* layer) {
324 mDrawFrameTask.pushLayerUpdate(layer);
325 }
326
cancelLayerUpdate(DeferredLayerUpdater * layer)327 void RenderProxy::cancelLayerUpdate(DeferredLayerUpdater* layer) {
328 mDrawFrameTask.removeLayerUpdate(layer);
329 }
330
CREATE_BRIDGE1(detachSurfaceTexture,DeferredLayerUpdater * layer)331 CREATE_BRIDGE1(detachSurfaceTexture, DeferredLayerUpdater* layer) {
332 args->layer->detachSurfaceTexture();
333 return nullptr;
334 }
335
detachSurfaceTexture(DeferredLayerUpdater * layer)336 void RenderProxy::detachSurfaceTexture(DeferredLayerUpdater* layer) {
337 SETUP_TASK(detachSurfaceTexture);
338 args->layer = layer;
339 postAndWait(task);
340 }
341
CREATE_BRIDGE2(destroyHardwareResources,CanvasContext * context,TreeObserver * observer)342 CREATE_BRIDGE2(destroyHardwareResources, CanvasContext* context, TreeObserver* observer) {
343 args->context->destroyHardwareResources(args->observer);
344 return nullptr;
345 }
346
destroyHardwareResources(TreeObserver * observer)347 void RenderProxy::destroyHardwareResources(TreeObserver* observer) {
348 SETUP_TASK(destroyHardwareResources);
349 args->context = mContext;
350 args->observer = observer;
351 postAndWait(task);
352 }
353
CREATE_BRIDGE2(trimMemory,RenderThread * thread,int level)354 CREATE_BRIDGE2(trimMemory, RenderThread* thread, int level) {
355 CanvasContext::trimMemory(*args->thread, args->level);
356 return nullptr;
357 }
358
trimMemory(int level)359 void RenderProxy::trimMemory(int level) {
360 // Avoid creating a RenderThread to do a trimMemory.
361 if (RenderThread::hasInstance()) {
362 RenderThread& thread = RenderThread::getInstance();
363 SETUP_TASK(trimMemory);
364 args->thread = &thread;
365 args->level = level;
366 thread.queue(task);
367 }
368 }
369
CREATE_BRIDGE2(overrideProperty,const char * name,const char * value)370 CREATE_BRIDGE2(overrideProperty, const char* name, const char* value) {
371 Properties::overrideProperty(args->name, args->value);
372 return nullptr;
373 }
374
overrideProperty(const char * name,const char * value)375 void RenderProxy::overrideProperty(const char* name, const char* value) {
376 SETUP_TASK(overrideProperty);
377 args->name = name;
378 args->value = value;
379 staticPostAndWait(task); // expensive, but block here since name/value pointers owned by caller
380 }
381
CREATE_BRIDGE0(fence)382 CREATE_BRIDGE0(fence) {
383 // Intentionally empty
384 return nullptr;
385 }
386
387 template <typename T>
UNUSED(T t)388 void UNUSED(T t) {}
389
fence()390 void RenderProxy::fence() {
391 SETUP_TASK(fence);
392 UNUSED(args);
393 postAndWait(task);
394 }
395
staticFence()396 void RenderProxy::staticFence() {
397 SETUP_TASK(fence);
398 UNUSED(args);
399 staticPostAndWait(task);
400 }
401
CREATE_BRIDGE1(stopDrawing,CanvasContext * context)402 CREATE_BRIDGE1(stopDrawing, CanvasContext* context) {
403 args->context->stopDrawing();
404 return nullptr;
405 }
406
stopDrawing()407 void RenderProxy::stopDrawing() {
408 SETUP_TASK(stopDrawing);
409 args->context = mContext;
410 postAndWait(task);
411 }
412
CREATE_BRIDGE1(notifyFramePending,CanvasContext * context)413 CREATE_BRIDGE1(notifyFramePending, CanvasContext* context) {
414 args->context->notifyFramePending();
415 return nullptr;
416 }
417
notifyFramePending()418 void RenderProxy::notifyFramePending() {
419 SETUP_TASK(notifyFramePending);
420 args->context = mContext;
421 mRenderThread.queueAtFront(task);
422 }
423
CREATE_BRIDGE4(dumpProfileInfo,CanvasContext * context,RenderThread * thread,int fd,int dumpFlags)424 CREATE_BRIDGE4(dumpProfileInfo, CanvasContext* context, RenderThread* thread,
425 int fd, int dumpFlags) {
426 args->context->profiler().dumpData(args->fd);
427 if (args->dumpFlags & DumpFlags::FrameStats) {
428 args->context->dumpFrames(args->fd);
429 }
430 if (args->dumpFlags & DumpFlags::Reset) {
431 args->context->resetFrameStats();
432 }
433 if (args->dumpFlags & DumpFlags::JankStats) {
434 args->thread->jankTracker().dump(args->fd);
435 }
436 return nullptr;
437 }
438
dumpProfileInfo(int fd,int dumpFlags)439 void RenderProxy::dumpProfileInfo(int fd, int dumpFlags) {
440 SETUP_TASK(dumpProfileInfo);
441 args->context = mContext;
442 args->thread = &mRenderThread;
443 args->fd = fd;
444 args->dumpFlags = dumpFlags;
445 postAndWait(task);
446 }
447
CREATE_BRIDGE1(resetProfileInfo,CanvasContext * context)448 CREATE_BRIDGE1(resetProfileInfo, CanvasContext* context) {
449 args->context->resetFrameStats();
450 return nullptr;
451 }
452
resetProfileInfo()453 void RenderProxy::resetProfileInfo() {
454 SETUP_TASK(resetProfileInfo);
455 args->context = mContext;
456 postAndWait(task);
457 }
458
CREATE_BRIDGE2(dumpGraphicsMemory,int fd,RenderThread * thread)459 CREATE_BRIDGE2(dumpGraphicsMemory, int fd, RenderThread* thread) {
460 args->thread->jankTracker().dump(args->fd);
461
462 FILE *file = fdopen(args->fd, "a");
463 if (Caches::hasInstance()) {
464 String8 cachesLog;
465 Caches::getInstance().dumpMemoryUsage(cachesLog);
466 fprintf(file, "\nCaches:\n%s\n", cachesLog.string());
467 } else {
468 fprintf(file, "\nNo caches instance.\n");
469 }
470 #if HWUI_NEW_OPS
471 fprintf(file, "\nPipeline=FrameBuilder\n");
472 #else
473 fprintf(file, "\nPipeline=OpenGLRenderer\n");
474 #endif
475 fflush(file);
476 return nullptr;
477 }
478
dumpGraphicsMemory(int fd)479 void RenderProxy::dumpGraphicsMemory(int fd) {
480 if (!RenderThread::hasInstance()) return;
481 SETUP_TASK(dumpGraphicsMemory);
482 args->fd = fd;
483 args->thread = &RenderThread::getInstance();
484 staticPostAndWait(task);
485 }
486
CREATE_BRIDGE4(setTextureAtlas,RenderThread * thread,GraphicBuffer * buffer,int64_t * map,size_t size)487 CREATE_BRIDGE4(setTextureAtlas, RenderThread* thread, GraphicBuffer* buffer, int64_t* map,
488 size_t size) {
489 CanvasContext::setTextureAtlas(*args->thread, args->buffer, args->map, args->size);
490 args->buffer->decStrong(nullptr);
491 return nullptr;
492 }
493
setTextureAtlas(const sp<GraphicBuffer> & buffer,int64_t * map,size_t size)494 void RenderProxy::setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t size) {
495 SETUP_TASK(setTextureAtlas);
496 args->thread = &mRenderThread;
497 args->buffer = buffer.get();
498 args->buffer->incStrong(nullptr);
499 args->map = map;
500 args->size = size;
501 post(task);
502 }
503
CREATE_BRIDGE2(setProcessStatsBuffer,RenderThread * thread,int fd)504 CREATE_BRIDGE2(setProcessStatsBuffer, RenderThread* thread, int fd) {
505 args->thread->jankTracker().switchStorageToAshmem(args->fd);
506 close(args->fd);
507 return nullptr;
508 }
509
setProcessStatsBuffer(int fd)510 void RenderProxy::setProcessStatsBuffer(int fd) {
511 SETUP_TASK(setProcessStatsBuffer);
512 args->thread = &mRenderThread;
513 args->fd = dup(fd);
514 post(task);
515 }
516
CREATE_BRIDGE3(addRenderNode,CanvasContext * context,RenderNode * node,bool placeFront)517 CREATE_BRIDGE3(addRenderNode, CanvasContext* context, RenderNode* node, bool placeFront) {
518 args->context->addRenderNode(args->node, args->placeFront);
519 return nullptr;
520 }
521
addRenderNode(RenderNode * node,bool placeFront)522 void RenderProxy::addRenderNode(RenderNode* node, bool placeFront) {
523 SETUP_TASK(addRenderNode);
524 args->context = mContext;
525 args->node = node;
526 args->placeFront = placeFront;
527 post(task);
528 }
529
CREATE_BRIDGE2(removeRenderNode,CanvasContext * context,RenderNode * node)530 CREATE_BRIDGE2(removeRenderNode, CanvasContext* context, RenderNode* node) {
531 args->context->removeRenderNode(args->node);
532 return nullptr;
533 }
534
removeRenderNode(RenderNode * node)535 void RenderProxy::removeRenderNode(RenderNode* node) {
536 SETUP_TASK(removeRenderNode);
537 args->context = mContext;
538 args->node = node;
539 post(task);
540 }
541
CREATE_BRIDGE2(drawRenderNode,CanvasContext * context,RenderNode * node)542 CREATE_BRIDGE2(drawRenderNode, CanvasContext* context, RenderNode* node) {
543 args->context->prepareAndDraw(args->node);
544 return nullptr;
545 }
546
drawRenderNode(RenderNode * node)547 void RenderProxy::drawRenderNode(RenderNode* node) {
548 SETUP_TASK(drawRenderNode);
549 args->context = mContext;
550 args->node = node;
551 // Be pseudo-thread-safe and don't use any member variables
552 staticPostAndWait(task);
553 }
554
CREATE_BRIDGE5(setContentDrawBounds,CanvasContext * context,int left,int top,int right,int bottom)555 CREATE_BRIDGE5(setContentDrawBounds, CanvasContext* context, int left, int top,
556 int right, int bottom) {
557 args->context->setContentDrawBounds(args->left, args->top, args->right, args->bottom);
558 return nullptr;
559 }
560
setContentDrawBounds(int left,int top,int right,int bottom)561 void RenderProxy::setContentDrawBounds(int left, int top, int right, int bottom) {
562 SETUP_TASK(setContentDrawBounds);
563 args->context = mContext;
564 args->left = left;
565 args->top = top;
566 args->right = right;
567 args->bottom = bottom;
568 staticPostAndWait(task);
569 }
570
CREATE_BRIDGE1(serializeDisplayListTree,CanvasContext * context)571 CREATE_BRIDGE1(serializeDisplayListTree, CanvasContext* context) {
572 args->context->serializeDisplayListTree();
573 return nullptr;
574 }
575
serializeDisplayListTree()576 void RenderProxy::serializeDisplayListTree() {
577 SETUP_TASK(serializeDisplayListTree);
578 args->context = mContext;
579 post(task);
580 }
581
CREATE_BRIDGE2(addFrameMetricsObserver,CanvasContext * context,FrameMetricsObserver * frameStatsObserver)582 CREATE_BRIDGE2(addFrameMetricsObserver, CanvasContext* context,
583 FrameMetricsObserver* frameStatsObserver) {
584 args->context->addFrameMetricsObserver(args->frameStatsObserver);
585 if (args->frameStatsObserver != nullptr) {
586 args->frameStatsObserver->decStrong(args->context);
587 }
588 return nullptr;
589 }
590
addFrameMetricsObserver(FrameMetricsObserver * observer)591 void RenderProxy::addFrameMetricsObserver(FrameMetricsObserver* observer) {
592 SETUP_TASK(addFrameMetricsObserver);
593 args->context = mContext;
594 args->frameStatsObserver = observer;
595 if (observer != nullptr) {
596 observer->incStrong(mContext);
597 }
598 post(task);
599 }
600
CREATE_BRIDGE2(removeFrameMetricsObserver,CanvasContext * context,FrameMetricsObserver * frameStatsObserver)601 CREATE_BRIDGE2(removeFrameMetricsObserver, CanvasContext* context,
602 FrameMetricsObserver* frameStatsObserver) {
603 args->context->removeFrameMetricsObserver(args->frameStatsObserver);
604 if (args->frameStatsObserver != nullptr) {
605 args->frameStatsObserver->decStrong(args->context);
606 }
607 return nullptr;
608 }
609
removeFrameMetricsObserver(FrameMetricsObserver * observer)610 void RenderProxy::removeFrameMetricsObserver(FrameMetricsObserver* observer) {
611 SETUP_TASK(removeFrameMetricsObserver);
612 args->context = mContext;
613 args->frameStatsObserver = observer;
614 if (observer != nullptr) {
615 observer->incStrong(mContext);
616 }
617 post(task);
618 }
619
CREATE_BRIDGE3(copySurfaceInto,RenderThread * thread,Surface * surface,SkBitmap * bitmap)620 CREATE_BRIDGE3(copySurfaceInto, RenderThread* thread,
621 Surface* surface, SkBitmap* bitmap) {
622 return (void*) Readback::copySurfaceInto(*args->thread,
623 *args->surface, args->bitmap);
624 }
625
copySurfaceInto(sp<Surface> & surface,SkBitmap * bitmap)626 int RenderProxy::copySurfaceInto(sp<Surface>& surface, SkBitmap* bitmap) {
627 SETUP_TASK(copySurfaceInto);
628 args->bitmap = bitmap;
629 args->surface = surface.get();
630 args->thread = &RenderThread::getInstance();
631 return static_cast<int>(
632 reinterpret_cast<intptr_t>( staticPostAndWait(task) ));
633 }
634
post(RenderTask * task)635 void RenderProxy::post(RenderTask* task) {
636 mRenderThread.queue(task);
637 }
638
postAndWait(MethodInvokeRenderTask * task)639 void* RenderProxy::postAndWait(MethodInvokeRenderTask* task) {
640 void* retval;
641 task->setReturnPtr(&retval);
642 SignalingRenderTask syncTask(task, &mSyncMutex, &mSyncCondition);
643 AutoMutex _lock(mSyncMutex);
644 mRenderThread.queue(&syncTask);
645 mSyncCondition.wait(mSyncMutex);
646 return retval;
647 }
648
staticPostAndWait(MethodInvokeRenderTask * task)649 void* RenderProxy::staticPostAndWait(MethodInvokeRenderTask* task) {
650 RenderThread& thread = RenderThread::getInstance();
651 void* retval;
652 task->setReturnPtr(&retval);
653 thread.queueAndWait(task);
654 return retval;
655 }
656
657 } /* namespace renderthread */
658 } /* namespace uirenderer */
659 } /* namespace android */
660