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