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