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