• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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