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