DisplayListRenderer.cpp revision b051e895ccb696604349c6c5efe7c4747e1d1ab6
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// Display list 26/////////////////////////////////////////////////////////////////////////////// 27 28DisplayList::DisplayList(const DisplayListRenderer& recorder) { 29 const SkWriter32& writer = recorder.writeStream(); 30 init(); 31 32 if (writer.size() == 0) { 33 return; 34 } 35 36 size_t size = writer.size(); 37 void* buffer = sk_malloc_throw(size); 38 writer.flatten(buffer); 39 mReader.setMemory(buffer, size); 40 41 mRCPlayback.reset(&recorder.mRCRecorder); 42 mRCPlayback.setupBuffer(mReader); 43 44 mTFPlayback.reset(&recorder.mTFRecorder); 45 mTFPlayback.setupBuffer(mReader); 46 47 const SkTDArray<const SkFlatBitmap*>& bitmaps = recorder.getBitmaps(); 48 mBitmapCount = bitmaps.count(); 49 if (mBitmapCount > 0) { 50 mBitmaps = new SkBitmap[mBitmapCount]; 51 for (const SkFlatBitmap** flatBitmapPtr = bitmaps.begin(); 52 flatBitmapPtr != bitmaps.end(); flatBitmapPtr++) { 53 const SkFlatBitmap* flatBitmap = *flatBitmapPtr; 54 int index = flatBitmap->index() - 1; 55 flatBitmap->unflatten(&mBitmaps[index], &mRCPlayback); 56 } 57 } 58 59 const SkTDArray<const SkFlatMatrix*>& matrices = recorder.getMatrices(); 60 mMatrixCount = matrices.count(); 61 if (mMatrixCount > 0) { 62 mMatrices = new SkMatrix[mMatrixCount]; 63 for (const SkFlatMatrix** matrixPtr = matrices.begin(); 64 matrixPtr != matrices.end(); matrixPtr++) { 65 const SkFlatMatrix* flatMatrix = *matrixPtr; 66 flatMatrix->unflatten(&mMatrices[flatMatrix->index() - 1]); 67 } 68 } 69 70 const SkTDArray<const SkFlatPaint*>& paints = recorder.getPaints(); 71 mPaintCount = paints.count(); 72 if (mPaintCount > 0) { 73 mPaints = new SkPaint[mPaintCount]; 74 for (const SkFlatPaint** flatPaintPtr = paints.begin(); 75 flatPaintPtr != paints.end(); flatPaintPtr++) { 76 const SkFlatPaint* flatPaint = *flatPaintPtr; 77 int index = flatPaint->index() - 1; 78 flatPaint->unflatten(&mPaints[index], &mRCPlayback, &mTFPlayback); 79 } 80 } 81 82 mPathHeap = recorder.mPathHeap; 83 mPathHeap->safeRef(); 84} 85 86DisplayList::~DisplayList() { 87 sk_free((void*) mReader.base()); 88 89 Caches& caches = Caches::getInstance(); 90 for (int i = 0; i < mBitmapCount; i++) { 91 caches.textureCache.remove(&mBitmaps[i]); 92 } 93 94 delete[] mBitmaps; 95 delete[] mMatrices; 96 delete[] mPaints; 97 98 mPathHeap->safeUnref(); 99} 100 101void DisplayList::init() { 102 mBitmaps = NULL; 103 mMatrices = NULL; 104 mPaints = NULL; 105 mPathHeap = NULL; 106 mBitmapCount = mMatrixCount = mPaintCount = 0; 107} 108 109void DisplayList::replay(OpenGLRenderer& renderer) { 110 TextContainer text; 111 mReader.rewind(); 112 113 int saveCount = renderer.getSaveCount() - 1; 114 115 while (!mReader.eof()) { 116 switch (mReader.readInt()) { 117 case AcquireContext: { 118 renderer.acquireContext(); 119 } 120 break; 121 case ReleaseContext: { 122 renderer.releaseContext(); 123 } 124 break; 125 case Save: { 126 renderer.save(getInt()); 127 } 128 break; 129 case Restore: { 130 renderer.restore(); 131 } 132 break; 133 case RestoreToCount: { 134 renderer.restoreToCount(saveCount + getInt()); 135 } 136 break; 137 case SaveLayer: { 138 renderer.saveLayer(getFloat(), getFloat(), getFloat(), getFloat(), 139 getPaint(), getInt()); 140 } 141 break; 142 case Translate: { 143 renderer.translate(getFloat(), getFloat()); 144 } 145 break; 146 case Rotate: { 147 renderer.rotate(getFloat()); 148 } 149 break; 150 case Scale: { 151 renderer.scale(getFloat(), getFloat()); 152 } 153 break; 154 case SetMatrix: { 155 renderer.setMatrix(getMatrix()); 156 } 157 break; 158 case ConcatMatrix: { 159 renderer.concatMatrix(getMatrix()); 160 } 161 break; 162 case ClipRect: { 163 renderer.clipRect(getFloat(), getFloat(), getFloat(), getFloat(), 164 (SkRegion::Op) getInt()); 165 } 166 break; 167 case DrawBitmap: { 168 renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getPaint()); 169 } 170 break; 171 case DrawBitmapMatrix: { 172 renderer.drawBitmap(getBitmap(), getMatrix(), getPaint()); 173 } 174 break; 175 case DrawBitmapRect: { 176 renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getFloat(), getFloat(), 177 getFloat(), getFloat(), getFloat(), getFloat(), getPaint()); 178 } 179 break; 180 case DrawPatch: { 181 int32_t* xDivs = NULL; 182 int32_t* yDivs = NULL; 183 uint32_t xDivsCount = 0; 184 uint32_t yDivsCount = 0; 185 186 SkBitmap* bitmap = getBitmap(); 187 188 xDivs = getInts(xDivsCount); 189 yDivs = getInts(yDivsCount); 190 191 renderer.drawPatch(bitmap, xDivs, yDivs, xDivsCount, yDivsCount, 192 getFloat(), getFloat(), getFloat(), getFloat(), getPaint()); 193 } 194 break; 195 case DrawColor: { 196 renderer.drawColor(getInt(), (SkXfermode::Mode) getInt()); 197 } 198 break; 199 case DrawRect: { 200 renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint()); 201 } 202 break; 203 case DrawPath: { 204 renderer.drawPath(getPath(), getPaint()); 205 } 206 break; 207 case DrawLines: { 208 int count = 0; 209 float* points = getFloats(count); 210 renderer.drawLines(points, count, getPaint()); 211 } 212 break; 213 case DrawText: { 214 getText(&text); 215 renderer.drawText(text.text(), text.length(), getInt(), 216 getFloat(), getFloat(), getPaint()); 217 } 218 break; 219 case ResetShader: { 220 renderer.resetShader(); 221 } 222 break; 223 case SetupShader: { 224 // TODO: Implement 225 } 226 break; 227 case ResetColorFilter: { 228 renderer.resetColorFilter(); 229 } 230 break; 231 case SetupColorFilter: { 232 // TODO: Implement 233 } 234 break; 235 case ResetShadow: { 236 renderer.resetShadow(); 237 } 238 break; 239 case SetupShadow: { 240 renderer.setupShadow(getFloat(), getFloat(), getFloat(), getInt()); 241 } 242 break; 243 } 244 } 245} 246 247/////////////////////////////////////////////////////////////////////////////// 248// Base structure 249/////////////////////////////////////////////////////////////////////////////// 250 251DisplayListRenderer::DisplayListRenderer(): 252 mHeap(HEAP_BLOCK_SIZE), mWriter(MIN_WRITER_SIZE) { 253 mBitmapIndex = mMatrixIndex = mPaintIndex = 1; 254 mPathHeap = NULL; 255} 256 257DisplayListRenderer::~DisplayListRenderer() { 258 reset(); 259} 260 261void DisplayListRenderer::reset() { 262 if (mPathHeap) { 263 mPathHeap->unref(); 264 mPathHeap = NULL; 265 } 266 267 mBitmaps.reset(); 268 mMatrices.reset(); 269 mPaints.reset(); 270 271 mWriter.reset(); 272 mHeap.reset(); 273 274 mRCRecorder.reset(); 275 mTFRecorder.reset(); 276} 277 278/////////////////////////////////////////////////////////////////////////////// 279// Operations 280/////////////////////////////////////////////////////////////////////////////// 281 282void DisplayListRenderer::setViewport(int width, int height) { 283 mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); 284 285 mWidth = width; 286 mHeight = height; 287} 288 289void DisplayListRenderer::prepare() { 290 mSnapshot = new Snapshot(mFirstSnapshot, 291 SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 292 mSaveCount = 1; 293 mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight); 294} 295 296void DisplayListRenderer::acquireContext() { 297 addOp(DisplayList::AcquireContext); 298 OpenGLRenderer::acquireContext(); 299} 300 301void DisplayListRenderer::releaseContext() { 302 addOp(DisplayList::ReleaseContext); 303 OpenGLRenderer::releaseContext(); 304} 305 306int DisplayListRenderer::save(int flags) { 307 addOp(DisplayList::Save); 308 addInt(flags); 309 return OpenGLRenderer::save(flags); 310} 311 312void DisplayListRenderer::restore() { 313 addOp(DisplayList::Restore); 314 OpenGLRenderer::restore(); 315} 316 317void DisplayListRenderer::restoreToCount(int saveCount) { 318 addOp(DisplayList::RestoreToCount); 319 addInt(saveCount); 320 OpenGLRenderer::restoreToCount(saveCount); 321} 322 323int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom, 324 const SkPaint* p, int flags) { 325 addOp(DisplayList::SaveLayer); 326 addBounds(left, top, right, bottom); 327 addPaint(p); 328 addInt(flags); 329 return OpenGLRenderer::save(flags); 330} 331 332void DisplayListRenderer::translate(float dx, float dy) { 333 addOp(DisplayList::Translate); 334 addPoint(dx, dy); 335 OpenGLRenderer::translate(dx, dy); 336} 337 338void DisplayListRenderer::rotate(float degrees) { 339 addOp(DisplayList::Rotate); 340 addFloat(degrees); 341 OpenGLRenderer::rotate(degrees); 342} 343 344void DisplayListRenderer::scale(float sx, float sy) { 345 addOp(DisplayList::Scale); 346 addPoint(sx, sy); 347 OpenGLRenderer::scale(sx, sy); 348} 349 350void DisplayListRenderer::setMatrix(SkMatrix* matrix) { 351 addOp(DisplayList::SetMatrix); 352 addMatrix(matrix); 353 OpenGLRenderer::setMatrix(matrix); 354} 355 356void DisplayListRenderer::concatMatrix(SkMatrix* matrix) { 357 addOp(DisplayList::ConcatMatrix); 358 addMatrix(matrix); 359 OpenGLRenderer::concatMatrix(matrix); 360} 361 362bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom, 363 SkRegion::Op op) { 364 addOp(DisplayList::ClipRect); 365 addBounds(left, top, right, bottom); 366 addInt(op); 367 return OpenGLRenderer::clipRect(left, top, right, bottom, op); 368} 369 370void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, 371 const SkPaint* paint) { 372 addOp(DisplayList::DrawBitmap); 373 addBitmap(bitmap); 374 addPoint(left, top); 375 addPaint(paint); 376} 377 378void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, 379 const SkPaint* paint) { 380 addOp(DisplayList::DrawBitmapMatrix); 381 addBitmap(bitmap); 382 addMatrix(matrix); 383 addPaint(paint); 384} 385 386void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, 387 float srcRight, float srcBottom, float dstLeft, float dstTop, 388 float dstRight, float dstBottom, const SkPaint* paint) { 389 addOp(DisplayList::DrawBitmapRect); 390 addBitmap(bitmap); 391 addBounds(srcLeft, srcTop, srcRight, srcBottom); 392 addBounds(dstLeft, dstTop, dstRight, dstBottom); 393 addPaint(paint); 394} 395 396void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, 397 uint32_t width, uint32_t height, float left, float top, float right, float bottom, 398 const SkPaint* paint) { 399 addOp(DisplayList::DrawPatch); 400 addBitmap(bitmap); 401 addInts(xDivs, width); 402 addInts(yDivs, height); 403 addBounds(left, top, right, bottom); 404 addPaint(paint); 405} 406 407void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { 408 addOp(DisplayList::DrawColor); 409 addInt(color); 410 addInt(mode); 411} 412 413void DisplayListRenderer::drawRect(float left, float top, float right, float bottom, 414 const SkPaint* paint) { 415 addOp(DisplayList::DrawRect); 416 addBounds(left, top, right, bottom); 417 addPaint(paint); 418} 419 420void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) { 421 addOp(DisplayList::DrawPath); 422 addPath(path); 423 addPaint(paint); 424} 425 426void DisplayListRenderer::drawLines(float* points, int count, const SkPaint* paint) { 427 addOp(DisplayList::DrawLines); 428 addFloats(points, count); 429 addPaint(paint); 430} 431 432void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, 433 float x, float y, SkPaint* paint) { 434 addOp(DisplayList::DrawText); 435 addText(text, bytesCount); 436 addInt(count); 437 addPoint(x, y); 438 addPaint(paint); 439} 440 441void DisplayListRenderer::resetShader() { 442 addOp(DisplayList::ResetShader); 443 OpenGLRenderer::resetShader(); 444} 445 446void DisplayListRenderer::setupShader(SkiaShader* shader) { 447 // TODO: Implement 448 OpenGLRenderer::setupShader(shader); 449} 450 451void DisplayListRenderer::resetColorFilter() { 452 addOp(DisplayList::ResetColorFilter); 453 OpenGLRenderer::resetColorFilter(); 454} 455 456void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) { 457 // TODO: Implement 458 OpenGLRenderer::setupColorFilter(filter); 459} 460 461void DisplayListRenderer::resetShadow() { 462 addOp(DisplayList::ResetShadow); 463 OpenGLRenderer::resetShadow(); 464} 465 466void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) { 467 addOp(DisplayList::SetupShadow); 468 addFloat(radius); 469 addPoint(dx, dy); 470 addInt(color); 471 OpenGLRenderer::setupShadow(radius, dx, dy, color); 472} 473 474/////////////////////////////////////////////////////////////////////////////// 475// Recording management 476/////////////////////////////////////////////////////////////////////////////// 477 478int DisplayListRenderer::find(SkTDArray<const SkFlatPaint*>& paints, const SkPaint* paint) { 479 if (paint == NULL) { 480 return 0; 481 } 482 483 SkFlatPaint* flat = SkFlatPaint::Flatten(&mHeap, *paint, mPaintIndex, 484 &mRCRecorder, &mTFRecorder); 485 int index = SkTSearch<SkFlatData>((const SkFlatData**) paints.begin(), 486 paints.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare); 487 if (index >= 0) { 488 (void) mHeap.unalloc(flat); 489 return paints[index]->index(); 490 } 491 492 index = ~index; 493 *paints.insert(index) = flat; 494 return mPaintIndex++; 495} 496 497int DisplayListRenderer::find(SkTDArray<const SkFlatMatrix*>& matrices, const SkMatrix* matrix) { 498 if (matrix == NULL) { 499 return 0; 500 } 501 502 SkFlatMatrix* flat = SkFlatMatrix::Flatten(&mHeap, *matrix, mMatrixIndex); 503 int index = SkTSearch<SkFlatData>((const SkFlatData**) matrices.begin(), 504 matrices.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare); 505 if (index >= 0) { 506 (void) mHeap.unalloc(flat); 507 return matrices[index]->index(); 508 } 509 index = ~index; 510 *matrices.insert(index) = flat; 511 return mMatrixIndex++; 512} 513 514int DisplayListRenderer::find(SkTDArray<const SkFlatBitmap*>& bitmaps, const SkBitmap& bitmap) { 515 SkFlatBitmap* flat = SkFlatBitmap::Flatten(&mHeap, bitmap, mBitmapIndex, &mRCRecorder); 516 int index = SkTSearch<SkFlatData>((const SkFlatData**) bitmaps.begin(), 517 bitmaps.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare); 518 if (index >= 0) { 519 (void) mHeap.unalloc(flat); 520 return bitmaps[index]->index(); 521 } 522 index = ~index; 523 *bitmaps.insert(index) = flat; 524 return mBitmapIndex++; 525} 526 527}; // namespace uirenderer 528}; // namespace android 529