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