DisplayListRenderer.cpp revision 6b7bd24659fb175fe1f0e97c86c18969918b496a
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 xDivsCount = 0; 240 uint32_t yDivsCount = 0; 241 242 SkBitmap* bitmap = getBitmap(); 243 244 xDivs = getInts(xDivsCount); 245 yDivs = getInts(yDivsCount); 246 247 renderer.drawPatch(bitmap, xDivs, yDivs, xDivsCount, yDivsCount, 248 getFloat(), getFloat(), getFloat(), getFloat(), getPaint()); 249 } 250 break; 251 case DrawColor: { 252 renderer.drawColor(getInt(), (SkXfermode::Mode) getInt()); 253 } 254 break; 255 case DrawRect: { 256 renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint()); 257 } 258 break; 259 case DrawPath: { 260 renderer.drawPath(getPath(), getPaint()); 261 } 262 break; 263 case DrawLines: { 264 int count = 0; 265 float* points = getFloats(count); 266 renderer.drawLines(points, count, getPaint()); 267 } 268 break; 269 case DrawText: { 270 getText(&text); 271 renderer.drawText(text.text(), text.length(), getInt(), 272 getFloat(), getFloat(), getPaint()); 273 } 274 break; 275 case ResetShader: { 276 renderer.resetShader(); 277 } 278 break; 279 case SetupShader: { 280 // TODO: Implement 281 } 282 break; 283 case ResetColorFilter: { 284 renderer.resetColorFilter(); 285 } 286 break; 287 case SetupColorFilter: { 288 // TODO: Implement 289 } 290 break; 291 case ResetShadow: { 292 renderer.resetShadow(); 293 } 294 break; 295 case SetupShadow: { 296 renderer.setupShadow(getFloat(), getFloat(), getFloat(), getInt()); 297 } 298 break; 299 } 300 } 301} 302 303/////////////////////////////////////////////////////////////////////////////// 304// Base structure 305/////////////////////////////////////////////////////////////////////////////// 306 307DisplayListRenderer::DisplayListRenderer(): 308 mHeap(HEAP_BLOCK_SIZE), mWriter(MIN_WRITER_SIZE) { 309 mBitmapIndex = mMatrixIndex = mPaintIndex = 1; 310 mPathHeap = NULL; 311} 312 313DisplayListRenderer::~DisplayListRenderer() { 314 reset(); 315} 316 317void DisplayListRenderer::reset() { 318 if (mPathHeap) { 319 mPathHeap->unref(); 320 mPathHeap = NULL; 321 } 322 323 mBitmaps.reset(); 324 mMatrices.reset(); 325 mPaints.reset(); 326 327 mWriter.reset(); 328 mHeap.reset(); 329 330 mRCRecorder.reset(); 331 mTFRecorder.reset(); 332} 333 334/////////////////////////////////////////////////////////////////////////////// 335// Operations 336/////////////////////////////////////////////////////////////////////////////// 337 338void DisplayListRenderer::setViewport(int width, int height) { 339 mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); 340 341 mWidth = width; 342 mHeight = height; 343} 344 345void DisplayListRenderer::prepare(bool opaque) { 346 mSnapshot = new Snapshot(mFirstSnapshot, 347 SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 348 mSaveCount = 1; 349 mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight); 350} 351 352void DisplayListRenderer::acquireContext() { 353 addOp(DisplayList::AcquireContext); 354 OpenGLRenderer::acquireContext(); 355} 356 357void DisplayListRenderer::releaseContext() { 358 addOp(DisplayList::ReleaseContext); 359 OpenGLRenderer::releaseContext(); 360} 361 362int DisplayListRenderer::save(int flags) { 363 addOp(DisplayList::Save); 364 addInt(flags); 365 return OpenGLRenderer::save(flags); 366} 367 368void DisplayListRenderer::restore() { 369 addOp(DisplayList::Restore); 370 OpenGLRenderer::restore(); 371} 372 373void DisplayListRenderer::restoreToCount(int saveCount) { 374 addOp(DisplayList::RestoreToCount); 375 addInt(saveCount); 376 OpenGLRenderer::restoreToCount(saveCount); 377} 378 379int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom, 380 const SkPaint* p, int flags) { 381 addOp(DisplayList::SaveLayer); 382 addBounds(left, top, right, bottom); 383 addPaint(p); 384 addInt(flags); 385 return OpenGLRenderer::save(flags); 386} 387 388void DisplayListRenderer::translate(float dx, float dy) { 389 addOp(DisplayList::Translate); 390 addPoint(dx, dy); 391 OpenGLRenderer::translate(dx, dy); 392} 393 394void DisplayListRenderer::rotate(float degrees) { 395 addOp(DisplayList::Rotate); 396 addFloat(degrees); 397 OpenGLRenderer::rotate(degrees); 398} 399 400void DisplayListRenderer::scale(float sx, float sy) { 401 addOp(DisplayList::Scale); 402 addPoint(sx, sy); 403 OpenGLRenderer::scale(sx, sy); 404} 405 406void DisplayListRenderer::setMatrix(SkMatrix* matrix) { 407 addOp(DisplayList::SetMatrix); 408 addMatrix(matrix); 409 OpenGLRenderer::setMatrix(matrix); 410} 411 412void DisplayListRenderer::concatMatrix(SkMatrix* matrix) { 413 addOp(DisplayList::ConcatMatrix); 414 addMatrix(matrix); 415 OpenGLRenderer::concatMatrix(matrix); 416} 417 418bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom, 419 SkRegion::Op op) { 420 addOp(DisplayList::ClipRect); 421 addBounds(left, top, right, bottom); 422 addInt(op); 423 return OpenGLRenderer::clipRect(left, top, right, bottom, op); 424} 425 426void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, 427 const SkPaint* paint) { 428 addOp(DisplayList::DrawBitmap); 429 addBitmap(bitmap); 430 addPoint(left, top); 431 addPaint(paint); 432} 433 434void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, 435 const SkPaint* paint) { 436 addOp(DisplayList::DrawBitmapMatrix); 437 addBitmap(bitmap); 438 addMatrix(matrix); 439 addPaint(paint); 440} 441 442void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, 443 float srcRight, float srcBottom, float dstLeft, float dstTop, 444 float dstRight, float dstBottom, const SkPaint* paint) { 445 addOp(DisplayList::DrawBitmapRect); 446 addBitmap(bitmap); 447 addBounds(srcLeft, srcTop, srcRight, srcBottom); 448 addBounds(dstLeft, dstTop, dstRight, dstBottom); 449 addPaint(paint); 450} 451 452void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, 453 uint32_t width, uint32_t height, float left, float top, float right, float bottom, 454 const SkPaint* paint) { 455 addOp(DisplayList::DrawPatch); 456 addBitmap(bitmap); 457 addInts(xDivs, width); 458 addInts(yDivs, height); 459 addBounds(left, top, right, bottom); 460 addPaint(paint); 461} 462 463void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { 464 addOp(DisplayList::DrawColor); 465 addInt(color); 466 addInt(mode); 467} 468 469void DisplayListRenderer::drawRect(float left, float top, float right, float bottom, 470 const SkPaint* paint) { 471 addOp(DisplayList::DrawRect); 472 addBounds(left, top, right, bottom); 473 addPaint(paint); 474} 475 476void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) { 477 addOp(DisplayList::DrawPath); 478 addPath(path); 479 addPaint(paint); 480} 481 482void DisplayListRenderer::drawLines(float* points, int count, const SkPaint* paint) { 483 addOp(DisplayList::DrawLines); 484 addFloats(points, count); 485 addPaint(paint); 486} 487 488void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, 489 float x, float y, SkPaint* paint) { 490 addOp(DisplayList::DrawText); 491 addText(text, bytesCount); 492 addInt(count); 493 addPoint(x, y); 494 addPaint(paint); 495} 496 497void DisplayListRenderer::resetShader() { 498 addOp(DisplayList::ResetShader); 499 OpenGLRenderer::resetShader(); 500} 501 502void DisplayListRenderer::setupShader(SkiaShader* shader) { 503 // TODO: Implement 504 OpenGLRenderer::setupShader(shader); 505} 506 507void DisplayListRenderer::resetColorFilter() { 508 addOp(DisplayList::ResetColorFilter); 509 OpenGLRenderer::resetColorFilter(); 510} 511 512void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) { 513 // TODO: Implement 514 OpenGLRenderer::setupColorFilter(filter); 515} 516 517void DisplayListRenderer::resetShadow() { 518 addOp(DisplayList::ResetShadow); 519 OpenGLRenderer::resetShadow(); 520} 521 522void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) { 523 addOp(DisplayList::SetupShadow); 524 addFloat(radius); 525 addPoint(dx, dy); 526 addInt(color); 527 OpenGLRenderer::setupShadow(radius, dx, dy, color); 528} 529 530/////////////////////////////////////////////////////////////////////////////// 531// Recording management 532/////////////////////////////////////////////////////////////////////////////// 533 534int DisplayListRenderer::find(SkTDArray<const SkFlatPaint*>& paints, const SkPaint* paint) { 535 if (paint == NULL) { 536 return 0; 537 } 538 539 SkFlatPaint* flat = SkFlatPaint::Flatten(&mHeap, *paint, mPaintIndex, 540 &mRCRecorder, &mTFRecorder); 541 int index = SkTSearch<SkFlatData>((const SkFlatData**) paints.begin(), 542 paints.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare); 543 if (index >= 0) { 544 (void) mHeap.unalloc(flat); 545 return paints[index]->index(); 546 } 547 548 index = ~index; 549 *paints.insert(index) = flat; 550 return mPaintIndex++; 551} 552 553int DisplayListRenderer::find(SkTDArray<const SkFlatMatrix*>& matrices, const SkMatrix* matrix) { 554 if (matrix == NULL) { 555 return 0; 556 } 557 558 SkFlatMatrix* flat = SkFlatMatrix::Flatten(&mHeap, *matrix, mMatrixIndex); 559 int index = SkTSearch<SkFlatData>((const SkFlatData**) matrices.begin(), 560 matrices.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare); 561 if (index >= 0) { 562 (void) mHeap.unalloc(flat); 563 return matrices[index]->index(); 564 } 565 index = ~index; 566 *matrices.insert(index) = flat; 567 return mMatrixIndex++; 568} 569 570int DisplayListRenderer::find(SkTDArray<const SkFlatBitmap*>& bitmaps, const SkBitmap& bitmap) { 571 SkFlatBitmap* flat = SkFlatBitmap::Flatten(&mHeap, bitmap, mBitmapIndex, &mRCRecorder); 572 int index = SkTSearch<SkFlatData>((const SkFlatData**) bitmaps.begin(), 573 bitmaps.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare); 574 if (index >= 0) { 575 (void) mHeap.unalloc(flat); 576 return bitmaps[index]->index(); 577 } 578 index = ~index; 579 *bitmaps.insert(index) = flat; 580 return mBitmapIndex++; 581} 582 583}; // namespace uirenderer 584}; // namespace android 585