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