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