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