DisplayListRenderer.cpp revision ffac7fc5042296a459d0f5a450dbfe20917093dc
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 < mShaderResources.size(); i++) { 132 caches.resourceCache.decrementRefcount(mShaderResources.itemAt(i)); 133 } 134 mShaderResources.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*> &shaderResources = recorder.getShaderResources(); 183 for (size_t i = 0; i < shaderResources.size(); i++) { 184 SkiaShader* resource = shaderResources.itemAt(i); 185 mShaderResources.add(resource); 186 caches.resourceCache.incrementRefcount(resource); 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 SetMatrix: { 272 renderer.setMatrix(getMatrix()); 273 } 274 break; 275 case ConcatMatrix: { 276 renderer.concatMatrix(getMatrix()); 277 } 278 break; 279 case ClipRect: { 280 renderer.clipRect(getFloat(), getFloat(), getFloat(), getFloat(), 281 (SkRegion::Op) getInt()); 282 } 283 break; 284 case DrawDisplayList: { 285 renderer.drawDisplayList(getDisplayList(), level + 1); 286 } 287 break; 288 case DrawLayer: { 289 renderer.drawLayer((Layer*) getInt(), getFloat(), getFloat(), getPaint()); 290 } 291 break; 292 case DrawBitmap: { 293 renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getPaint()); 294 } 295 break; 296 case DrawBitmapMatrix: { 297 renderer.drawBitmap(getBitmap(), getMatrix(), getPaint()); 298 } 299 break; 300 case DrawBitmapRect: { 301 renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getFloat(), getFloat(), 302 getFloat(), getFloat(), getFloat(), getFloat(), getPaint()); 303 } 304 break; 305 case DrawPatch: { 306 int32_t* xDivs = NULL; 307 int32_t* yDivs = NULL; 308 uint32_t* colors = NULL; 309 uint32_t xDivsCount = 0; 310 uint32_t yDivsCount = 0; 311 int8_t numColors = 0; 312 313 SkBitmap* bitmap = getBitmap(); 314 315 xDivs = getInts(xDivsCount); 316 yDivs = getInts(yDivsCount); 317 colors = getUInts(numColors); 318 319 renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount, 320 numColors, getFloat(), getFloat(), getFloat(), getFloat(), getPaint()); 321 } 322 break; 323 case DrawColor: { 324 renderer.drawColor(getInt(), (SkXfermode::Mode) getInt()); 325 } 326 break; 327 case DrawRect: { 328 renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint()); 329 } 330 break; 331 case DrawPath: { 332 renderer.drawPath(getPath(), getPaint()); 333 } 334 break; 335 case DrawLines: { 336 int count = 0; 337 float* points = getFloats(count); 338 renderer.drawLines(points, count, getPaint()); 339 } 340 break; 341 case DrawText: { 342 getText(&text); 343 renderer.drawText(text.text(), text.length(), getInt(), 344 getFloat(), getFloat(), getPaint()); 345 } 346 break; 347 case ResetShader: { 348 renderer.resetShader(); 349 } 350 break; 351 case SetupShader: { 352 renderer.setupShader(getShader()); 353 } 354 break; 355 case ResetColorFilter: { 356 renderer.resetColorFilter(); 357 } 358 break; 359 case SetupColorFilter: { 360 renderer.setupColorFilter(getColorFilter()); 361 } 362 break; 363 case ResetShadow: { 364 renderer.resetShadow(); 365 } 366 break; 367 case SetupShadow: { 368 renderer.setupShadow(getFloat(), getFloat(), getFloat(), getInt()); 369 } 370 break; 371 } 372 } 373 374 DISPLAY_LIST_LOGD("%sDone", (char*) indent + 2); 375} 376 377/////////////////////////////////////////////////////////////////////////////// 378// Base structure 379/////////////////////////////////////////////////////////////////////////////// 380 381DisplayListRenderer::DisplayListRenderer(): 382 mHeap(HEAP_BLOCK_SIZE), mWriter(MIN_WRITER_SIZE) { 383 mPathHeap = NULL; 384 mDisplayList = NULL; 385} 386 387DisplayListRenderer::~DisplayListRenderer() { 388 reset(); 389} 390 391void DisplayListRenderer::reset() { 392 if (mPathHeap) { 393 mPathHeap->unref(); 394 mPathHeap = NULL; 395 } 396 397 mWriter.reset(); 398 mHeap.reset(); 399 400 mRCRecorder.reset(); 401 mTFRecorder.reset(); 402 403 Caches& caches = Caches::getInstance(); 404 for (size_t i = 0; i < mBitmapResources.size(); i++) { 405 SkBitmap* resource = mBitmapResources.itemAt(i); 406 caches.resourceCache.decrementRefcount(resource); 407 } 408 mBitmapResources.clear(); 409 410 for (size_t i = 0; i < mShaderResources.size(); i++) { 411 SkiaShader* resource = mShaderResources.itemAt(i); 412 caches.resourceCache.decrementRefcount(resource); 413 } 414 mShaderResources.clear(); 415 416 mPaints.clear(); 417 mPaintMap.clear(); 418 mMatrices.clear(); 419} 420 421/////////////////////////////////////////////////////////////////////////////// 422// Operations 423/////////////////////////////////////////////////////////////////////////////// 424 425DisplayList* DisplayListRenderer::getDisplayList() { 426 if (mDisplayList == NULL) { 427 mDisplayList = new DisplayList(*this); 428 } else { 429 mDisplayList->initFromDisplayListRenderer(*this); 430 } 431 return mDisplayList; 432} 433 434void DisplayListRenderer::setViewport(int width, int height) { 435 mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); 436 437 mWidth = width; 438 mHeight = height; 439} 440 441void DisplayListRenderer::prepare(bool opaque) { 442 mSnapshot = new Snapshot(mFirstSnapshot, 443 SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 444 mSaveCount = 1; 445 mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight); 446} 447 448void DisplayListRenderer::acquireContext() { 449 addOp(DisplayList::AcquireContext); 450 OpenGLRenderer::acquireContext(); 451} 452 453void DisplayListRenderer::releaseContext() { 454 addOp(DisplayList::ReleaseContext); 455 OpenGLRenderer::releaseContext(); 456} 457 458int DisplayListRenderer::save(int flags) { 459 addOp(DisplayList::Save); 460 addInt(flags); 461 return OpenGLRenderer::save(flags); 462} 463 464void DisplayListRenderer::restore() { 465 addOp(DisplayList::Restore); 466 OpenGLRenderer::restore(); 467} 468 469void DisplayListRenderer::restoreToCount(int saveCount) { 470 addOp(DisplayList::RestoreToCount); 471 addInt(saveCount); 472 OpenGLRenderer::restoreToCount(saveCount); 473} 474 475int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom, 476 SkPaint* p, int flags) { 477 addOp(DisplayList::SaveLayer); 478 addBounds(left, top, right, bottom); 479 addPaint(p); 480 addInt(flags); 481 return OpenGLRenderer::save(flags); 482} 483 484int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom, 485 int alpha, int flags) { 486 addOp(DisplayList::SaveLayerAlpha); 487 addBounds(left, top, right, bottom); 488 addInt(alpha); 489 addInt(flags); 490 return OpenGLRenderer::save(flags); 491} 492 493void DisplayListRenderer::translate(float dx, float dy) { 494 addOp(DisplayList::Translate); 495 addPoint(dx, dy); 496 OpenGLRenderer::translate(dx, dy); 497} 498 499void DisplayListRenderer::rotate(float degrees) { 500 addOp(DisplayList::Rotate); 501 addFloat(degrees); 502 OpenGLRenderer::rotate(degrees); 503} 504 505void DisplayListRenderer::scale(float sx, float sy) { 506 addOp(DisplayList::Scale); 507 addPoint(sx, sy); 508 OpenGLRenderer::scale(sx, sy); 509} 510 511void DisplayListRenderer::setMatrix(SkMatrix* matrix) { 512 addOp(DisplayList::SetMatrix); 513 addMatrix(matrix); 514 OpenGLRenderer::setMatrix(matrix); 515} 516 517void DisplayListRenderer::concatMatrix(SkMatrix* matrix) { 518 addOp(DisplayList::ConcatMatrix); 519 addMatrix(matrix); 520 OpenGLRenderer::concatMatrix(matrix); 521} 522 523bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom, 524 SkRegion::Op op) { 525 addOp(DisplayList::ClipRect); 526 addBounds(left, top, right, bottom); 527 addInt(op); 528 return OpenGLRenderer::clipRect(left, top, right, bottom, op); 529} 530 531void DisplayListRenderer::drawDisplayList(DisplayList* displayList, uint32_t level) { 532 addOp(DisplayList::DrawDisplayList); 533 addDisplayList(displayList); 534} 535 536void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { 537 addOp(DisplayList::DrawLayer); 538 addInt((int) layer); 539 addPoint(x, y); 540 addPaint(paint); 541} 542 543void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, 544 SkPaint* paint) { 545 addOp(DisplayList::DrawBitmap); 546 addBitmap(bitmap); 547 addPoint(left, top); 548 addPaint(paint); 549} 550 551void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, 552 SkPaint* paint) { 553 addOp(DisplayList::DrawBitmapMatrix); 554 addBitmap(bitmap); 555 addMatrix(matrix); 556 addPaint(paint); 557} 558 559void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, 560 float srcRight, float srcBottom, float dstLeft, float dstTop, 561 float dstRight, float dstBottom, SkPaint* paint) { 562 addOp(DisplayList::DrawBitmapRect); 563 addBitmap(bitmap); 564 addBounds(srcLeft, srcTop, srcRight, srcBottom); 565 addBounds(dstLeft, dstTop, dstRight, dstBottom); 566 addPaint(paint); 567} 568 569void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, 570 const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, 571 float left, float top, float right, float bottom, SkPaint* paint) { 572 addOp(DisplayList::DrawPatch); 573 addBitmap(bitmap); 574 addInts(xDivs, width); 575 addInts(yDivs, height); 576 addUInts(colors, numColors); 577 addBounds(left, top, right, bottom); 578 addPaint(paint); 579} 580 581void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { 582 addOp(DisplayList::DrawColor); 583 addInt(color); 584 addInt(mode); 585} 586 587void DisplayListRenderer::drawRect(float left, float top, float right, float bottom, 588 SkPaint* paint) { 589 addOp(DisplayList::DrawRect); 590 addBounds(left, top, right, bottom); 591 addPaint(paint); 592} 593 594void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) { 595 addOp(DisplayList::DrawPath); 596 addPath(path); 597 addPaint(paint); 598} 599 600void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) { 601 addOp(DisplayList::DrawLines); 602 addFloats(points, count); 603 addPaint(paint); 604} 605 606void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, 607 float x, float y, SkPaint* paint) { 608 addOp(DisplayList::DrawText); 609 addText(text, bytesCount); 610 addInt(count); 611 addPoint(x, y); 612 addPaint(paint); 613} 614 615void DisplayListRenderer::resetShader() { 616 addOp(DisplayList::ResetShader); 617} 618 619void DisplayListRenderer::setupShader(SkiaShader* shader) { 620 addOp(DisplayList::SetupShader); 621 addShader(shader); 622} 623 624void DisplayListRenderer::resetColorFilter() { 625 addOp(DisplayList::ResetColorFilter); 626} 627 628void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) { 629 addOp(DisplayList::SetupColorFilter); 630 addColorFilter(filter); 631} 632 633void DisplayListRenderer::resetShadow() { 634 addOp(DisplayList::ResetShadow); 635} 636 637void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) { 638 addOp(DisplayList::SetupShadow); 639 addFloat(radius); 640 addPoint(dx, dy); 641 addInt(color); 642} 643 644}; // namespace uirenderer 645}; // namespace android 646