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