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