DisplayListRenderer.cpp revision a566b7c3aada08d37cf08096c972e3e641bed773
1/* 2 * Copyright (C) 2010 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#define LOG_TAG "OpenGLRenderer" 18 19#include "DisplayListRenderer.h" 20 21namespace android { 22namespace uirenderer { 23 24/////////////////////////////////////////////////////////////////////////////// 25// Defines 26/////////////////////////////////////////////////////////////////////////////// 27 28#define PATH_HEAP_SIZE 64 29 30/////////////////////////////////////////////////////////////////////////////// 31// Helpers 32/////////////////////////////////////////////////////////////////////////////// 33 34PathHeap::PathHeap(): mHeap(PATH_HEAP_SIZE * sizeof(SkPath)) { 35} 36 37PathHeap::PathHeap(SkFlattenableReadBuffer& buffer): mHeap(PATH_HEAP_SIZE * sizeof(SkPath)) { 38 int count = buffer.readS32(); 39 40 mPaths.setCount(count); 41 SkPath** ptr = mPaths.begin(); 42 SkPath* p = (SkPath*) mHeap.allocThrow(count * sizeof(SkPath)); 43 44 for (int i = 0; i < count; i++) { 45 new (p) SkPath; 46 p->unflatten(buffer); 47 *ptr++ = p; 48 p++; 49 } 50} 51 52PathHeap::~PathHeap() { 53 SkPath** iter = mPaths.begin(); 54 SkPath** stop = mPaths.end(); 55 while (iter < stop) { 56 (*iter)->~SkPath(); 57 iter++; 58 } 59} 60 61int PathHeap::append(const SkPath& path) { 62 SkPath* p = (SkPath*) mHeap.allocThrow(sizeof(SkPath)); 63 new (p) SkPath(path); 64 *mPaths.append() = p; 65 return mPaths.count(); 66} 67 68void PathHeap::flatten(SkFlattenableWriteBuffer& buffer) const { 69 int count = mPaths.count(); 70 71 buffer.write32(count); 72 SkPath** iter = mPaths.begin(); 73 SkPath** stop = mPaths.end(); 74 while (iter < stop) { 75 (*iter)->flatten(buffer); 76 iter++; 77 } 78} 79 80/////////////////////////////////////////////////////////////////////////////// 81// Display list 82/////////////////////////////////////////////////////////////////////////////// 83 84const char* DisplayList::OP_NAMES[] = { 85 "AcquireContext", 86 "ReleaseContext", 87 "Save", 88 "Restore", 89 "RestoreToCount", 90 "SaveLayer", 91 "SaveLayerAlpha", 92 "Translate", 93 "Rotate", 94 "Scale", 95 "Skew", 96 "SetMatrix", 97 "ConcatMatrix", 98 "ClipRect", 99 "DrawDisplayList", 100 "DrawLayer", 101 "DrawBitmap", 102 "DrawBitmapMatrix", 103 "DrawBitmapRect", 104 "DrawBitmapMesh", 105 "DrawPatch", 106 "DrawColor", 107 "DrawRect", 108 "DrawRoundRect", 109 "DrawCircle", 110 "DrawOval", 111 "DrawArc", 112 "DrawPath", 113 "DrawLines", 114 "DrawText", 115 "ResetShader", 116 "SetupShader", 117 "ResetColorFilter", 118 "SetupColorFilter", 119 "ResetShadow", 120 "SetupShadow" 121}; 122 123DisplayList::DisplayList(const DisplayListRenderer& recorder) { 124 initFromDisplayListRenderer(recorder); 125} 126 127DisplayList::~DisplayList() { 128 sk_free((void*) mReader.base()); 129 130 Caches& caches = Caches::getInstance(); 131 132 for (size_t i = 0; i < mBitmapResources.size(); i++) { 133 caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i)); 134 } 135 mBitmapResources.clear(); 136 137 for (size_t i = 0; i < mShaders.size(); i++) { 138 caches.resourceCache.decrementRefcount(mShaders.itemAt(i)); 139 } 140 mShaders.clear(); 141 142 for (size_t i = 0; i < mPaints.size(); i++) { 143 delete mPaints.itemAt(i); 144 } 145 mPaints.clear(); 146 147 for (size_t i = 0; i < mMatrices.size(); i++) { 148 delete mMatrices.itemAt(i); 149 } 150 mMatrices.clear(); 151 152 if (mPathHeap) { 153 for (int i = 0; i < mPathHeap->count(); i++) { 154 caches.pathCache.removeDeferred(&(*mPathHeap)[i]); 155 } 156 mPathHeap->safeUnref(); 157 } 158} 159 160void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder) { 161 const SkWriter32& writer = recorder.writeStream(); 162 init(); 163 164 if (writer.size() == 0) { 165 return; 166 } 167 168 size_t size = writer.size(); 169 void* buffer = sk_malloc_throw(size); 170 writer.flatten(buffer); 171 mReader.setMemory(buffer, size); 172 173 mRCPlayback.reset(&recorder.mRCRecorder); 174 mRCPlayback.setupBuffer(mReader); 175 176 mTFPlayback.reset(&recorder.mTFRecorder); 177 mTFPlayback.setupBuffer(mReader); 178 179 Caches& caches = Caches::getInstance(); 180 181 const Vector<SkBitmap*> &bitmapResources = recorder.getBitmapResources(); 182 for (size_t i = 0; i < bitmapResources.size(); i++) { 183 SkBitmap* resource = bitmapResources.itemAt(i); 184 mBitmapResources.add(resource); 185 caches.resourceCache.incrementRefcount(resource); 186 } 187 188 const Vector<SkiaShader*> &shaders = recorder.getShaders(); 189 for (size_t i = 0; i < shaders.size(); i++) { 190 SkiaShader* shader = shaders.itemAt(i); 191 mShaders.add(shader); 192 caches.resourceCache.incrementRefcount(shader); 193 } 194 195 const Vector<SkPaint*> &paints = recorder.getPaints(); 196 for (size_t i = 0; i < paints.size(); i++) { 197 mPaints.add(paints.itemAt(i)); 198 } 199 200 const Vector<SkMatrix*> &matrices = recorder.getMatrices(); 201 for (size_t i = 0; i < matrices.size(); i++) { 202 mMatrices.add(matrices.itemAt(i)); 203 } 204 205 mPathHeap = recorder.mPathHeap; 206 if (mPathHeap) { 207 mPathHeap->safeRef(); 208 } 209} 210 211void DisplayList::init() { 212 mPathHeap = NULL; 213} 214 215void DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) { 216 TextContainer text; 217 mReader.rewind(); 218 219#if DEBUG_DISPLAY_LIST 220 uint32_t count = (level + 1) * 2; 221 char indent[count + 1]; 222 for (uint32_t i = 0; i < count; i++) { 223 indent[i] = ' '; 224 } 225 indent[count] = '\0'; 226 DISPLAY_LIST_LOGD("%sStart display list (%p)", (char*) indent + 2, this); 227#endif 228 229 int saveCount = renderer.getSaveCount() - 1; 230 while (!mReader.eof()) { 231 int op = mReader.readInt(); 232 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); 233 234 switch (op) { 235 case AcquireContext: { 236 renderer.acquireContext(); 237 } 238 break; 239 case ReleaseContext: { 240 renderer.releaseContext(); 241 } 242 break; 243 case Save: { 244 renderer.save(getInt()); 245 } 246 break; 247 case Restore: { 248 renderer.restore(); 249 } 250 break; 251 case RestoreToCount: { 252 renderer.restoreToCount(saveCount + getInt()); 253 } 254 break; 255 case SaveLayer: { 256 renderer.saveLayer(getFloat(), getFloat(), getFloat(), getFloat(), 257 getPaint(), getInt()); 258 } 259 break; 260 case SaveLayerAlpha: { 261 renderer.saveLayerAlpha(getFloat(), getFloat(), getFloat(), getFloat(), 262 getInt(), getInt()); 263 } 264 break; 265 case Translate: { 266 renderer.translate(getFloat(), getFloat()); 267 } 268 break; 269 case Rotate: { 270 renderer.rotate(getFloat()); 271 } 272 break; 273 case Scale: { 274 renderer.scale(getFloat(), getFloat()); 275 } 276 break; 277 case Skew: { 278 renderer.skew(getFloat(), getFloat()); 279 } 280 break; 281 case SetMatrix: { 282 renderer.setMatrix(getMatrix()); 283 } 284 break; 285 case ConcatMatrix: { 286 renderer.concatMatrix(getMatrix()); 287 } 288 break; 289 case ClipRect: { 290 renderer.clipRect(getFloat(), getFloat(), getFloat(), getFloat(), 291 (SkRegion::Op) getInt()); 292 } 293 break; 294 case DrawDisplayList: { 295 renderer.drawDisplayList(getDisplayList(), level + 1); 296 } 297 break; 298 case DrawLayer: { 299 renderer.drawLayer((Layer*) getInt(), getFloat(), getFloat(), getPaint()); 300 } 301 break; 302 case DrawBitmap: { 303 renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getPaint()); 304 } 305 break; 306 case DrawBitmapMatrix: { 307 renderer.drawBitmap(getBitmap(), getMatrix(), getPaint()); 308 } 309 break; 310 case DrawBitmapRect: { 311 renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getFloat(), getFloat(), 312 getFloat(), getFloat(), getFloat(), getFloat(), getPaint()); 313 } 314 break; 315 case DrawBitmapMesh: { 316 int verticesCount = 0; 317 uint32_t colorsCount = 0; 318 319 SkBitmap* bitmap = getBitmap(); 320 uint32_t meshWidth = getInt(); 321 uint32_t meshHeight = getInt(); 322 float* vertices = getFloats(verticesCount); 323 bool hasColors = getInt(); 324 int* colors = hasColors ? getInts(colorsCount) : NULL; 325 326 renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, colors, getPaint()); 327 } 328 break; 329 case DrawPatch: { 330 int32_t* xDivs = NULL; 331 int32_t* yDivs = NULL; 332 uint32_t* colors = NULL; 333 uint32_t xDivsCount = 0; 334 uint32_t yDivsCount = 0; 335 int8_t numColors = 0; 336 337 SkBitmap* bitmap = getBitmap(); 338 339 xDivs = getInts(xDivsCount); 340 yDivs = getInts(yDivsCount); 341 colors = getUInts(numColors); 342 343 renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount, 344 numColors, getFloat(), getFloat(), getFloat(), getFloat(), getPaint()); 345 } 346 break; 347 case DrawColor: { 348 renderer.drawColor(getInt(), (SkXfermode::Mode) getInt()); 349 } 350 break; 351 case DrawRect: { 352 renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint()); 353 } 354 break; 355 case DrawRoundRect: { 356 renderer.drawRoundRect(getFloat(), getFloat(), getFloat(), getFloat(), 357 getFloat(), getFloat(), getPaint()); 358 } 359 break; 360 case DrawCircle: { 361 renderer.drawCircle(getFloat(), getFloat(), getFloat(), getPaint()); 362 } 363 break; 364 case DrawOval: { 365 renderer.drawOval(getFloat(), getFloat(), getFloat(), getFloat(), getPaint()); 366 } 367 break; 368 case DrawArc: { 369 renderer.drawArc(getFloat(), getFloat(), getFloat(), getFloat(), 370 getFloat(), getFloat(), getInt() == 1, getPaint()); 371 } 372 break; 373 case DrawPath: { 374 renderer.drawPath(getPath(), getPaint()); 375 } 376 break; 377 case DrawLines: { 378 int count = 0; 379 float* points = getFloats(count); 380 renderer.drawLines(points, count, getPaint()); 381 } 382 break; 383 case DrawText: { 384 getText(&text); 385 renderer.drawText(text.text(), text.length(), getInt(), 386 getFloat(), getFloat(), getPaint()); 387 } 388 break; 389 case ResetShader: { 390 renderer.resetShader(); 391 } 392 break; 393 case SetupShader: { 394 renderer.setupShader(getShader()); 395 } 396 break; 397 case ResetColorFilter: { 398 renderer.resetColorFilter(); 399 } 400 break; 401 case SetupColorFilter: { 402 renderer.setupColorFilter(getColorFilter()); 403 } 404 break; 405 case ResetShadow: { 406 renderer.resetShadow(); 407 } 408 break; 409 case SetupShadow: { 410 renderer.setupShadow(getFloat(), getFloat(), getFloat(), getInt()); 411 } 412 break; 413 } 414 } 415 416 DISPLAY_LIST_LOGD("%sDone", (char*) indent + 2); 417} 418 419/////////////////////////////////////////////////////////////////////////////// 420// Base structure 421/////////////////////////////////////////////////////////////////////////////// 422 423DisplayListRenderer::DisplayListRenderer(): 424 mHeap(HEAP_BLOCK_SIZE), mWriter(MIN_WRITER_SIZE) { 425 mPathHeap = NULL; 426 mDisplayList = NULL; 427} 428 429DisplayListRenderer::~DisplayListRenderer() { 430 reset(); 431} 432 433void DisplayListRenderer::reset() { 434 if (mPathHeap) { 435 mPathHeap->unref(); 436 mPathHeap = NULL; 437 } 438 439 mWriter.reset(); 440 mHeap.reset(); 441 442 mRCRecorder.reset(); 443 mTFRecorder.reset(); 444 445 Caches& caches = Caches::getInstance(); 446 for (size_t i = 0; i < mBitmapResources.size(); i++) { 447 SkBitmap* resource = mBitmapResources.itemAt(i); 448 caches.resourceCache.decrementRefcount(resource); 449 } 450 mBitmapResources.clear(); 451 452 for (size_t i = 0; i < mShaders.size(); i++) { 453 caches.resourceCache.decrementRefcount(mShaders.itemAt(i)); 454 } 455 mShaders.clear(); 456 mShaderMap.clear(); 457 458 mPaints.clear(); 459 mPaintMap.clear(); 460 mMatrices.clear(); 461} 462 463/////////////////////////////////////////////////////////////////////////////// 464// Operations 465/////////////////////////////////////////////////////////////////////////////// 466 467DisplayList* DisplayListRenderer::getDisplayList() { 468 if (mDisplayList == NULL) { 469 mDisplayList = new DisplayList(*this); 470 } else { 471 mDisplayList->initFromDisplayListRenderer(*this); 472 } 473 return mDisplayList; 474} 475 476void DisplayListRenderer::setViewport(int width, int height) { 477 mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); 478 479 mWidth = width; 480 mHeight = height; 481} 482 483void DisplayListRenderer::prepare(bool opaque) { 484 mSnapshot = new Snapshot(mFirstSnapshot, 485 SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 486 mSaveCount = 1; 487 mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight); 488 mRestoreSaveCount = -1; 489} 490 491void DisplayListRenderer::finish() { 492 insertRestoreToCount(); 493 OpenGLRenderer::finish(); 494} 495 496void DisplayListRenderer::acquireContext() { 497 addOp(DisplayList::AcquireContext); 498 OpenGLRenderer::acquireContext(); 499} 500 501void DisplayListRenderer::releaseContext() { 502 addOp(DisplayList::ReleaseContext); 503 OpenGLRenderer::releaseContext(); 504} 505 506int DisplayListRenderer::save(int flags) { 507 addOp(DisplayList::Save); 508 addInt(flags); 509 return OpenGLRenderer::save(flags); 510} 511 512void DisplayListRenderer::restore() { 513 addOp(DisplayList::Restore); 514 OpenGLRenderer::restore(); 515} 516 517void DisplayListRenderer::restoreToCount(int saveCount) { 518 mRestoreSaveCount = saveCount; 519 OpenGLRenderer::restoreToCount(saveCount); 520} 521 522int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom, 523 SkPaint* p, int flags) { 524 addOp(DisplayList::SaveLayer); 525 addBounds(left, top, right, bottom); 526 addPaint(p); 527 addInt(flags); 528 return OpenGLRenderer::save(flags); 529} 530 531int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom, 532 int alpha, int flags) { 533 addOp(DisplayList::SaveLayerAlpha); 534 addBounds(left, top, right, bottom); 535 addInt(alpha); 536 addInt(flags); 537 return OpenGLRenderer::save(flags); 538} 539 540void DisplayListRenderer::translate(float dx, float dy) { 541 addOp(DisplayList::Translate); 542 addPoint(dx, dy); 543 OpenGLRenderer::translate(dx, dy); 544} 545 546void DisplayListRenderer::rotate(float degrees) { 547 addOp(DisplayList::Rotate); 548 addFloat(degrees); 549 OpenGLRenderer::rotate(degrees); 550} 551 552void DisplayListRenderer::scale(float sx, float sy) { 553 addOp(DisplayList::Scale); 554 addPoint(sx, sy); 555 OpenGLRenderer::scale(sx, sy); 556} 557 558void DisplayListRenderer::skew(float sx, float sy) { 559 addOp(DisplayList::Skew); 560 addPoint(sx, sy); 561 OpenGLRenderer::skew(sx, sy); 562} 563 564void DisplayListRenderer::setMatrix(SkMatrix* matrix) { 565 addOp(DisplayList::SetMatrix); 566 addMatrix(matrix); 567 OpenGLRenderer::setMatrix(matrix); 568} 569 570void DisplayListRenderer::concatMatrix(SkMatrix* matrix) { 571 addOp(DisplayList::ConcatMatrix); 572 addMatrix(matrix); 573 OpenGLRenderer::concatMatrix(matrix); 574} 575 576bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom, 577 SkRegion::Op op) { 578 addOp(DisplayList::ClipRect); 579 addBounds(left, top, right, bottom); 580 addInt(op); 581 return OpenGLRenderer::clipRect(left, top, right, bottom, op); 582} 583 584void DisplayListRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) { 585 addOp(DisplayList::DrawDisplayList); 586 addDisplayList(displayList); 587} 588 589void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { 590 addOp(DisplayList::DrawLayer); 591 addInt((int) layer); 592 addPoint(x, y); 593 addPaint(paint); 594} 595 596void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, 597 SkPaint* paint) { 598 addOp(DisplayList::DrawBitmap); 599 addBitmap(bitmap); 600 addPoint(left, top); 601 addPaint(paint); 602} 603 604void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, 605 SkPaint* paint) { 606 addOp(DisplayList::DrawBitmapMatrix); 607 addBitmap(bitmap); 608 addMatrix(matrix); 609 addPaint(paint); 610} 611 612void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, 613 float srcRight, float srcBottom, float dstLeft, float dstTop, 614 float dstRight, float dstBottom, SkPaint* paint) { 615 addOp(DisplayList::DrawBitmapRect); 616 addBitmap(bitmap); 617 addBounds(srcLeft, srcTop, srcRight, srcBottom); 618 addBounds(dstLeft, dstTop, dstRight, dstBottom); 619 addPaint(paint); 620} 621 622void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, 623 float* vertices, int* colors, SkPaint* paint) { 624 addOp(DisplayList::DrawBitmapMesh); 625 addBitmap(bitmap); 626 addInt(meshWidth); 627 addInt(meshHeight); 628 addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2); 629 if (colors) { 630 addInt(1); 631 addInts(colors, (meshWidth + 1) * (meshHeight + 1)); 632 } else { 633 addInt(0); 634 } 635 addPaint(paint); 636} 637 638void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, 639 const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, 640 float left, float top, float right, float bottom, SkPaint* paint) { 641 addOp(DisplayList::DrawPatch); 642 addBitmap(bitmap); 643 addInts(xDivs, width); 644 addInts(yDivs, height); 645 addUInts(colors, numColors); 646 addBounds(left, top, right, bottom); 647 addPaint(paint); 648} 649 650void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { 651 addOp(DisplayList::DrawColor); 652 addInt(color); 653 addInt(mode); 654} 655 656void DisplayListRenderer::drawRect(float left, float top, float right, float bottom, 657 SkPaint* paint) { 658 addOp(DisplayList::DrawRect); 659 addBounds(left, top, right, bottom); 660 addPaint(paint); 661} 662 663void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom, 664 float rx, float ry, SkPaint* paint) { 665 addOp(DisplayList::DrawRoundRect); 666 addBounds(left, top, right, bottom); 667 addPoint(rx, ry); 668 addPaint(paint); 669} 670 671void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) { 672 addOp(DisplayList::DrawCircle); 673 addPoint(x, y); 674 addFloat(radius); 675 addPaint(paint); 676} 677 678void DisplayListRenderer::drawOval(float left, float top, float right, float bottom, 679 SkPaint* paint) { 680 addOp(DisplayList::DrawOval); 681 addBounds(left, top, right, bottom); 682 addPaint(paint); 683} 684 685void DisplayListRenderer::drawArc(float left, float top, float right, float bottom, 686 float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) { 687 addOp(DisplayList::DrawOval); 688 addBounds(left, top, right, bottom); 689 addPoint(startAngle, sweepAngle); 690 addInt(useCenter ? 1 : 0); 691 addPaint(paint); 692} 693 694void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) { 695 addOp(DisplayList::DrawPath); 696 addPath(path); 697 addPaint(paint); 698} 699 700void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) { 701 addOp(DisplayList::DrawLines); 702 addFloats(points, count); 703 addPaint(paint); 704} 705 706void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, 707 float x, float y, SkPaint* paint) { 708 addOp(DisplayList::DrawText); 709 addText(text, bytesCount); 710 addInt(count); 711 addPoint(x, y); 712 addPaint(paint); 713} 714 715void DisplayListRenderer::resetShader() { 716 addOp(DisplayList::ResetShader); 717} 718 719void DisplayListRenderer::setupShader(SkiaShader* shader) { 720 addOp(DisplayList::SetupShader); 721 addShader(shader); 722} 723 724void DisplayListRenderer::resetColorFilter() { 725 addOp(DisplayList::ResetColorFilter); 726} 727 728void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) { 729 addOp(DisplayList::SetupColorFilter); 730 addColorFilter(filter); 731} 732 733void DisplayListRenderer::resetShadow() { 734 addOp(DisplayList::ResetShadow); 735} 736 737void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) { 738 addOp(DisplayList::SetupShadow); 739 addFloat(radius); 740 addPoint(dx, dy); 741 addInt(color); 742} 743 744}; // namespace uirenderer 745}; // namespace android 746