DisplayListRenderer.cpp revision d98aa2de9ab18e09c2be1997f41212740f51f6e6
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 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 renderer.setupShader(getShader()); 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 mPathHeap = NULL; 313} 314 315DisplayListRenderer::~DisplayListRenderer() { 316 reset(); 317} 318 319void DisplayListRenderer::reset() { 320 if (mPathHeap) { 321 mPathHeap->unref(); 322 mPathHeap = NULL; 323 } 324 325 mWriter.reset(); 326 mHeap.reset(); 327 328 mRCRecorder.reset(); 329 mTFRecorder.reset(); 330 331 Caches& caches = Caches::getInstance(); 332 for (size_t i = 0; i < mBitmapResources.size(); i++) { 333 SkBitmap* resource = mBitmapResources.itemAt(i); 334 caches.resourceCache.decrementRefcount(resource); 335 } 336 mBitmapResources.clear(); 337 338 for (size_t i = 0; i < mShaderResources.size(); i++) { 339 SkiaShader* resource = mShaderResources.itemAt(i); 340 caches.resourceCache.decrementRefcount(resource); 341 } 342 mShaderResources.clear(); 343 344 mPaints.clear(); 345 mPaintMap.clear(); 346 mMatrices.clear(); 347} 348 349/////////////////////////////////////////////////////////////////////////////// 350// Operations 351/////////////////////////////////////////////////////////////////////////////// 352 353void DisplayListRenderer::setViewport(int width, int height) { 354 mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); 355 356 mWidth = width; 357 mHeight = height; 358} 359 360void DisplayListRenderer::prepare(bool opaque) { 361 mSnapshot = new Snapshot(mFirstSnapshot, 362 SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 363 mSaveCount = 1; 364 mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight); 365} 366 367void DisplayListRenderer::acquireContext() { 368 addOp(DisplayList::AcquireContext); 369 OpenGLRenderer::acquireContext(); 370} 371 372void DisplayListRenderer::releaseContext() { 373 addOp(DisplayList::ReleaseContext); 374 OpenGLRenderer::releaseContext(); 375} 376 377int DisplayListRenderer::save(int flags) { 378 addOp(DisplayList::Save); 379 addInt(flags); 380 return OpenGLRenderer::save(flags); 381} 382 383void DisplayListRenderer::restore() { 384 addOp(DisplayList::Restore); 385 OpenGLRenderer::restore(); 386} 387 388void DisplayListRenderer::restoreToCount(int saveCount) { 389 addOp(DisplayList::RestoreToCount); 390 addInt(saveCount); 391 OpenGLRenderer::restoreToCount(saveCount); 392} 393 394int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom, 395 SkPaint* p, int flags) { 396 addOp(DisplayList::SaveLayer); 397 addBounds(left, top, right, bottom); 398 addPaint(p); 399 addInt(flags); 400 return OpenGLRenderer::save(flags); 401} 402 403void DisplayListRenderer::translate(float dx, float dy) { 404 addOp(DisplayList::Translate); 405 addPoint(dx, dy); 406 OpenGLRenderer::translate(dx, dy); 407} 408 409void DisplayListRenderer::rotate(float degrees) { 410 addOp(DisplayList::Rotate); 411 addFloat(degrees); 412 OpenGLRenderer::rotate(degrees); 413} 414 415void DisplayListRenderer::scale(float sx, float sy) { 416 addOp(DisplayList::Scale); 417 addPoint(sx, sy); 418 OpenGLRenderer::scale(sx, sy); 419} 420 421void DisplayListRenderer::setMatrix(SkMatrix* matrix) { 422 addOp(DisplayList::SetMatrix); 423 addMatrix(matrix); 424 OpenGLRenderer::setMatrix(matrix); 425} 426 427void DisplayListRenderer::concatMatrix(SkMatrix* matrix) { 428 addOp(DisplayList::ConcatMatrix); 429 addMatrix(matrix); 430 OpenGLRenderer::concatMatrix(matrix); 431} 432 433bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom, 434 SkRegion::Op op) { 435 addOp(DisplayList::ClipRect); 436 addBounds(left, top, right, bottom); 437 addInt(op); 438 return OpenGLRenderer::clipRect(left, top, right, bottom, op); 439} 440 441void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, 442 SkPaint* paint) { 443 addOp(DisplayList::DrawBitmap); 444 addBitmap(bitmap); 445 addPoint(left, top); 446 addPaint(paint); 447} 448 449void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, 450 SkPaint* paint) { 451 addOp(DisplayList::DrawBitmapMatrix); 452 addBitmap(bitmap); 453 addMatrix(matrix); 454 addPaint(paint); 455} 456 457void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, 458 float srcRight, float srcBottom, float dstLeft, float dstTop, 459 float dstRight, float dstBottom, SkPaint* paint) { 460 addOp(DisplayList::DrawBitmapRect); 461 addBitmap(bitmap); 462 addBounds(srcLeft, srcTop, srcRight, srcBottom); 463 addBounds(dstLeft, dstTop, dstRight, dstBottom); 464 addPaint(paint); 465} 466 467void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, 468 const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, 469 float left, float top, float right, float bottom, SkPaint* paint) { 470 addOp(DisplayList::DrawPatch); 471 addBitmap(bitmap); 472 addInts(xDivs, width); 473 addInts(yDivs, height); 474 addUInts(colors, numColors); 475 addBounds(left, top, right, bottom); 476 addPaint(paint); 477} 478 479void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { 480 addOp(DisplayList::DrawColor); 481 addInt(color); 482 addInt(mode); 483} 484 485void DisplayListRenderer::drawRect(float left, float top, float right, float bottom, 486 SkPaint* paint) { 487 addOp(DisplayList::DrawRect); 488 addBounds(left, top, right, bottom); 489 addPaint(paint); 490} 491 492void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) { 493 addOp(DisplayList::DrawPath); 494 addPath(path); 495 addPaint(paint); 496} 497 498void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) { 499 addOp(DisplayList::DrawLines); 500 addFloats(points, count); 501 addPaint(paint); 502} 503 504void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, 505 float x, float y, SkPaint* paint) { 506 addOp(DisplayList::DrawText); 507 addText(text, bytesCount); 508 addInt(count); 509 addPoint(x, y); 510 addPaint(paint); 511} 512 513void DisplayListRenderer::resetShader() { 514 addOp(DisplayList::ResetShader); 515 OpenGLRenderer::resetShader(); 516} 517 518void DisplayListRenderer::setupShader(SkiaShader* shader) { 519 addOp(DisplayList::SetupShader); 520 addShader(shader); 521} 522 523void DisplayListRenderer::resetColorFilter() { 524 addOp(DisplayList::ResetColorFilter); 525 OpenGLRenderer::resetColorFilter(); 526} 527 528void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) { 529 // TODO: Implement 530 OpenGLRenderer::setupColorFilter(filter); 531} 532 533void DisplayListRenderer::resetShadow() { 534 addOp(DisplayList::ResetShadow); 535 OpenGLRenderer::resetShadow(); 536} 537 538void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) { 539 addOp(DisplayList::SetupShadow); 540 addFloat(radius); 541 addPoint(dx, dy); 542 addInt(color); 543 OpenGLRenderer::setupShadow(radius, dx, dy, color); 544} 545 546}; // namespace uirenderer 547}; // namespace android 548