DisplayListOp.h revision c3566d06421c8acc0aafb18f7e307e5725ce87e1
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 virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount, 78 uint32_t level, bool caching, int multipliedAlpha) = 0; 79 80 // same as replay above, but draw operations will defer into the deferredList if possible 81 // NOTE: colorfilters, paintfilters, shaders, shadow, and complex clips prevent deferral 82 virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount, 83 uint32_t level, bool caching, int multipliedAlpha, 84 DeferredDisplayList& deferredList) = 0; 85 86 virtual void output(int level, uint32_t flags = 0) = 0; 87 88 // NOTE: it would be nice to declare constants and overriding the implementation in each op to 89 // point at the constants, but that seems to require a .cpp file 90 virtual const char* name() = 0; 91}; 92 93class StateOp : public DisplayListOp { 94public: 95 StateOp() {}; 96 97 virtual ~StateOp() {} 98 99 virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount, 100 uint32_t level, bool caching, int multipliedAlpha) { 101 applyState(renderer, saveCount); 102 return DrawGlInfo::kStatusDone; 103 } 104 105 /** 106 * State operations are applied directly to the renderer, but can cause the deferred drawing op 107 * list to flush 108 */ 109 virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount, 110 uint32_t level, bool caching, int multipliedAlpha, DeferredDisplayList& deferredList) { 111 status_t status = DrawGlInfo::kStatusDone; 112 if (requiresDrawOpFlush()) { 113 // will be setting renderer state that affects ops in deferredList, so flush list first 114 status |= deferredList.flush(renderer, dirty, flags, level); 115 } 116 applyState(renderer, saveCount); 117 return status; 118 } 119 120 virtual void applyState(OpenGLRenderer& renderer, int saveCount) = 0; 121 122 /** 123 * Returns true if it affects renderer drawing state in such a way to break deferral 124 * see OpenGLRenderer::disallowDeferral() 125 */ 126 virtual bool requiresDrawOpFlush() { return false; } 127}; 128 129class DrawOp : public DisplayListOp { 130public: 131 DrawOp(SkPaint* paint) 132 : mPaint(paint), mQuickRejected(false) {} 133 134 virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount, 135 uint32_t level, bool caching, int multipliedAlpha) { 136 if (mQuickRejected && CC_LIKELY(flags & DisplayList::kReplayFlag_ClipChildren)) { 137 return DrawGlInfo::kStatusDone; 138 } 139 140 return applyDraw(renderer, dirty, level, caching, multipliedAlpha); 141 } 142 143 /** Draw operations are stored in the deferredList with information necessary for playback */ 144 virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount, 145 uint32_t level, bool caching, int multipliedAlpha, DeferredDisplayList& deferredList) { 146 if (mQuickRejected && CC_LIKELY(flags & DisplayList::kReplayFlag_ClipChildren)) { 147 return DrawGlInfo::kStatusDone; 148 } 149 150 if (renderer.disallowDeferral()) { 151 // dispatch draw immediately, since the renderer's state is too complex for deferral 152 return applyDraw(renderer, dirty, level, caching, multipliedAlpha); 153 } 154 155 if (!caching) multipliedAlpha = -1; 156 state.mMultipliedAlpha = multipliedAlpha; 157 if (!getLocalBounds(state.mBounds)) { 158 // empty bounds signify bounds can't be calculated 159 state.mBounds.setEmpty(); 160 } 161 162 if (!renderer.storeDisplayState(state)) { 163 // op wasn't quick-rejected, so defer 164 deferredList.add(this, renderer.disallowReorder()); 165 } 166 167 return DrawGlInfo::kStatusDone; 168 } 169 170 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 171 bool caching, int multipliedAlpha) = 0; 172 173 // returns true if bounds exist 174 virtual bool getLocalBounds(Rect& localBounds) { return false; } 175 176 // TODO: better refine localbounds usage 177 void setQuickRejected(bool quickRejected) { mQuickRejected = quickRejected; } 178 bool getQuickRejected() { return mQuickRejected; } 179 180 /** Batching disabled by default, turned on for individual ops */ 181 virtual DeferredDisplayList::OpBatchId getBatchId() { 182 return DeferredDisplayList::kOpBatch_None; 183 } 184 185 float strokeWidthOutset() { return mPaint->getStrokeWidth() * 0.5f; } 186 187public: 188 /** 189 * Stores the relevant canvas state of the object between deferral and replay (if the canvas 190 * state supports being stored) See OpenGLRenderer::simpleClipAndState() 191 */ 192 DeferredDisplayState state; 193protected: 194 SkPaint* getPaint(OpenGLRenderer& renderer) { 195 return renderer.filterPaint(mPaint); 196 } 197 198 SkPaint* mPaint; // should be accessed via getPaint() when applying 199 bool mQuickRejected; 200}; 201 202class DrawBoundedOp : public DrawOp { 203public: 204 DrawBoundedOp(float left, float top, float right, float bottom, SkPaint* paint) 205 : DrawOp(paint), mLocalBounds(left, top, right, bottom) {} 206 207 // default constructor for area, to be overridden in child constructor body 208 DrawBoundedOp(SkPaint* paint) 209 : DrawOp(paint) {} 210 211 bool getLocalBounds(Rect& localBounds) { 212 localBounds.set(mLocalBounds); 213 return true; 214 } 215 216protected: 217 Rect mLocalBounds; // displayed area in LOCAL coord. doesn't incorporate stroke, so check paint 218}; 219 220/////////////////////////////////////////////////////////////////////////////// 221// STATE OPERATIONS - these may affect the state of the canvas/renderer, but do 222// not directly draw or alter output 223/////////////////////////////////////////////////////////////////////////////// 224 225class SaveOp : public StateOp { 226public: 227 SaveOp(int flags) 228 : mFlags(flags) {} 229 230 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 231 renderer.save(mFlags); 232 } 233 234 virtual void output(int level, uint32_t flags = 0) { 235 OP_LOG("Save flags %x", mFlags); 236 } 237 238 virtual const char* name() { return "Save"; } 239 240private: 241 int mFlags; 242}; 243 244class RestoreToCountOp : public StateOp { 245public: 246 RestoreToCountOp(int count) 247 : mCount(count) {} 248 249 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 250 renderer.restoreToCount(saveCount + mCount); 251 252 } 253 254 virtual void output(int level, uint32_t flags = 0) { 255 OP_LOG("Restore to count %d", mCount); 256 } 257 258 virtual const char* name() { return "RestoreToCount"; } 259 // Note: don't have to return true for requiresDrawOpFlush - even though restore can create a 260 // complex clip, the clip and matrix are overridden by DeferredDisplayList::flush() 261 262private: 263 int mCount; 264}; 265 266class SaveLayerOp : public StateOp { 267public: 268 SaveLayerOp(float left, float top, float right, float bottom, SkPaint* paint, int flags) 269 : mArea(left, top, right, bottom), mPaint(paint), mFlags(flags) {} 270 271 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 272 SkPaint* paint = renderer.filterPaint(mPaint); 273 renderer.saveLayer(mArea.left, mArea.top, mArea.right, mArea.bottom, paint, mFlags); 274 } 275 276 virtual void output(int level, uint32_t flags = 0) { 277 OP_LOG("SaveLayer of area " RECT_STRING, RECT_ARGS(mArea)); 278 } 279 280 virtual const char* name() { return "SaveLayer"; } 281 virtual bool requiresDrawOpFlush() { return true; } 282 283private: 284 Rect mArea; 285 SkPaint* mPaint; 286 int mFlags; 287}; 288 289class SaveLayerAlphaOp : public StateOp { 290public: 291 SaveLayerAlphaOp(float left, float top, float right, float bottom, int alpha, int flags) 292 : mArea(left, top, right, bottom), mAlpha(alpha), mFlags(flags) {} 293 294 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 295 renderer.saveLayerAlpha(mArea.left, mArea.top, mArea.right, mArea.bottom, mAlpha, mFlags); 296 } 297 298 virtual void output(int level, uint32_t flags = 0) { 299 OP_LOG("SaveLayerAlpha of area " RECT_STRING, RECT_ARGS(mArea)); 300 } 301 302 virtual const char* name() { return "SaveLayerAlpha"; } 303 virtual bool requiresDrawOpFlush() { return true; } 304 305private: 306 Rect mArea; 307 int mAlpha; 308 int mFlags; 309}; 310 311class TranslateOp : public StateOp { 312public: 313 TranslateOp(float dx, float dy) 314 : mDx(dx), mDy(dy) {} 315 316 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 317 renderer.translate(mDx, mDy); 318 } 319 320 virtual void output(int level, uint32_t flags = 0) { 321 OP_LOG("Translate by %f %f", mDx, mDy); 322 } 323 324 virtual const char* name() { return "Translate"; } 325 326private: 327 float mDx; 328 float mDy; 329}; 330 331class RotateOp : public StateOp { 332public: 333 RotateOp(float degrees) 334 : mDegrees(degrees) {} 335 336 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 337 renderer.rotate(mDegrees); 338 } 339 340 virtual void output(int level, uint32_t flags = 0) { 341 OP_LOG("Rotate by %f degrees", mDegrees); 342 } 343 344 virtual const char* name() { return "Rotate"; } 345 346private: 347 float mDegrees; 348}; 349 350class ScaleOp : public StateOp { 351public: 352 ScaleOp(float sx, float sy) 353 : mSx(sx), mSy(sy) {} 354 355 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 356 renderer.scale(mSx, mSy); 357 } 358 359 virtual void output(int level, uint32_t flags = 0) { 360 OP_LOG("Scale by %f %f", mSx, mSy); 361 } 362 363 virtual const char* name() { return "Scale"; } 364 365private: 366 float mSx; 367 float mSy; 368}; 369 370class SkewOp : public StateOp { 371public: 372 SkewOp(float sx, float sy) 373 : mSx(sx), mSy(sy) {} 374 375 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 376 renderer.skew(mSx, mSy); 377 } 378 379 virtual void output(int level, uint32_t flags = 0) { 380 OP_LOG("Skew by %f %f", mSx, mSy); 381 } 382 383 virtual const char* name() { return "Skew"; } 384 385private: 386 float mSx; 387 float mSy; 388}; 389 390class SetMatrixOp : public StateOp { 391public: 392 SetMatrixOp(SkMatrix* matrix) 393 : mMatrix(matrix) {} 394 395 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 396 renderer.setMatrix(mMatrix); 397 } 398 399 virtual void output(int level, uint32_t flags = 0) { 400 OP_LOG("SetMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix)); 401 } 402 403 virtual const char* name() { return "SetMatrix"; } 404 405private: 406 SkMatrix* mMatrix; 407}; 408 409class ConcatMatrixOp : public StateOp { 410public: 411 ConcatMatrixOp(SkMatrix* matrix) 412 : mMatrix(matrix) {} 413 414 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 415 renderer.concatMatrix(mMatrix); 416 } 417 418 virtual void output(int level, uint32_t flags = 0) { 419 OP_LOG("ConcatMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix)); 420 } 421 422 virtual const char* name() { return "ConcatMatrix"; } 423 424private: 425 SkMatrix* mMatrix; 426}; 427 428class ClipRectOp : public StateOp { 429public: 430 ClipRectOp(float left, float top, float right, float bottom, SkRegion::Op op) 431 : mArea(left, top, right, bottom), mOp(op) {} 432 433 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 434 renderer.clipRect(mArea.left, mArea.top, mArea.right, mArea.bottom, mOp); 435 } 436 437 virtual void output(int level, uint32_t flags = 0) { 438 OP_LOG("ClipRect " RECT_STRING, RECT_ARGS(mArea)); 439 } 440 441 virtual const char* name() { return "ClipRect"; } 442 443private: 444 Rect mArea; 445 SkRegion::Op mOp; 446}; 447 448class ClipPathOp : public StateOp { 449public: 450 ClipPathOp(SkPath* path, SkRegion::Op op) 451 : mPath(path), mOp(op) {} 452 453 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 454 renderer.clipPath(mPath, mOp); 455 } 456 457 virtual void output(int level, uint32_t flags = 0) { 458 SkRect bounds = mPath->getBounds(); 459 OP_LOG("ClipPath bounds " RECT_STRING, 460 bounds.left(), bounds.top(), bounds.right(), bounds.bottom()); 461 } 462 463 virtual const char* name() { return "ClipPath"; } 464 virtual bool requiresDrawOpFlush() { return true; } 465 466private: 467 SkPath* mPath; 468 SkRegion::Op mOp; 469}; 470 471class ClipRegionOp : public StateOp { 472public: 473 ClipRegionOp(SkRegion* region, SkRegion::Op op) 474 : mRegion(region), mOp(op) {} 475 476 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 477 renderer.clipRegion(mRegion, mOp); 478 } 479 480 virtual void output(int level, uint32_t flags = 0) { 481 SkIRect bounds = mRegion->getBounds(); 482 OP_LOG("ClipRegion bounds %d %d %d %d", 483 bounds.left(), bounds.top(), bounds.right(), bounds.bottom()); 484 } 485 486 virtual const char* name() { return "ClipRegion"; } 487 virtual bool requiresDrawOpFlush() { return true; } 488 489private: 490 SkRegion* mRegion; 491 SkRegion::Op mOp; 492}; 493 494class ResetShaderOp : public StateOp { 495public: 496 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 497 renderer.resetShader(); 498 } 499 500 virtual void output(int level, uint32_t flags = 0) { 501 OP_LOGS("ResetShader"); 502 } 503 504 virtual const char* name() { return "ResetShader"; } 505}; 506 507class SetupShaderOp : public StateOp { 508public: 509 SetupShaderOp(SkiaShader* shader) 510 : mShader(shader) {} 511 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 512 renderer.setupShader(mShader); 513 } 514 515 virtual void output(int level, uint32_t flags = 0) { 516 OP_LOG("SetupShader, shader %p", mShader); 517 } 518 519 virtual const char* name() { return "SetupShader"; } 520 521private: 522 SkiaShader* mShader; 523}; 524 525class ResetColorFilterOp : public StateOp { 526public: 527 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 528 renderer.resetColorFilter(); 529 } 530 531 virtual void output(int level, uint32_t flags = 0) { 532 OP_LOGS("ResetColorFilter"); 533 } 534 535 virtual const char* name() { return "ResetColorFilter"; } 536}; 537 538class SetupColorFilterOp : public StateOp { 539public: 540 SetupColorFilterOp(SkiaColorFilter* colorFilter) 541 : mColorFilter(colorFilter) {} 542 543 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 544 renderer.setupColorFilter(mColorFilter); 545 } 546 547 virtual void output(int level, uint32_t flags = 0) { 548 OP_LOG("SetupColorFilter, filter %p", mColorFilter); 549 } 550 551 virtual const char* name() { return "SetupColorFilter"; } 552 553private: 554 SkiaColorFilter* mColorFilter; 555}; 556 557class ResetShadowOp : public StateOp { 558public: 559 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 560 renderer.resetShadow(); 561 } 562 563 virtual void output(int level, uint32_t flags = 0) { 564 OP_LOGS("ResetShadow"); 565 } 566 567 virtual const char* name() { return "ResetShadow"; } 568}; 569 570class SetupShadowOp : public StateOp { 571public: 572 SetupShadowOp(float radius, float dx, float dy, int color) 573 : mRadius(radius), mDx(dx), mDy(dy), mColor(color) {} 574 575 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 576 renderer.setupShadow(mRadius, mDx, mDy, mColor); 577 } 578 579 virtual void output(int level, uint32_t flags = 0) { 580 OP_LOG("SetupShadow, radius %f, %f, %f, color %#x", mRadius, mDx, mDy, mColor); 581 } 582 583 virtual const char* name() { return "SetupShadow"; } 584 585private: 586 float mRadius; 587 float mDx; 588 float mDy; 589 int mColor; 590}; 591 592class ResetPaintFilterOp : public StateOp { 593public: 594 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 595 renderer.resetPaintFilter(); 596 } 597 598 virtual void output(int level, uint32_t flags = 0) { 599 OP_LOGS("ResetPaintFilter"); 600 } 601 602 virtual const char* name() { return "ResetPaintFilter"; } 603}; 604 605class SetupPaintFilterOp : public StateOp { 606public: 607 SetupPaintFilterOp(int clearBits, int setBits) 608 : mClearBits(clearBits), mSetBits(setBits) {} 609 610 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 611 renderer.setupPaintFilter(mClearBits, mSetBits); 612 } 613 614 virtual void output(int level, uint32_t flags = 0) { 615 OP_LOG("SetupPaintFilter, clear %#x, set %#x", mClearBits, mSetBits); 616 } 617 618 virtual const char* name() { return "SetupPaintFilter"; } 619 620private: 621 int mClearBits; 622 int mSetBits; 623}; 624 625 626/////////////////////////////////////////////////////////////////////////////// 627// DRAW OPERATIONS - these are operations that can draw to the canvas's device 628/////////////////////////////////////////////////////////////////////////////// 629 630class DrawBitmapOp : public DrawBoundedOp { 631public: 632 DrawBitmapOp(SkBitmap* bitmap, float left, float top, SkPaint* paint) 633 : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(), 634 paint), 635 mBitmap(bitmap) {} 636 637 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 638 bool caching, int multipliedAlpha) { 639 SkPaint* paint = getPaint(renderer); 640 int oldAlpha = -1; 641 if (caching && multipliedAlpha < 255) { 642 oldAlpha = paint->getAlpha(); 643 paint->setAlpha(multipliedAlpha); 644 } 645 status_t ret = renderer.drawBitmap(mBitmap, mLocalBounds.left, mLocalBounds.top, paint); 646 if (oldAlpha >= 0) { 647 paint->setAlpha(oldAlpha); 648 } 649 return ret; 650 } 651 652 virtual void output(int level, uint32_t flags) { 653 OP_LOG("Draw bitmap %p at %f %f", mBitmap, mLocalBounds.left, mLocalBounds.top); 654 } 655 656 virtual const char* name() { return "DrawBitmap"; } 657 virtual DeferredDisplayList::OpBatchId getBatchId() { 658 return DeferredDisplayList::kOpBatch_Bitmap; 659 } 660 661protected: 662 SkBitmap* mBitmap; 663}; 664 665class DrawBitmapMatrixOp : public DrawBoundedOp { 666public: 667 DrawBitmapMatrixOp(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) 668 : DrawBoundedOp(paint), mBitmap(bitmap), mMatrix(matrix) { 669 mLocalBounds.set(0, 0, bitmap->width(), bitmap->height()); 670 const mat4 transform(*matrix); 671 transform.mapRect(mLocalBounds); 672 } 673 674 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 675 bool caching, int multipliedAlpha) { 676 return renderer.drawBitmap(mBitmap, mMatrix, getPaint(renderer)); 677 } 678 679 virtual void output(int level, uint32_t flags) { 680 OP_LOG("Draw bitmap %p matrix " MATRIX_STRING, mBitmap, MATRIX_ARGS(mMatrix)); 681 } 682 683 virtual const char* name() { return "DrawBitmap"; } 684 virtual DeferredDisplayList::OpBatchId getBatchId() { 685 return DeferredDisplayList::kOpBatch_Bitmap; 686 } 687 688private: 689 SkBitmap* mBitmap; 690 SkMatrix* mMatrix; 691}; 692 693class DrawBitmapRectOp : public DrawBoundedOp { 694public: 695 DrawBitmapRectOp(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, 696 float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) 697 : DrawBoundedOp(dstLeft, dstTop, dstRight, dstBottom, paint), 698 mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {} 699 700 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 701 bool caching, int multipliedAlpha) { 702 return renderer.drawBitmap(mBitmap, mSrc.left, mSrc.top, mSrc.right, mSrc.bottom, 703 mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom, 704 getPaint(renderer)); 705 } 706 707 virtual void output(int level, uint32_t flags) { 708 OP_LOG("Draw bitmap %p src="RECT_STRING", dst="RECT_STRING, 709 mBitmap, RECT_ARGS(mSrc), RECT_ARGS(mLocalBounds)); 710 } 711 712 virtual const char* name() { return "DrawBitmapRect"; } 713 virtual DeferredDisplayList::OpBatchId getBatchId() { 714 return DeferredDisplayList::kOpBatch_Bitmap; 715 } 716 717private: 718 SkBitmap* mBitmap; 719 Rect mSrc; 720}; 721 722class DrawBitmapDataOp : public DrawBitmapOp { 723public: 724 DrawBitmapDataOp(SkBitmap* bitmap, float left, float top, SkPaint* paint) 725 : DrawBitmapOp(bitmap, left, top, paint) {} 726 727 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 728 bool caching, int multipliedAlpha) { 729 return renderer.drawBitmapData(mBitmap, mLocalBounds.left, 730 mLocalBounds.top, getPaint(renderer)); 731 } 732 733 virtual void output(int level, uint32_t flags) { 734 OP_LOG("Draw bitmap %p", mBitmap); 735 } 736 737 virtual const char* name() { return "DrawBitmapData"; } 738 virtual DeferredDisplayList::OpBatchId getBatchId() { 739 return DeferredDisplayList::kOpBatch_Bitmap; 740 } 741}; 742 743class DrawBitmapMeshOp : public DrawOp { 744public: 745 DrawBitmapMeshOp(SkBitmap* bitmap, int meshWidth, int meshHeight, 746 float* vertices, int* colors, SkPaint* paint) 747 : DrawOp(paint), mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight), 748 mVertices(vertices), mColors(colors) {} 749 750 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 751 bool caching, int multipliedAlpha) { 752 return renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight, 753 mVertices, mColors, getPaint(renderer)); 754 } 755 756 virtual void output(int level, uint32_t flags) { 757 OP_LOG("Draw bitmap %p mesh %d x %d", mBitmap, mMeshWidth, mMeshHeight); 758 } 759 760 virtual const char* name() { return "DrawBitmapMesh"; } 761 virtual DeferredDisplayList::OpBatchId getBatchId() { 762 return DeferredDisplayList::kOpBatch_Bitmap; 763 } 764 765private: 766 SkBitmap* mBitmap; 767 int mMeshWidth; 768 int mMeshHeight; 769 float* mVertices; 770 int* mColors; 771}; 772 773class DrawPatchOp : public DrawBoundedOp { 774public: 775 DrawPatchOp(SkBitmap* bitmap, const int32_t* xDivs, 776 const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height, 777 int8_t numColors, float left, float top, float right, float bottom, 778 int alpha, SkXfermode::Mode mode) 779 : DrawBoundedOp(left, top, right, bottom, 0), 780 mBitmap(bitmap), mxDivs(xDivs), myDivs(yDivs), 781 mColors(colors), mxDivsCount(width), myDivsCount(height), 782 mNumColors(numColors), mAlpha(alpha), mMode(mode) {}; 783 784 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 785 bool caching, int multipliedAlpha) { 786 // NOTE: not calling the virtual method, which takes a paint 787 return renderer.drawPatch(mBitmap, mxDivs, myDivs, mColors, 788 mxDivsCount, myDivsCount, mNumColors, 789 mLocalBounds.left, mLocalBounds.top, 790 mLocalBounds.right, mLocalBounds.bottom, mAlpha, mMode); 791 } 792 793 virtual void output(int level, uint32_t flags) { 794 OP_LOG("Draw patch "RECT_STRING, RECT_ARGS(mLocalBounds)); 795 } 796 797 virtual const char* name() { return "DrawPatch"; } 798 virtual DeferredDisplayList::OpBatchId getBatchId() { 799 return DeferredDisplayList::kOpBatch_Patch; 800 } 801 802private: 803 SkBitmap* mBitmap; 804 const int32_t* mxDivs; 805 const int32_t* myDivs; 806 const uint32_t* mColors; 807 uint32_t mxDivsCount; 808 uint32_t myDivsCount; 809 int8_t mNumColors; 810 int mAlpha; 811 SkXfermode::Mode mMode; 812}; 813 814class DrawColorOp : public DrawOp { 815public: 816 DrawColorOp(int color, SkXfermode::Mode mode) 817 : DrawOp(0), mColor(color), mMode(mode) {}; 818 819 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 820 bool caching, int multipliedAlpha) { 821 return renderer.drawColor(mColor, mMode); 822 } 823 824 virtual void output(int level, uint32_t flags) { 825 OP_LOG("Draw color %#x, mode %d", mColor, mMode); 826 } 827 828 virtual const char* name() { return "DrawColor"; } 829 830private: 831 int mColor; 832 SkXfermode::Mode mMode; 833}; 834 835class DrawStrokableOp : public DrawBoundedOp { 836public: 837 DrawStrokableOp(float left, float top, float right, float bottom, SkPaint* paint) 838 : DrawBoundedOp(left, top, right, bottom, paint) {}; 839 840 bool getLocalBounds(Rect& localBounds) { 841 localBounds.set(mLocalBounds); 842 if (mPaint && mPaint->getStyle() != SkPaint::kFill_Style) { 843 localBounds.outset(strokeWidthOutset()); 844 } 845 return true; 846 } 847 848 virtual DeferredDisplayList::OpBatchId getBatchId() { 849 if (mPaint->getPathEffect()) { 850 return DeferredDisplayList::kOpBatch_AlphaMaskTexture; 851 } 852 return mPaint->isAntiAlias() ? 853 DeferredDisplayList::kOpBatch_AlphaVertices : 854 DeferredDisplayList::kOpBatch_Vertices; 855 } 856}; 857 858class DrawRectOp : public DrawStrokableOp { 859public: 860 DrawRectOp(float left, float top, float right, float bottom, SkPaint* paint) 861 : DrawStrokableOp(left, top, right, bottom, paint) {} 862 863 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 864 bool caching, int multipliedAlpha) { 865 return renderer.drawRect(mLocalBounds.left, mLocalBounds.top, 866 mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer)); 867 } 868 869 virtual void output(int level, uint32_t flags) { 870 OP_LOG("Draw Rect "RECT_STRING, RECT_ARGS(mLocalBounds)); 871 } 872 873 virtual const char* name() { return "DrawRect"; } 874}; 875 876class DrawRectsOp : public DrawOp { 877public: 878 DrawRectsOp(const float* rects, int count, SkPaint* paint) 879 : DrawOp(paint), mRects(rects), mCount(count) {} 880 881 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 882 bool caching, int multipliedAlpha) { 883 return renderer.drawRects(mRects, mCount, getPaint(renderer)); 884 } 885 886 virtual void output(int level, uint32_t flags) { 887 OP_LOG("Draw Rects count %d", mCount); 888 } 889 890 virtual const char* name() { return "DrawRects"; } 891 892 virtual DeferredDisplayList::OpBatchId getBatchId() { 893 return DeferredDisplayList::kOpBatch_Vertices; 894 } 895 896private: 897 const float* mRects; 898 int mCount; 899}; 900 901class DrawRoundRectOp : public DrawStrokableOp { 902public: 903 DrawRoundRectOp(float left, float top, float right, float bottom, 904 float rx, float ry, SkPaint* paint) 905 : DrawStrokableOp(left, top, right, bottom, paint), mRx(rx), mRy(ry) {} 906 907 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 908 bool caching, int multipliedAlpha) { 909 return renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top, 910 mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, getPaint(renderer)); 911 } 912 913 virtual void output(int level, uint32_t flags) { 914 OP_LOG("Draw RoundRect "RECT_STRING", rx %f, ry %f", RECT_ARGS(mLocalBounds), mRx, mRy); 915 } 916 917 virtual const char* name() { return "DrawRoundRect"; } 918 919private: 920 float mRx; 921 float mRy; 922}; 923 924class DrawCircleOp : public DrawStrokableOp { 925public: 926 DrawCircleOp(float x, float y, float radius, SkPaint* paint) 927 : DrawStrokableOp(x - radius, y - radius, x + radius, y + radius, paint), 928 mX(x), mY(y), mRadius(radius) {} 929 930 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 931 bool caching, int multipliedAlpha) { 932 return renderer.drawCircle(mX, mY, mRadius, getPaint(renderer)); 933 } 934 935 virtual void output(int level, uint32_t flags) { 936 OP_LOG("Draw Circle x %f, y %f, r %f", mX, mY, mRadius); 937 } 938 939 virtual const char* name() { return "DrawCircle"; } 940 941private: 942 float mX; 943 float mY; 944 float mRadius; 945}; 946 947class DrawOvalOp : public DrawStrokableOp { 948public: 949 DrawOvalOp(float left, float top, float right, float bottom, SkPaint* paint) 950 : DrawStrokableOp(left, top, right, bottom, paint) {} 951 952 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 953 bool caching, int multipliedAlpha) { 954 return renderer.drawOval(mLocalBounds.left, mLocalBounds.top, 955 mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer)); 956 } 957 958 virtual void output(int level, uint32_t flags) { 959 OP_LOG("Draw Oval "RECT_STRING, RECT_ARGS(mLocalBounds)); 960 } 961 962 virtual const char* name() { return "DrawOval"; } 963}; 964 965class DrawArcOp : public DrawStrokableOp { 966public: 967 DrawArcOp(float left, float top, float right, float bottom, 968 float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) 969 : DrawStrokableOp(left, top, right, bottom, paint), 970 mStartAngle(startAngle), mSweepAngle(sweepAngle), mUseCenter(useCenter) {} 971 972 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 973 bool caching, int multipliedAlpha) { 974 return renderer.drawArc(mLocalBounds.left, mLocalBounds.top, 975 mLocalBounds.right, mLocalBounds.bottom, 976 mStartAngle, mSweepAngle, mUseCenter, getPaint(renderer)); 977 } 978 979 virtual void output(int level, uint32_t flags) { 980 OP_LOG("Draw Arc "RECT_STRING", start %f, sweep %f, useCenter %d", 981 RECT_ARGS(mLocalBounds), mStartAngle, mSweepAngle, mUseCenter); 982 } 983 984 virtual const char* name() { return "DrawArc"; } 985 986private: 987 float mStartAngle; 988 float mSweepAngle; 989 bool mUseCenter; 990}; 991 992class DrawPathOp : public DrawBoundedOp { 993public: 994 DrawPathOp(SkPath* path, SkPaint* paint) 995 : DrawBoundedOp(paint), mPath(path) { 996 float left, top, offset; 997 uint32_t width, height; 998 computePathBounds(path, paint, left, top, offset, width, height); 999 left -= offset; 1000 top -= offset; 1001 mLocalBounds.set(left, top, left + width, top + height); 1002 } 1003 1004 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1005 bool caching, int multipliedAlpha) { 1006 return renderer.drawPath(mPath, getPaint(renderer)); 1007 } 1008 1009 virtual void output(int level, uint32_t flags) { 1010 OP_LOG("Draw Path %p in "RECT_STRING, mPath, RECT_ARGS(mLocalBounds)); 1011 } 1012 1013 virtual const char* name() { return "DrawPath"; } 1014 1015 virtual DeferredDisplayList::OpBatchId getBatchId() { 1016 return DeferredDisplayList::kOpBatch_AlphaMaskTexture; 1017 } 1018private: 1019 SkPath* mPath; 1020}; 1021 1022class DrawLinesOp : public DrawBoundedOp { 1023public: 1024 DrawLinesOp(float* points, int count, SkPaint* paint) 1025 : DrawBoundedOp(paint), mPoints(points), mCount(count) { 1026 for (int i = 0; i < count; i += 2) { 1027 mLocalBounds.left = fminf(mLocalBounds.left, points[i]); 1028 mLocalBounds.right = fmaxf(mLocalBounds.right, points[i]); 1029 mLocalBounds.top = fminf(mLocalBounds.top, points[i+1]); 1030 mLocalBounds.bottom = fmaxf(mLocalBounds.bottom, points[i+1]); 1031 } 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 DrawOp { 1203public: 1204 DrawDisplayListOp(DisplayList* displayList, int flags) 1205 : DrawOp(0), mDisplayList(displayList), mFlags(flags) {} 1206 1207 virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount, 1208 uint32_t level, bool caching, int multipliedAlpha, DeferredDisplayList& deferredList) { 1209 if (mDisplayList && mDisplayList->isRenderable()) { 1210 return mDisplayList->replay(renderer, dirty, mFlags, level + 1, &deferredList); 1211 } 1212 return DrawGlInfo::kStatusDone; 1213 } 1214 1215 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1216 bool caching, int multipliedAlpha) { 1217 if (mDisplayList && mDisplayList->isRenderable()) { 1218 return mDisplayList->replay(renderer, dirty, mFlags, level + 1); 1219 } 1220 return DrawGlInfo::kStatusDone; 1221 } 1222 1223 virtual void output(int level, uint32_t flags) { 1224 OP_LOG("Draw Display List %p, flags %#x", mDisplayList, mFlags); 1225 if (mDisplayList && (flags & kOpLogFlag_Recurse)) { 1226 mDisplayList->output(level + 1); 1227 } 1228 } 1229 1230 virtual const char* name() { return "DrawDisplayList"; } 1231 1232private: 1233 DisplayList* mDisplayList; 1234 int mFlags; 1235}; 1236 1237class DrawLayerOp : public DrawOp { 1238public: 1239 DrawLayerOp(Layer* layer, float x, float y, SkPaint* paint) 1240 : DrawOp(paint), mLayer(layer), mX(x), mY(y) {} 1241 1242 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1243 bool caching, int multipliedAlpha) { 1244 int oldAlpha = -1; 1245 1246 if (caching && multipliedAlpha < 255) { 1247 oldAlpha = mLayer->getAlpha(); 1248 mLayer->setAlpha(multipliedAlpha); 1249 } 1250 status_t ret = renderer.drawLayer(mLayer, mX, mY, getPaint(renderer)); 1251 if (oldAlpha >= 0) { 1252 mLayer->setAlpha(oldAlpha); 1253 } 1254 return ret; 1255 } 1256 1257 virtual void output(int level, uint32_t flags) { 1258 OP_LOG("Draw Layer %p at %f %f", mLayer, mX, mY); 1259 } 1260 1261 virtual const char* name() { return "DrawLayer"; } 1262 1263private: 1264 Layer* mLayer; 1265 float mX; 1266 float mY; 1267}; 1268 1269}; // namespace uirenderer 1270}; // namespace android 1271 1272#endif // ANDROID_HWUI_DISPLAY_OPERATION_H 1273