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