DisplayListOp.h revision bd3055f95e67a55648fd84a125e939293115171b
1/* 2 * Copyright (C) 2013 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#ifndef ANDROID_HWUI_DISPLAY_OPERATION_H 18#define ANDROID_HWUI_DISPLAY_OPERATION_H 19 20#ifndef LOG_TAG 21 #define LOG_TAG "OpenGLRenderer" 22#endif 23 24#include <SkXfermode.h> 25 26#include <private/hwui/DrawGlInfo.h> 27 28#include "OpenGLRenderer.h" 29#include "DeferredDisplayList.h" 30#include "DisplayListRenderer.h" 31#include "utils/LinearAllocator.h" 32 33#define CRASH() do { \ 34 *(int *)(uintptr_t)0xbbadbeef = 0; \ 35 ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \ 36} while(false) 37 38#define MATRIX_STRING "[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]" 39#define MATRIX_ARGS(m) \ 40 m->get(0), m->get(1), m->get(2), \ 41 m->get(3), m->get(4), m->get(5), \ 42 m->get(6), m->get(7), m->get(8) 43#define RECT_STRING "%.2f %.2f %.2f %.2f" 44#define RECT_ARGS(r) \ 45 r.left, r.top, r.right, r.bottom 46 47// Use OP_LOG for logging with arglist, OP_LOGS if just printing char* 48#define OP_LOGS(s) OP_LOG("%s", s) 49#define OP_LOG(s, ...) ALOGD( "%*s" s, level * 2, "", __VA_ARGS__ ) 50 51namespace android { 52namespace uirenderer { 53 54/** 55 * Structure for storing canvas operations when they are recorded into a DisplayList, so that they 56 * may be replayed to an OpenGLRenderer. 57 * 58 * To avoid individual memory allocations, DisplayListOps may only be allocated into a 59 * LinearAllocator's managed memory buffers. Each pointer held by a DisplayListOp is either a 60 * pointer into memory also allocated in the LinearAllocator (mostly for text and float buffers) or 61 * references a externally refcounted object (Sk... and Skia... objects). ~DisplayListOp() is 62 * never called as LinearAllocators are simply discarded, so no memory management should be done in 63 * this class. 64 */ 65class DisplayListOp { 66public: 67 // These objects should always be allocated with a LinearAllocator, and never destroyed/deleted. 68 // standard new() intentionally not implemented, and delete/deconstructor should never be used. 69 virtual ~DisplayListOp() { CRASH(); } 70 static void operator delete(void* ptr) { CRASH(); } 71 /** static void* operator new(size_t size); PURPOSELY OMITTED **/ 72 static void* operator new(size_t size, LinearAllocator& allocator) { 73 return allocator.alloc(size); 74 } 75 76 enum OpLogFlag { 77 kOpLogFlag_Recurse = 0x1, 78 kOpLogFlag_JSON = 0x2 // TODO: add? 79 }; 80 81 // If a DeferredDisplayList is supplied, DrawOps will be stored until the list is flushed 82 // NOTE: complex clips and layers prevent deferral 83 virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount, 84 uint32_t level, bool caching, int multipliedAlpha, 85 DeferredDisplayList* deferredList) = 0; 86 87 virtual void output(int level, uint32_t flags = 0) = 0; 88 89 // NOTE: it would be nice to declare constants and overriding the implementation in each op to 90 // point at the constants, but that seems to require a .cpp file 91 virtual const char* name() = 0; 92}; 93 94class StateOp : public DisplayListOp { 95public: 96 StateOp() {}; 97 98 virtual ~StateOp() {} 99 100 /** 101 * State operations are applied directly to the renderer, but can cause the deferred drawing op 102 * list to flush 103 */ 104 virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount, 105 uint32_t level, bool caching, int multipliedAlpha, DeferredDisplayList* deferredList) { 106 status_t status = DrawGlInfo::kStatusDone; 107 if (deferredList && requiresDrawOpFlush(renderer)) { 108 // will be setting renderer state that affects ops in deferredList, so flush list first 109 status |= deferredList->flush(renderer, dirty, flags, level); 110 } 111 applyState(renderer, saveCount); 112 return status; 113 } 114 115 virtual void applyState(OpenGLRenderer& renderer, int saveCount) = 0; 116 117 /** 118 * Returns true if it affects renderer drawing state in such a way to break deferral 119 * see OpenGLRenderer::disallowDeferral() 120 */ 121 virtual bool requiresDrawOpFlush(OpenGLRenderer& renderer) { return false; } 122}; 123 124class DrawOp : public DisplayListOp { 125public: 126 DrawOp(SkPaint* paint) 127 : mPaint(paint), mQuickRejected(false) {} 128 129 /** Draw operations are stored in the deferredList with information necessary for playback */ 130 virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount, 131 uint32_t level, bool caching, int multipliedAlpha, DeferredDisplayList* deferredList) { 132 if (mQuickRejected && CC_LIKELY(flags & DisplayList::kReplayFlag_ClipChildren)) { 133 return DrawGlInfo::kStatusDone; 134 } 135 136 if (!deferredList || renderer.disallowDeferral()) { 137 // dispatch draw immediately, since the renderer's state is too complex for deferral 138 return applyDraw(renderer, dirty, level, caching, multipliedAlpha); 139 } 140 141 if (!caching) multipliedAlpha = -1; 142 state.mMultipliedAlpha = multipliedAlpha; 143 if (!getLocalBounds(state.mBounds)) { 144 // empty bounds signify bounds can't be calculated 145 state.mBounds.setEmpty(); 146 } 147 148 if (!renderer.storeDisplayState(state)) { 149 // op wasn't quick-rejected, so defer 150 deferredList->add(this, renderer.getCaches().drawReorderDisabled); 151 onDrawOpDeferred(renderer); 152 } 153 154 return DrawGlInfo::kStatusDone; 155 } 156 157 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 158 bool caching, int multipliedAlpha) = 0; 159 160 virtual void onDrawOpDeferred(OpenGLRenderer& renderer) { 161 } 162 163 // returns true if bounds exist 164 virtual bool getLocalBounds(Rect& localBounds) { return false; } 165 166 // TODO: better refine localbounds usage 167 void setQuickRejected(bool quickRejected) { mQuickRejected = quickRejected; } 168 bool getQuickRejected() { return mQuickRejected; } 169 170 /** Batching disabled by default, turned on for individual ops */ 171 virtual DeferredDisplayList::OpBatchId getBatchId() { 172 return DeferredDisplayList::kOpBatch_None; 173 } 174 175 float strokeWidthOutset() { return mPaint->getStrokeWidth() * 0.5f; } 176 177 /** 178 * Stores the relevant canvas state of the object between deferral and replay (if the canvas 179 * state supports being stored) See OpenGLRenderer::simpleClipAndState() 180 */ 181 DeferredDisplayState state; 182protected: 183 SkPaint* getPaint(OpenGLRenderer& renderer, bool alwaysCopy = false) { 184 return renderer.filterPaint(mPaint, alwaysCopy); 185 } 186 187 SkPaint* mPaint; // should be accessed via getPaint() when applying 188 bool mQuickRejected; 189}; 190 191class DrawBoundedOp : public DrawOp { 192public: 193 DrawBoundedOp(float left, float top, float right, float bottom, SkPaint* paint) 194 : DrawOp(paint), mLocalBounds(left, top, right, bottom) {} 195 196 // Calculates bounds as smallest rect encompassing all points 197 // NOTE: requires at least 1 vertex, and doesn't account for stroke size (should be handled in 198 // subclass' constructor) 199 DrawBoundedOp(const float* points, int count, SkPaint* paint) 200 : DrawOp(paint), mLocalBounds(points[0], points[1], points[0], points[1]) { 201 for (int i = 2; i < count; i += 2) { 202 mLocalBounds.left = fminf(mLocalBounds.left, points[i]); 203 mLocalBounds.right = fmaxf(mLocalBounds.right, points[i]); 204 mLocalBounds.top = fminf(mLocalBounds.top, points[i + 1]); 205 mLocalBounds.bottom = fmaxf(mLocalBounds.bottom, points[i + 1]); 206 } 207 } 208 209 // default empty constructor for bounds, to be overridden in child constructor body 210 DrawBoundedOp(SkPaint* paint) 211 : DrawOp(paint) {} 212 213 bool getLocalBounds(Rect& localBounds) { 214 localBounds.set(mLocalBounds); 215 return true; 216 } 217 218protected: 219 Rect mLocalBounds; // displayed area in LOCAL coord. doesn't incorporate stroke, so check paint 220}; 221 222/////////////////////////////////////////////////////////////////////////////// 223// STATE OPERATIONS - these may affect the state of the canvas/renderer, but do 224// not directly draw or alter output 225/////////////////////////////////////////////////////////////////////////////// 226 227class SaveOp : public StateOp { 228public: 229 SaveOp(int flags) 230 : mFlags(flags) {} 231 232 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 233 renderer.save(mFlags); 234 } 235 236 virtual void output(int level, uint32_t flags = 0) { 237 OP_LOG("Save flags %x", mFlags); 238 } 239 240 virtual const char* name() { return "Save"; } 241 242private: 243 int mFlags; 244}; 245 246class RestoreToCountOp : public StateOp { 247public: 248 RestoreToCountOp(int count) 249 : mCount(count) {} 250 251 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 252 renderer.restoreToCount(saveCount + mCount); 253 254 } 255 256 virtual void output(int level, uint32_t flags = 0) { 257 OP_LOG("Restore to count %d", mCount); 258 } 259 260 virtual const char* name() { return "RestoreToCount"; } 261 // Note: don't have to return true for requiresDrawOpFlush - even though restore can create a 262 // complex clip, the clip and matrix are overridden by DeferredDisplayList::flush() 263 264private: 265 int mCount; 266}; 267 268class SaveLayerOp : public StateOp { 269public: 270 SaveLayerOp(float left, float top, float right, float bottom, SkPaint* paint, int flags) 271 : mArea(left, top, right, bottom), mPaint(paint), mFlags(flags) {} 272 273 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 274 SkPaint* paint = renderer.filterPaint(mPaint); 275 renderer.saveLayer(mArea.left, mArea.top, mArea.right, mArea.bottom, paint, mFlags); 276 } 277 278 virtual void output(int level, uint32_t flags = 0) { 279 OP_LOG("SaveLayer of area " RECT_STRING, RECT_ARGS(mArea)); 280 } 281 282 virtual const char* name() { return "SaveLayer"; } 283 virtual bool requiresDrawOpFlush(OpenGLRenderer& renderer) { return true; } 284 285private: 286 Rect mArea; 287 SkPaint* mPaint; 288 int mFlags; 289}; 290 291class SaveLayerAlphaOp : public StateOp { 292public: 293 SaveLayerAlphaOp(float left, float top, float right, float bottom, int alpha, int flags) 294 : mArea(left, top, right, bottom), mAlpha(alpha), mFlags(flags) {} 295 296 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 297 renderer.saveLayerAlpha(mArea.left, mArea.top, mArea.right, mArea.bottom, mAlpha, mFlags); 298 } 299 300 virtual void output(int level, uint32_t flags = 0) { 301 OP_LOG("SaveLayerAlpha of area " RECT_STRING, RECT_ARGS(mArea)); 302 } 303 304 virtual const char* name() { return "SaveLayerAlpha"; } 305 virtual bool requiresDrawOpFlush(OpenGLRenderer& renderer) { return true; } 306 307private: 308 Rect mArea; 309 int mAlpha; 310 int mFlags; 311}; 312 313class TranslateOp : public StateOp { 314public: 315 TranslateOp(float dx, float dy) 316 : mDx(dx), mDy(dy) {} 317 318 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 319 renderer.translate(mDx, mDy); 320 } 321 322 virtual void output(int level, uint32_t flags = 0) { 323 OP_LOG("Translate by %f %f", mDx, mDy); 324 } 325 326 virtual const char* name() { return "Translate"; } 327 328private: 329 float mDx; 330 float mDy; 331}; 332 333class RotateOp : public StateOp { 334public: 335 RotateOp(float degrees) 336 : mDegrees(degrees) {} 337 338 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 339 renderer.rotate(mDegrees); 340 } 341 342 virtual void output(int level, uint32_t flags = 0) { 343 OP_LOG("Rotate by %f degrees", mDegrees); 344 } 345 346 virtual const char* name() { return "Rotate"; } 347 348private: 349 float mDegrees; 350}; 351 352class ScaleOp : public StateOp { 353public: 354 ScaleOp(float sx, float sy) 355 : mSx(sx), mSy(sy) {} 356 357 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 358 renderer.scale(mSx, mSy); 359 } 360 361 virtual void output(int level, uint32_t flags = 0) { 362 OP_LOG("Scale by %f %f", mSx, mSy); 363 } 364 365 virtual const char* name() { return "Scale"; } 366 367private: 368 float mSx; 369 float mSy; 370}; 371 372class SkewOp : public StateOp { 373public: 374 SkewOp(float sx, float sy) 375 : mSx(sx), mSy(sy) {} 376 377 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 378 renderer.skew(mSx, mSy); 379 } 380 381 virtual void output(int level, uint32_t flags = 0) { 382 OP_LOG("Skew by %f %f", mSx, mSy); 383 } 384 385 virtual const char* name() { return "Skew"; } 386 387private: 388 float mSx; 389 float mSy; 390}; 391 392class SetMatrixOp : public StateOp { 393public: 394 SetMatrixOp(SkMatrix* matrix) 395 : mMatrix(matrix) {} 396 397 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 398 renderer.setMatrix(mMatrix); 399 } 400 401 virtual void output(int level, uint32_t flags = 0) { 402 OP_LOG("SetMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix)); 403 } 404 405 virtual const char* name() { return "SetMatrix"; } 406 407private: 408 SkMatrix* mMatrix; 409}; 410 411class ConcatMatrixOp : public StateOp { 412public: 413 ConcatMatrixOp(SkMatrix* matrix) 414 : mMatrix(matrix) {} 415 416 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 417 renderer.concatMatrix(mMatrix); 418 } 419 420 virtual void output(int level, uint32_t flags = 0) { 421 OP_LOG("ConcatMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix)); 422 } 423 424 virtual const char* name() { return "ConcatMatrix"; } 425 426private: 427 SkMatrix* mMatrix; 428}; 429 430class ClipRectOp : public StateOp { 431public: 432 ClipRectOp(float left, float top, float right, float bottom, SkRegion::Op op) 433 : mArea(left, top, right, bottom), mOp(op) {} 434 435 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 436 renderer.clipRect(mArea.left, mArea.top, mArea.right, mArea.bottom, mOp); 437 } 438 439 virtual void output(int level, uint32_t flags = 0) { 440 OP_LOG("ClipRect " RECT_STRING, RECT_ARGS(mArea)); 441 } 442 443 virtual const char* name() { return "ClipRect"; } 444 445 virtual bool requiresDrawOpFlush(OpenGLRenderer& renderer) { 446 // TODO: currently, we flush when we *might* cause a clip region to exist. Ideally, we 447 // should only flush when a non-rectangular clip would result 448 return !renderer.hasRectToRectTransform() || !hasRectToRectOp(); 449 } 450 451private: 452 inline bool hasRectToRectOp() { 453 return mOp == SkRegion::kIntersect_Op || mOp == SkRegion::kReplace_Op; 454 } 455 Rect mArea; 456 SkRegion::Op mOp; 457}; 458 459class ClipPathOp : public StateOp { 460public: 461 ClipPathOp(SkPath* path, SkRegion::Op op) 462 : mPath(path), mOp(op) {} 463 464 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 465 renderer.clipPath(mPath, mOp); 466 } 467 468 virtual void output(int level, uint32_t flags = 0) { 469 SkRect bounds = mPath->getBounds(); 470 OP_LOG("ClipPath bounds " RECT_STRING, 471 bounds.left(), bounds.top(), bounds.right(), bounds.bottom()); 472 } 473 474 virtual const char* name() { return "ClipPath"; } 475 virtual bool requiresDrawOpFlush(OpenGLRenderer& renderer) { return true; } 476 477private: 478 SkPath* mPath; 479 SkRegion::Op mOp; 480}; 481 482class ClipRegionOp : public StateOp { 483public: 484 ClipRegionOp(SkRegion* region, SkRegion::Op op) 485 : mRegion(region), mOp(op) {} 486 487 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 488 renderer.clipRegion(mRegion, mOp); 489 } 490 491 virtual void output(int level, uint32_t flags = 0) { 492 SkIRect bounds = mRegion->getBounds(); 493 OP_LOG("ClipRegion bounds %d %d %d %d", 494 bounds.left(), bounds.top(), bounds.right(), bounds.bottom()); 495 } 496 497 virtual const char* name() { return "ClipRegion"; } 498 virtual bool requiresDrawOpFlush(OpenGLRenderer& renderer) { return true; } 499 500private: 501 SkRegion* mRegion; 502 SkRegion::Op mOp; 503}; 504 505class ResetShaderOp : public StateOp { 506public: 507 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 508 renderer.resetShader(); 509 } 510 511 virtual void output(int level, uint32_t flags = 0) { 512 OP_LOGS("ResetShader"); 513 } 514 515 virtual const char* name() { return "ResetShader"; } 516}; 517 518class SetupShaderOp : public StateOp { 519public: 520 SetupShaderOp(SkiaShader* shader) 521 : mShader(shader) {} 522 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 523 renderer.setupShader(mShader); 524 } 525 526 virtual void output(int level, uint32_t flags = 0) { 527 OP_LOG("SetupShader, shader %p", mShader); 528 } 529 530 virtual const char* name() { return "SetupShader"; } 531 532private: 533 SkiaShader* mShader; 534}; 535 536class ResetColorFilterOp : public StateOp { 537public: 538 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 539 renderer.resetColorFilter(); 540 } 541 542 virtual void output(int level, uint32_t flags = 0) { 543 OP_LOGS("ResetColorFilter"); 544 } 545 546 virtual const char* name() { return "ResetColorFilter"; } 547}; 548 549class SetupColorFilterOp : public StateOp { 550public: 551 SetupColorFilterOp(SkiaColorFilter* colorFilter) 552 : mColorFilter(colorFilter) {} 553 554 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 555 renderer.setupColorFilter(mColorFilter); 556 } 557 558 virtual void output(int level, uint32_t flags = 0) { 559 OP_LOG("SetupColorFilter, filter %p", mColorFilter); 560 } 561 562 virtual const char* name() { return "SetupColorFilter"; } 563 564private: 565 SkiaColorFilter* mColorFilter; 566}; 567 568class ResetShadowOp : public StateOp { 569public: 570 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 571 renderer.resetShadow(); 572 } 573 574 virtual void output(int level, uint32_t flags = 0) { 575 OP_LOGS("ResetShadow"); 576 } 577 578 virtual const char* name() { return "ResetShadow"; } 579}; 580 581class SetupShadowOp : public StateOp { 582public: 583 SetupShadowOp(float radius, float dx, float dy, int color) 584 : mRadius(radius), mDx(dx), mDy(dy), mColor(color) {} 585 586 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 587 renderer.setupShadow(mRadius, mDx, mDy, mColor); 588 } 589 590 virtual void output(int level, uint32_t flags = 0) { 591 OP_LOG("SetupShadow, radius %f, %f, %f, color %#x", mRadius, mDx, mDy, mColor); 592 } 593 594 virtual const char* name() { return "SetupShadow"; } 595 596private: 597 float mRadius; 598 float mDx; 599 float mDy; 600 int mColor; 601}; 602 603class ResetPaintFilterOp : public StateOp { 604public: 605 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 606 renderer.resetPaintFilter(); 607 } 608 609 virtual void output(int level, uint32_t flags = 0) { 610 OP_LOGS("ResetPaintFilter"); 611 } 612 613 virtual const char* name() { return "ResetPaintFilter"; } 614}; 615 616class SetupPaintFilterOp : public StateOp { 617public: 618 SetupPaintFilterOp(int clearBits, int setBits) 619 : mClearBits(clearBits), mSetBits(setBits) {} 620 621 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 622 renderer.setupPaintFilter(mClearBits, mSetBits); 623 } 624 625 virtual void output(int level, uint32_t flags = 0) { 626 OP_LOG("SetupPaintFilter, clear %#x, set %#x", mClearBits, mSetBits); 627 } 628 629 virtual const char* name() { return "SetupPaintFilter"; } 630 631private: 632 int mClearBits; 633 int mSetBits; 634}; 635 636 637/////////////////////////////////////////////////////////////////////////////// 638// DRAW OPERATIONS - these are operations that can draw to the canvas's device 639/////////////////////////////////////////////////////////////////////////////// 640 641class DrawBitmapOp : public DrawBoundedOp { 642public: 643 DrawBitmapOp(SkBitmap* bitmap, float left, float top, SkPaint* paint) 644 : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(), 645 paint), 646 mBitmap(bitmap) {} 647 648 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 649 bool caching, int multipliedAlpha) { 650 bool makeCopy = caching && multipliedAlpha < 255; 651 SkPaint* paint = getPaint(renderer, makeCopy); 652 if (makeCopy) { 653 // The paint is safe to modify since we're working on a copy 654 paint->setAlpha(multipliedAlpha); 655 } 656 status_t ret = renderer.drawBitmap(mBitmap, mLocalBounds.left, mLocalBounds.top, paint); 657 return ret; 658 } 659 660 virtual void output(int level, uint32_t flags) { 661 OP_LOG("Draw bitmap %p at %f %f", mBitmap, mLocalBounds.left, mLocalBounds.top); 662 } 663 664 virtual const char* name() { return "DrawBitmap"; } 665 virtual DeferredDisplayList::OpBatchId getBatchId() { 666 return DeferredDisplayList::kOpBatch_Bitmap; 667 } 668 669protected: 670 SkBitmap* mBitmap; 671}; 672 673class DrawBitmapMatrixOp : public DrawBoundedOp { 674public: 675 DrawBitmapMatrixOp(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) 676 : DrawBoundedOp(paint), mBitmap(bitmap), mMatrix(matrix) { 677 mLocalBounds.set(0, 0, bitmap->width(), bitmap->height()); 678 const mat4 transform(*matrix); 679 transform.mapRect(mLocalBounds); 680 } 681 682 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 683 bool caching, int multipliedAlpha) { 684 return renderer.drawBitmap(mBitmap, mMatrix, getPaint(renderer)); 685 } 686 687 virtual void output(int level, uint32_t flags) { 688 OP_LOG("Draw bitmap %p matrix " MATRIX_STRING, mBitmap, MATRIX_ARGS(mMatrix)); 689 } 690 691 virtual const char* name() { return "DrawBitmap"; } 692 virtual DeferredDisplayList::OpBatchId getBatchId() { 693 return DeferredDisplayList::kOpBatch_Bitmap; 694 } 695 696private: 697 SkBitmap* mBitmap; 698 SkMatrix* mMatrix; 699}; 700 701class DrawBitmapRectOp : public DrawBoundedOp { 702public: 703 DrawBitmapRectOp(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, 704 float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) 705 : DrawBoundedOp(dstLeft, dstTop, dstRight, dstBottom, paint), 706 mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {} 707 708 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 709 bool caching, int multipliedAlpha) { 710 return renderer.drawBitmap(mBitmap, mSrc.left, mSrc.top, mSrc.right, mSrc.bottom, 711 mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom, 712 getPaint(renderer)); 713 } 714 715 virtual void output(int level, uint32_t flags) { 716 OP_LOG("Draw bitmap %p src="RECT_STRING", dst="RECT_STRING, 717 mBitmap, RECT_ARGS(mSrc), RECT_ARGS(mLocalBounds)); 718 } 719 720 virtual const char* name() { return "DrawBitmapRect"; } 721 virtual DeferredDisplayList::OpBatchId getBatchId() { 722 return DeferredDisplayList::kOpBatch_Bitmap; 723 } 724 725private: 726 SkBitmap* mBitmap; 727 Rect mSrc; 728}; 729 730class DrawBitmapDataOp : public DrawBitmapOp { 731public: 732 DrawBitmapDataOp(SkBitmap* bitmap, float left, float top, SkPaint* paint) 733 : DrawBitmapOp(bitmap, left, top, paint) {} 734 735 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 736 bool caching, int multipliedAlpha) { 737 return renderer.drawBitmapData(mBitmap, mLocalBounds.left, 738 mLocalBounds.top, getPaint(renderer)); 739 } 740 741 virtual void output(int level, uint32_t flags) { 742 OP_LOG("Draw bitmap %p", mBitmap); 743 } 744 745 virtual const char* name() { return "DrawBitmapData"; } 746 virtual DeferredDisplayList::OpBatchId getBatchId() { 747 return DeferredDisplayList::kOpBatch_Bitmap; 748 } 749}; 750 751class DrawBitmapMeshOp : public DrawBoundedOp { 752public: 753 DrawBitmapMeshOp(SkBitmap* bitmap, int meshWidth, int meshHeight, 754 float* vertices, int* colors, SkPaint* paint) 755 : DrawBoundedOp(vertices, 2 * (meshWidth + 1) * (meshHeight + 1), paint), 756 mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight), 757 mVertices(vertices), mColors(colors) {} 758 759 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 760 bool caching, int multipliedAlpha) { 761 return renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight, 762 mVertices, mColors, getPaint(renderer)); 763 } 764 765 virtual void output(int level, uint32_t flags) { 766 OP_LOG("Draw bitmap %p mesh %d x %d", mBitmap, mMeshWidth, mMeshHeight); 767 } 768 769 virtual const char* name() { return "DrawBitmapMesh"; } 770 virtual DeferredDisplayList::OpBatchId getBatchId() { 771 return DeferredDisplayList::kOpBatch_Bitmap; 772 } 773 774private: 775 SkBitmap* mBitmap; 776 int mMeshWidth; 777 int mMeshHeight; 778 float* mVertices; 779 int* mColors; 780}; 781 782class DrawPatchOp : public DrawBoundedOp { 783public: 784 DrawPatchOp(SkBitmap* bitmap, const int32_t* xDivs, 785 const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height, 786 int8_t numColors, float left, float top, float right, float bottom, 787 int alpha, SkXfermode::Mode mode) 788 : DrawBoundedOp(left, top, right, bottom, 0), 789 mBitmap(bitmap), mxDivs(xDivs), myDivs(yDivs), 790 mColors(colors), mxDivsCount(width), myDivsCount(height), 791 mNumColors(numColors), mAlpha(alpha), mMode(mode) {}; 792 793 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 794 bool caching, int multipliedAlpha) { 795 // NOTE: not calling the virtual method, which takes a paint 796 return renderer.drawPatch(mBitmap, mxDivs, myDivs, mColors, 797 mxDivsCount, myDivsCount, mNumColors, 798 mLocalBounds.left, mLocalBounds.top, 799 mLocalBounds.right, mLocalBounds.bottom, mAlpha, mMode); 800 } 801 802 virtual void output(int level, uint32_t flags) { 803 OP_LOG("Draw patch "RECT_STRING, RECT_ARGS(mLocalBounds)); 804 } 805 806 virtual const char* name() { return "DrawPatch"; } 807 virtual DeferredDisplayList::OpBatchId getBatchId() { 808 return DeferredDisplayList::kOpBatch_Patch; 809 } 810 811private: 812 SkBitmap* mBitmap; 813 const int32_t* mxDivs; 814 const int32_t* myDivs; 815 const uint32_t* mColors; 816 uint32_t mxDivsCount; 817 uint32_t myDivsCount; 818 int8_t mNumColors; 819 int mAlpha; 820 SkXfermode::Mode mMode; 821}; 822 823class DrawColorOp : public DrawOp { 824public: 825 DrawColorOp(int color, SkXfermode::Mode mode) 826 : DrawOp(0), mColor(color), mMode(mode) {}; 827 828 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 829 bool caching, int multipliedAlpha) { 830 return renderer.drawColor(mColor, mMode); 831 } 832 833 virtual void output(int level, uint32_t flags) { 834 OP_LOG("Draw color %#x, mode %d", mColor, mMode); 835 } 836 837 virtual const char* name() { return "DrawColor"; } 838 839private: 840 int mColor; 841 SkXfermode::Mode mMode; 842}; 843 844class DrawStrokableOp : public DrawBoundedOp { 845public: 846 DrawStrokableOp(float left, float top, float right, float bottom, SkPaint* paint) 847 : DrawBoundedOp(left, top, right, bottom, paint) {}; 848 849 bool getLocalBounds(Rect& localBounds) { 850 localBounds.set(mLocalBounds); 851 if (mPaint && mPaint->getStyle() != SkPaint::kFill_Style) { 852 localBounds.outset(strokeWidthOutset()); 853 } 854 return true; 855 } 856 857 virtual DeferredDisplayList::OpBatchId getBatchId() { 858 if (mPaint->getPathEffect()) { 859 return DeferredDisplayList::kOpBatch_AlphaMaskTexture; 860 } 861 return mPaint->isAntiAlias() ? 862 DeferredDisplayList::kOpBatch_AlphaVertices : 863 DeferredDisplayList::kOpBatch_Vertices; 864 } 865}; 866 867class DrawRectOp : public DrawStrokableOp { 868public: 869 DrawRectOp(float left, float top, float right, float bottom, SkPaint* paint) 870 : DrawStrokableOp(left, top, right, bottom, paint) {} 871 872 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 873 bool caching, int multipliedAlpha) { 874 return renderer.drawRect(mLocalBounds.left, mLocalBounds.top, 875 mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer)); 876 } 877 878 virtual void output(int level, uint32_t flags) { 879 OP_LOG("Draw Rect "RECT_STRING, RECT_ARGS(mLocalBounds)); 880 } 881 882 virtual const char* name() { return "DrawRect"; } 883}; 884 885class DrawRectsOp : public DrawBoundedOp { 886public: 887 DrawRectsOp(const float* rects, int count, SkPaint* paint) 888 : DrawBoundedOp(rects, count, paint), 889 mRects(rects), mCount(count) {} 890 891 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 892 bool caching, int multipliedAlpha) { 893 return renderer.drawRects(mRects, mCount, getPaint(renderer)); 894 } 895 896 virtual void output(int level, uint32_t flags) { 897 OP_LOG("Draw Rects count %d", mCount); 898 } 899 900 virtual const char* name() { return "DrawRects"; } 901 902 virtual DeferredDisplayList::OpBatchId getBatchId() { 903 return DeferredDisplayList::kOpBatch_Vertices; 904 } 905 906private: 907 const float* mRects; 908 int mCount; 909}; 910 911class DrawRoundRectOp : public DrawStrokableOp { 912public: 913 DrawRoundRectOp(float left, float top, float right, float bottom, 914 float rx, float ry, SkPaint* paint) 915 : DrawStrokableOp(left, top, right, bottom, paint), mRx(rx), mRy(ry) {} 916 917 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 918 bool caching, int multipliedAlpha) { 919 return renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top, 920 mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, getPaint(renderer)); 921 } 922 923 virtual void output(int level, uint32_t flags) { 924 OP_LOG("Draw RoundRect "RECT_STRING", rx %f, ry %f", RECT_ARGS(mLocalBounds), mRx, mRy); 925 } 926 927 virtual const char* name() { return "DrawRoundRect"; } 928 929private: 930 float mRx; 931 float mRy; 932}; 933 934class DrawCircleOp : public DrawStrokableOp { 935public: 936 DrawCircleOp(float x, float y, float radius, SkPaint* paint) 937 : DrawStrokableOp(x - radius, y - radius, x + radius, y + radius, paint), 938 mX(x), mY(y), mRadius(radius) {} 939 940 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 941 bool caching, int multipliedAlpha) { 942 return renderer.drawCircle(mX, mY, mRadius, getPaint(renderer)); 943 } 944 945 virtual void output(int level, uint32_t flags) { 946 OP_LOG("Draw Circle x %f, y %f, r %f", mX, mY, mRadius); 947 } 948 949 virtual const char* name() { return "DrawCircle"; } 950 951private: 952 float mX; 953 float mY; 954 float mRadius; 955}; 956 957class DrawOvalOp : public DrawStrokableOp { 958public: 959 DrawOvalOp(float left, float top, float right, float bottom, SkPaint* paint) 960 : DrawStrokableOp(left, top, right, bottom, paint) {} 961 962 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 963 bool caching, int multipliedAlpha) { 964 return renderer.drawOval(mLocalBounds.left, mLocalBounds.top, 965 mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer)); 966 } 967 968 virtual void output(int level, uint32_t flags) { 969 OP_LOG("Draw Oval "RECT_STRING, RECT_ARGS(mLocalBounds)); 970 } 971 972 virtual const char* name() { return "DrawOval"; } 973}; 974 975class DrawArcOp : public DrawStrokableOp { 976public: 977 DrawArcOp(float left, float top, float right, float bottom, 978 float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) 979 : DrawStrokableOp(left, top, right, bottom, paint), 980 mStartAngle(startAngle), mSweepAngle(sweepAngle), mUseCenter(useCenter) {} 981 982 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 983 bool caching, int multipliedAlpha) { 984 return renderer.drawArc(mLocalBounds.left, mLocalBounds.top, 985 mLocalBounds.right, mLocalBounds.bottom, 986 mStartAngle, mSweepAngle, mUseCenter, getPaint(renderer)); 987 } 988 989 virtual void output(int level, uint32_t flags) { 990 OP_LOG("Draw Arc "RECT_STRING", start %f, sweep %f, useCenter %d", 991 RECT_ARGS(mLocalBounds), mStartAngle, mSweepAngle, mUseCenter); 992 } 993 994 virtual const char* name() { return "DrawArc"; } 995 996private: 997 float mStartAngle; 998 float mSweepAngle; 999 bool mUseCenter; 1000}; 1001 1002class DrawPathOp : public DrawBoundedOp { 1003public: 1004 DrawPathOp(SkPath* path, SkPaint* paint) 1005 : DrawBoundedOp(paint), mPath(path) { 1006 float left, top, offset; 1007 uint32_t width, height; 1008 PathCache::computePathBounds(path, paint, left, top, offset, width, height); 1009 left -= offset; 1010 top -= offset; 1011 mLocalBounds.set(left, top, left + width, top + height); 1012 } 1013 1014 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1015 bool caching, int multipliedAlpha) { 1016 return renderer.drawPath(mPath, getPaint(renderer)); 1017 } 1018 1019 virtual void onDrawOpDeferred(OpenGLRenderer& renderer) { 1020 SkPaint* paint = getPaint(renderer); 1021 renderer.getCaches().pathCache.precache(mPath, paint); 1022 } 1023 1024 virtual void output(int level, uint32_t flags) { 1025 OP_LOG("Draw Path %p in "RECT_STRING, mPath, RECT_ARGS(mLocalBounds)); 1026 } 1027 1028 virtual const char* name() { return "DrawPath"; } 1029 1030 virtual DeferredDisplayList::OpBatchId getBatchId() { 1031 return DeferredDisplayList::kOpBatch_AlphaMaskTexture; 1032 } 1033private: 1034 SkPath* mPath; 1035}; 1036 1037class DrawLinesOp : public DrawBoundedOp { 1038public: 1039 DrawLinesOp(float* points, int count, SkPaint* paint) 1040 : DrawBoundedOp(points, count, paint), 1041 mPoints(points), mCount(count) { 1042 mLocalBounds.outset(strokeWidthOutset()); 1043 } 1044 1045 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1046 bool caching, int multipliedAlpha) { 1047 return renderer.drawLines(mPoints, mCount, getPaint(renderer)); 1048 } 1049 1050 virtual void output(int level, uint32_t flags) { 1051 OP_LOG("Draw Lines count %d", mCount); 1052 } 1053 1054 virtual const char* name() { return "DrawLines"; } 1055 1056 virtual DeferredDisplayList::OpBatchId getBatchId() { 1057 return mPaint->isAntiAlias() ? 1058 DeferredDisplayList::kOpBatch_AlphaVertices : 1059 DeferredDisplayList::kOpBatch_Vertices; 1060 } 1061 1062protected: 1063 float* mPoints; 1064 int mCount; 1065}; 1066 1067class DrawPointsOp : public DrawLinesOp { 1068public: 1069 DrawPointsOp(float* points, int count, SkPaint* paint) 1070 : DrawLinesOp(points, count, paint) {} 1071 1072 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1073 bool caching, int multipliedAlpha) { 1074 return renderer.drawPoints(mPoints, mCount, getPaint(renderer)); 1075 } 1076 1077 virtual void output(int level, uint32_t flags) { 1078 OP_LOG("Draw Points count %d", mCount); 1079 } 1080 1081 virtual const char* name() { return "DrawPoints"; } 1082}; 1083 1084class DrawSomeTextOp : public DrawOp { 1085public: 1086 DrawSomeTextOp(const char* text, int bytesCount, int count, SkPaint* paint) 1087 : DrawOp(paint), mText(text), mBytesCount(bytesCount), mCount(count) {}; 1088 1089 virtual void output(int level, uint32_t flags) { 1090 OP_LOG("Draw some text, %d bytes", mBytesCount); 1091 } 1092 1093 virtual void onDrawOpDeferred(OpenGLRenderer& renderer) { 1094 SkPaint* paint = getPaint(renderer); 1095 FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint); 1096 fontRenderer.precache(paint, mText, mCount, mat4::identity()); 1097 } 1098 1099 virtual DeferredDisplayList::OpBatchId getBatchId() { 1100 return mPaint->getColor() == 0xff000000 ? 1101 DeferredDisplayList::kOpBatch_Text : 1102 DeferredDisplayList::kOpBatch_ColorText; 1103 } 1104protected: 1105 const char* mText; 1106 int mBytesCount; 1107 int mCount; 1108}; 1109 1110class DrawTextOnPathOp : public DrawSomeTextOp { 1111public: 1112 DrawTextOnPathOp(const char* text, int bytesCount, int count, 1113 SkPath* path, float hOffset, float vOffset, SkPaint* paint) 1114 : DrawSomeTextOp(text, bytesCount, count, paint), 1115 mPath(path), mHOffset(hOffset), mVOffset(vOffset) { 1116 /* TODO: inherit from DrawBounded and init mLocalBounds */ 1117 } 1118 1119 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1120 bool caching, int multipliedAlpha) { 1121 return renderer.drawTextOnPath(mText, mBytesCount, mCount, mPath, 1122 mHOffset, mVOffset, getPaint(renderer)); 1123 } 1124 1125 virtual const char* name() { return "DrawTextOnPath"; } 1126 1127private: 1128 SkPath* mPath; 1129 float mHOffset; 1130 float mVOffset; 1131}; 1132 1133class DrawPosTextOp : public DrawSomeTextOp { 1134public: 1135 DrawPosTextOp(const char* text, int bytesCount, int count, 1136 const float* positions, SkPaint* paint) 1137 : DrawSomeTextOp(text, bytesCount, count, paint), mPositions(positions) { 1138 /* TODO: inherit from DrawBounded and init mLocalBounds */ 1139 } 1140 1141 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1142 bool caching, int multipliedAlpha) { 1143 return renderer.drawPosText(mText, mBytesCount, mCount, mPositions, getPaint(renderer)); 1144 } 1145 1146 virtual const char* name() { return "DrawPosText"; } 1147 1148private: 1149 const float* mPositions; 1150}; 1151 1152class DrawTextOp : public DrawBoundedOp { 1153public: 1154 DrawTextOp(const char* text, int bytesCount, int count, float x, float y, 1155 const float* positions, SkPaint* paint, float length) 1156 : DrawBoundedOp(paint), mText(text), mBytesCount(bytesCount), mCount(count), 1157 mX(x), mY(y), mPositions(positions), mLength(length) { 1158 // duplicates bounds calculation from OpenGLRenderer::drawText, but doesn't alter mX 1159 SkPaint::FontMetrics metrics; 1160 paint->getFontMetrics(&metrics, 0.0f); 1161 switch (paint->getTextAlign()) { 1162 case SkPaint::kCenter_Align: 1163 x -= length / 2.0f; 1164 break; 1165 case SkPaint::kRight_Align: 1166 x -= length; 1167 break; 1168 default: 1169 break; 1170 } 1171 mLocalBounds.set(x, mY + metrics.fTop, x + length, mY + metrics.fBottom); 1172 memset(&mPrecacheTransform.data[0], 0xff, 16 * sizeof(float)); 1173 } 1174 1175 /* 1176 * When this method is invoked the state field is initialized to have the 1177 * final rendering state. We can thus use it to process data as it will be 1178 * used at draw time. 1179 */ 1180 virtual void onDrawOpDeferred(OpenGLRenderer& renderer) { 1181 SkPaint* paint = getPaint(renderer); 1182 FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint); 1183 const mat4& transform = renderer.findBestFontTransform(state.mMatrix); 1184 if (mPrecacheTransform != transform) { 1185 fontRenderer.precache(paint, mText, mCount, transform); 1186 mPrecacheTransform = transform; 1187 } 1188 } 1189 1190 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1191 bool caching, int multipliedAlpha) { 1192 return renderer.drawText(mText, mBytesCount, mCount, mX, mY, 1193 mPositions, getPaint(renderer), mLength); 1194 } 1195 1196 virtual void output(int level, uint32_t flags) { 1197 OP_LOG("Draw Text of count %d, bytes %d", mCount, mBytesCount); 1198 } 1199 1200 virtual const char* name() { return "DrawText"; } 1201 1202 virtual DeferredDisplayList::OpBatchId getBatchId() { 1203 return mPaint->getColor() == 0xff000000 ? 1204 DeferredDisplayList::kOpBatch_Text : 1205 DeferredDisplayList::kOpBatch_ColorText; 1206 } 1207 1208private: 1209 const char* mText; 1210 int mBytesCount; 1211 int mCount; 1212 float mX; 1213 float mY; 1214 const float* mPositions; 1215 float mLength; 1216 mat4 mPrecacheTransform; 1217}; 1218 1219/////////////////////////////////////////////////////////////////////////////// 1220// SPECIAL DRAW OPERATIONS 1221/////////////////////////////////////////////////////////////////////////////// 1222 1223class DrawFunctorOp : public DrawOp { 1224public: 1225 DrawFunctorOp(Functor* functor) 1226 : DrawOp(0), mFunctor(functor) {} 1227 1228 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1229 bool caching, int multipliedAlpha) { 1230 renderer.startMark("GL functor"); 1231 status_t ret = renderer.callDrawGLFunction(mFunctor, dirty); 1232 renderer.endMark(); 1233 return ret; 1234 } 1235 1236 virtual void output(int level, uint32_t flags) { 1237 OP_LOG("Draw Functor %p", mFunctor); 1238 } 1239 1240 virtual const char* name() { return "DrawFunctor"; } 1241 1242private: 1243 Functor* mFunctor; 1244}; 1245 1246class DrawDisplayListOp : public DrawBoundedOp { 1247public: 1248 DrawDisplayListOp(DisplayList* displayList, int flags) 1249 : DrawBoundedOp(0, 0, displayList->getWidth(), displayList->getHeight(), 0), 1250 mDisplayList(displayList), mFlags(flags) {} 1251 1252 virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount, 1253 uint32_t level, bool caching, int multipliedAlpha, DeferredDisplayList* deferredList) { 1254 if (mDisplayList && mDisplayList->isRenderable()) { 1255 return mDisplayList->replay(renderer, dirty, mFlags, level + 1, deferredList); 1256 } 1257 return DrawGlInfo::kStatusDone; 1258 } 1259 1260 // NOT USED, since replay is overridden 1261 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1262 bool caching, int multipliedAlpha) { return DrawGlInfo::kStatusDone; } 1263 1264 virtual void output(int level, uint32_t flags) { 1265 OP_LOG("Draw Display List %p, flags %#x", mDisplayList, mFlags); 1266 if (mDisplayList && (flags & kOpLogFlag_Recurse)) { 1267 mDisplayList->output(level + 1); 1268 } 1269 } 1270 1271 virtual const char* name() { return "DrawDisplayList"; } 1272 1273private: 1274 DisplayList* mDisplayList; 1275 int mFlags; 1276}; 1277 1278class DrawLayerOp : public DrawOp { 1279public: 1280 DrawLayerOp(Layer* layer, float x, float y, SkPaint* paint) 1281 : DrawOp(paint), mLayer(layer), mX(x), mY(y) {} 1282 1283 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1284 bool caching, int multipliedAlpha) { 1285 int oldAlpha = -1; 1286 1287 if (caching && multipliedAlpha < 255) { 1288 oldAlpha = mLayer->getAlpha(); 1289 mLayer->setAlpha(multipliedAlpha); 1290 } 1291 status_t ret = renderer.drawLayer(mLayer, mX, mY, getPaint(renderer)); 1292 if (oldAlpha >= 0) { 1293 mLayer->setAlpha(oldAlpha); 1294 } 1295 return ret; 1296 } 1297 1298 virtual void output(int level, uint32_t flags) { 1299 OP_LOG("Draw Layer %p at %f %f", mLayer, mX, mY); 1300 } 1301 1302 virtual const char* name() { return "DrawLayer"; } 1303 1304private: 1305 Layer* mLayer; 1306 float mX; 1307 float mY; 1308}; 1309 1310}; // namespace uirenderer 1311}; // namespace android 1312 1313#endif // ANDROID_HWUI_DISPLAY_OPERATION_H 1314