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