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