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