DisplayListOp.h revision 5d11676414b3606792e23c269cf75b44faa1a2af
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()) { 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() { 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() { 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() { 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 437private: 438 Rect mArea; 439 SkRegion::Op mOp; 440}; 441 442class ClipPathOp : public StateOp { 443public: 444 ClipPathOp(SkPath* path, SkRegion::Op op) 445 : mPath(path), mOp(op) {} 446 447 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 448 renderer.clipPath(mPath, mOp); 449 } 450 451 virtual void output(int level, uint32_t flags = 0) { 452 SkRect bounds = mPath->getBounds(); 453 OP_LOG("ClipPath bounds " RECT_STRING, 454 bounds.left(), bounds.top(), bounds.right(), bounds.bottom()); 455 } 456 457 virtual const char* name() { return "ClipPath"; } 458 virtual bool requiresDrawOpFlush() { return true; } 459 460private: 461 SkPath* mPath; 462 SkRegion::Op mOp; 463}; 464 465class ClipRegionOp : public StateOp { 466public: 467 ClipRegionOp(SkRegion* region, SkRegion::Op op) 468 : mRegion(region), mOp(op) {} 469 470 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 471 renderer.clipRegion(mRegion, mOp); 472 } 473 474 virtual void output(int level, uint32_t flags = 0) { 475 SkIRect bounds = mRegion->getBounds(); 476 OP_LOG("ClipRegion bounds %d %d %d %d", 477 bounds.left(), bounds.top(), bounds.right(), bounds.bottom()); 478 } 479 480 virtual const char* name() { return "ClipRegion"; } 481 virtual bool requiresDrawOpFlush() { return true; } 482 483private: 484 SkRegion* mRegion; 485 SkRegion::Op mOp; 486}; 487 488class ResetShaderOp : public StateOp { 489public: 490 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 491 renderer.resetShader(); 492 } 493 494 virtual void output(int level, uint32_t flags = 0) { 495 OP_LOGS("ResetShader"); 496 } 497 498 virtual const char* name() { return "ResetShader"; } 499}; 500 501class SetupShaderOp : public StateOp { 502public: 503 SetupShaderOp(SkiaShader* shader) 504 : mShader(shader) {} 505 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 506 renderer.setupShader(mShader); 507 } 508 509 virtual void output(int level, uint32_t flags = 0) { 510 OP_LOG("SetupShader, shader %p", mShader); 511 } 512 513 virtual const char* name() { return "SetupShader"; } 514 515private: 516 SkiaShader* mShader; 517}; 518 519class ResetColorFilterOp : public StateOp { 520public: 521 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 522 renderer.resetColorFilter(); 523 } 524 525 virtual void output(int level, uint32_t flags = 0) { 526 OP_LOGS("ResetColorFilter"); 527 } 528 529 virtual const char* name() { return "ResetColorFilter"; } 530}; 531 532class SetupColorFilterOp : public StateOp { 533public: 534 SetupColorFilterOp(SkiaColorFilter* colorFilter) 535 : mColorFilter(colorFilter) {} 536 537 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 538 renderer.setupColorFilter(mColorFilter); 539 } 540 541 virtual void output(int level, uint32_t flags = 0) { 542 OP_LOG("SetupColorFilter, filter %p", mColorFilter); 543 } 544 545 virtual const char* name() { return "SetupColorFilter"; } 546 547private: 548 SkiaColorFilter* mColorFilter; 549}; 550 551class ResetShadowOp : public StateOp { 552public: 553 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 554 renderer.resetShadow(); 555 } 556 557 virtual void output(int level, uint32_t flags = 0) { 558 OP_LOGS("ResetShadow"); 559 } 560 561 virtual const char* name() { return "ResetShadow"; } 562}; 563 564class SetupShadowOp : public StateOp { 565public: 566 SetupShadowOp(float radius, float dx, float dy, int color) 567 : mRadius(radius), mDx(dx), mDy(dy), mColor(color) {} 568 569 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 570 renderer.setupShadow(mRadius, mDx, mDy, mColor); 571 } 572 573 virtual void output(int level, uint32_t flags = 0) { 574 OP_LOG("SetupShadow, radius %f, %f, %f, color %#x", mRadius, mDx, mDy, mColor); 575 } 576 577 virtual const char* name() { return "SetupShadow"; } 578 579private: 580 float mRadius; 581 float mDx; 582 float mDy; 583 int mColor; 584}; 585 586class ResetPaintFilterOp : public StateOp { 587public: 588 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 589 renderer.resetPaintFilter(); 590 } 591 592 virtual void output(int level, uint32_t flags = 0) { 593 OP_LOGS("ResetPaintFilter"); 594 } 595 596 virtual const char* name() { return "ResetPaintFilter"; } 597}; 598 599class SetupPaintFilterOp : public StateOp { 600public: 601 SetupPaintFilterOp(int clearBits, int setBits) 602 : mClearBits(clearBits), mSetBits(setBits) {} 603 604 virtual void applyState(OpenGLRenderer& renderer, int saveCount) { 605 renderer.setupPaintFilter(mClearBits, mSetBits); 606 } 607 608 virtual void output(int level, uint32_t flags = 0) { 609 OP_LOG("SetupPaintFilter, clear %#x, set %#x", mClearBits, mSetBits); 610 } 611 612 virtual const char* name() { return "SetupPaintFilter"; } 613 614private: 615 int mClearBits; 616 int mSetBits; 617}; 618 619 620/////////////////////////////////////////////////////////////////////////////// 621// DRAW OPERATIONS - these are operations that can draw to the canvas's device 622/////////////////////////////////////////////////////////////////////////////// 623 624class DrawBitmapOp : public DrawBoundedOp { 625public: 626 DrawBitmapOp(SkBitmap* bitmap, float left, float top, SkPaint* paint) 627 : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(), 628 paint), 629 mBitmap(bitmap) {} 630 631 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 632 bool caching, int multipliedAlpha) { 633 SkPaint* paint = getPaint(renderer); 634 int oldAlpha = -1; 635 if (caching && multipliedAlpha < 255) { 636 oldAlpha = paint->getAlpha(); 637 paint->setAlpha(multipliedAlpha); 638 } 639 status_t ret = renderer.drawBitmap(mBitmap, mLocalBounds.left, mLocalBounds.top, paint); 640 if (oldAlpha >= 0) { 641 paint->setAlpha(oldAlpha); 642 } 643 return ret; 644 } 645 646 virtual void output(int level, uint32_t flags) { 647 OP_LOG("Draw bitmap %p at %f %f", mBitmap, mLocalBounds.left, mLocalBounds.top); 648 } 649 650 virtual const char* name() { return "DrawBitmap"; } 651 virtual DeferredDisplayList::OpBatchId getBatchId() { 652 return DeferredDisplayList::kOpBatch_Bitmap; 653 } 654 655protected: 656 SkBitmap* mBitmap; 657}; 658 659class DrawBitmapMatrixOp : public DrawBoundedOp { 660public: 661 DrawBitmapMatrixOp(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) 662 : DrawBoundedOp(paint), mBitmap(bitmap), mMatrix(matrix) { 663 mLocalBounds.set(0, 0, bitmap->width(), bitmap->height()); 664 const mat4 transform(*matrix); 665 transform.mapRect(mLocalBounds); 666 } 667 668 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 669 bool caching, int multipliedAlpha) { 670 return renderer.drawBitmap(mBitmap, mMatrix, getPaint(renderer)); 671 } 672 673 virtual void output(int level, uint32_t flags) { 674 OP_LOG("Draw bitmap %p matrix " MATRIX_STRING, mBitmap, MATRIX_ARGS(mMatrix)); 675 } 676 677 virtual const char* name() { return "DrawBitmap"; } 678 virtual DeferredDisplayList::OpBatchId getBatchId() { 679 return DeferredDisplayList::kOpBatch_Bitmap; 680 } 681 682private: 683 SkBitmap* mBitmap; 684 SkMatrix* mMatrix; 685}; 686 687class DrawBitmapRectOp : public DrawBoundedOp { 688public: 689 DrawBitmapRectOp(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, 690 float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) 691 : DrawBoundedOp(dstLeft, dstTop, dstRight, dstBottom, paint), 692 mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {} 693 694 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 695 bool caching, int multipliedAlpha) { 696 return renderer.drawBitmap(mBitmap, mSrc.left, mSrc.top, mSrc.right, mSrc.bottom, 697 mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom, 698 getPaint(renderer)); 699 } 700 701 virtual void output(int level, uint32_t flags) { 702 OP_LOG("Draw bitmap %p src="RECT_STRING", dst="RECT_STRING, 703 mBitmap, RECT_ARGS(mSrc), RECT_ARGS(mLocalBounds)); 704 } 705 706 virtual const char* name() { return "DrawBitmapRect"; } 707 virtual DeferredDisplayList::OpBatchId getBatchId() { 708 return DeferredDisplayList::kOpBatch_Bitmap; 709 } 710 711private: 712 SkBitmap* mBitmap; 713 Rect mSrc; 714}; 715 716class DrawBitmapDataOp : public DrawBitmapOp { 717public: 718 DrawBitmapDataOp(SkBitmap* bitmap, float left, float top, SkPaint* paint) 719 : DrawBitmapOp(bitmap, left, top, paint) {} 720 721 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 722 bool caching, int multipliedAlpha) { 723 return renderer.drawBitmapData(mBitmap, mLocalBounds.left, 724 mLocalBounds.top, getPaint(renderer)); 725 } 726 727 virtual void output(int level, uint32_t flags) { 728 OP_LOG("Draw bitmap %p", mBitmap); 729 } 730 731 virtual const char* name() { return "DrawBitmapData"; } 732 virtual DeferredDisplayList::OpBatchId getBatchId() { 733 return DeferredDisplayList::kOpBatch_Bitmap; 734 } 735}; 736 737class DrawBitmapMeshOp : public DrawBoundedOp { 738public: 739 DrawBitmapMeshOp(SkBitmap* bitmap, int meshWidth, int meshHeight, 740 float* vertices, int* colors, SkPaint* paint) 741 : DrawBoundedOp(vertices, 2 * (meshWidth + 1) * (meshHeight + 1), paint), 742 mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight), 743 mVertices(vertices), mColors(colors) {} 744 745 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 746 bool caching, int multipliedAlpha) { 747 return renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight, 748 mVertices, mColors, getPaint(renderer)); 749 } 750 751 virtual void output(int level, uint32_t flags) { 752 OP_LOG("Draw bitmap %p mesh %d x %d", mBitmap, mMeshWidth, mMeshHeight); 753 } 754 755 virtual const char* name() { return "DrawBitmapMesh"; } 756 virtual DeferredDisplayList::OpBatchId getBatchId() { 757 return DeferredDisplayList::kOpBatch_Bitmap; 758 } 759 760private: 761 SkBitmap* mBitmap; 762 int mMeshWidth; 763 int mMeshHeight; 764 float* mVertices; 765 int* mColors; 766}; 767 768class DrawPatchOp : public DrawBoundedOp { 769public: 770 DrawPatchOp(SkBitmap* bitmap, const int32_t* xDivs, 771 const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height, 772 int8_t numColors, float left, float top, float right, float bottom, 773 int alpha, SkXfermode::Mode mode) 774 : DrawBoundedOp(left, top, right, bottom, 0), 775 mBitmap(bitmap), mxDivs(xDivs), myDivs(yDivs), 776 mColors(colors), mxDivsCount(width), myDivsCount(height), 777 mNumColors(numColors), mAlpha(alpha), mMode(mode) {}; 778 779 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 780 bool caching, int multipliedAlpha) { 781 // NOTE: not calling the virtual method, which takes a paint 782 return renderer.drawPatch(mBitmap, mxDivs, myDivs, mColors, 783 mxDivsCount, myDivsCount, mNumColors, 784 mLocalBounds.left, mLocalBounds.top, 785 mLocalBounds.right, mLocalBounds.bottom, mAlpha, mMode); 786 } 787 788 virtual void output(int level, uint32_t flags) { 789 OP_LOG("Draw patch "RECT_STRING, RECT_ARGS(mLocalBounds)); 790 } 791 792 virtual const char* name() { return "DrawPatch"; } 793 virtual DeferredDisplayList::OpBatchId getBatchId() { 794 return DeferredDisplayList::kOpBatch_Patch; 795 } 796 797private: 798 SkBitmap* mBitmap; 799 const int32_t* mxDivs; 800 const int32_t* myDivs; 801 const uint32_t* mColors; 802 uint32_t mxDivsCount; 803 uint32_t myDivsCount; 804 int8_t mNumColors; 805 int mAlpha; 806 SkXfermode::Mode mMode; 807}; 808 809class DrawColorOp : public DrawOp { 810public: 811 DrawColorOp(int color, SkXfermode::Mode mode) 812 : DrawOp(0), mColor(color), mMode(mode) {}; 813 814 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 815 bool caching, int multipliedAlpha) { 816 return renderer.drawColor(mColor, mMode); 817 } 818 819 virtual void output(int level, uint32_t flags) { 820 OP_LOG("Draw color %#x, mode %d", mColor, mMode); 821 } 822 823 virtual const char* name() { return "DrawColor"; } 824 825private: 826 int mColor; 827 SkXfermode::Mode mMode; 828}; 829 830class DrawStrokableOp : public DrawBoundedOp { 831public: 832 DrawStrokableOp(float left, float top, float right, float bottom, SkPaint* paint) 833 : DrawBoundedOp(left, top, right, bottom, paint) {}; 834 835 bool getLocalBounds(Rect& localBounds) { 836 localBounds.set(mLocalBounds); 837 if (mPaint && mPaint->getStyle() != SkPaint::kFill_Style) { 838 localBounds.outset(strokeWidthOutset()); 839 } 840 return true; 841 } 842 843 virtual DeferredDisplayList::OpBatchId getBatchId() { 844 if (mPaint->getPathEffect()) { 845 return DeferredDisplayList::kOpBatch_AlphaMaskTexture; 846 } 847 return mPaint->isAntiAlias() ? 848 DeferredDisplayList::kOpBatch_AlphaVertices : 849 DeferredDisplayList::kOpBatch_Vertices; 850 } 851}; 852 853class DrawRectOp : public DrawStrokableOp { 854public: 855 DrawRectOp(float left, float top, float right, float bottom, SkPaint* paint) 856 : DrawStrokableOp(left, top, right, bottom, paint) {} 857 858 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 859 bool caching, int multipliedAlpha) { 860 return renderer.drawRect(mLocalBounds.left, mLocalBounds.top, 861 mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer)); 862 } 863 864 virtual void output(int level, uint32_t flags) { 865 OP_LOG("Draw Rect "RECT_STRING, RECT_ARGS(mLocalBounds)); 866 } 867 868 virtual const char* name() { return "DrawRect"; } 869}; 870 871class DrawRectsOp : public DrawBoundedOp { 872public: 873 DrawRectsOp(const float* rects, int count, SkPaint* paint) 874 : DrawBoundedOp(rects, count, paint), 875 mRects(rects), mCount(count) {} 876 877 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 878 bool caching, int multipliedAlpha) { 879 return renderer.drawRects(mRects, mCount, getPaint(renderer)); 880 } 881 882 virtual void output(int level, uint32_t flags) { 883 OP_LOG("Draw Rects count %d", mCount); 884 } 885 886 virtual const char* name() { return "DrawRects"; } 887 888 virtual DeferredDisplayList::OpBatchId getBatchId() { 889 return DeferredDisplayList::kOpBatch_Vertices; 890 } 891 892private: 893 const float* mRects; 894 int mCount; 895}; 896 897class DrawRoundRectOp : public DrawStrokableOp { 898public: 899 DrawRoundRectOp(float left, float top, float right, float bottom, 900 float rx, float ry, SkPaint* paint) 901 : DrawStrokableOp(left, top, right, bottom, paint), mRx(rx), mRy(ry) {} 902 903 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 904 bool caching, int multipliedAlpha) { 905 return renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top, 906 mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, getPaint(renderer)); 907 } 908 909 virtual void output(int level, uint32_t flags) { 910 OP_LOG("Draw RoundRect "RECT_STRING", rx %f, ry %f", RECT_ARGS(mLocalBounds), mRx, mRy); 911 } 912 913 virtual const char* name() { return "DrawRoundRect"; } 914 915private: 916 float mRx; 917 float mRy; 918}; 919 920class DrawCircleOp : public DrawStrokableOp { 921public: 922 DrawCircleOp(float x, float y, float radius, SkPaint* paint) 923 : DrawStrokableOp(x - radius, y - radius, x + radius, y + radius, paint), 924 mX(x), mY(y), mRadius(radius) {} 925 926 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 927 bool caching, int multipliedAlpha) { 928 return renderer.drawCircle(mX, mY, mRadius, getPaint(renderer)); 929 } 930 931 virtual void output(int level, uint32_t flags) { 932 OP_LOG("Draw Circle x %f, y %f, r %f", mX, mY, mRadius); 933 } 934 935 virtual const char* name() { return "DrawCircle"; } 936 937private: 938 float mX; 939 float mY; 940 float mRadius; 941}; 942 943class DrawOvalOp : public DrawStrokableOp { 944public: 945 DrawOvalOp(float left, float top, float right, float bottom, SkPaint* paint) 946 : DrawStrokableOp(left, top, right, bottom, paint) {} 947 948 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 949 bool caching, int multipliedAlpha) { 950 return renderer.drawOval(mLocalBounds.left, mLocalBounds.top, 951 mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer)); 952 } 953 954 virtual void output(int level, uint32_t flags) { 955 OP_LOG("Draw Oval "RECT_STRING, RECT_ARGS(mLocalBounds)); 956 } 957 958 virtual const char* name() { return "DrawOval"; } 959}; 960 961class DrawArcOp : public DrawStrokableOp { 962public: 963 DrawArcOp(float left, float top, float right, float bottom, 964 float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) 965 : DrawStrokableOp(left, top, right, bottom, paint), 966 mStartAngle(startAngle), mSweepAngle(sweepAngle), mUseCenter(useCenter) {} 967 968 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 969 bool caching, int multipliedAlpha) { 970 return renderer.drawArc(mLocalBounds.left, mLocalBounds.top, 971 mLocalBounds.right, mLocalBounds.bottom, 972 mStartAngle, mSweepAngle, mUseCenter, getPaint(renderer)); 973 } 974 975 virtual void output(int level, uint32_t flags) { 976 OP_LOG("Draw Arc "RECT_STRING", start %f, sweep %f, useCenter %d", 977 RECT_ARGS(mLocalBounds), mStartAngle, mSweepAngle, mUseCenter); 978 } 979 980 virtual const char* name() { return "DrawArc"; } 981 982private: 983 float mStartAngle; 984 float mSweepAngle; 985 bool mUseCenter; 986}; 987 988class DrawPathOp : public DrawBoundedOp { 989public: 990 DrawPathOp(SkPath* path, SkPaint* paint) 991 : DrawBoundedOp(paint), mPath(path) { 992 float left, top, offset; 993 uint32_t width, height; 994 computePathBounds(path, paint, left, top, offset, width, height); 995 left -= offset; 996 top -= offset; 997 mLocalBounds.set(left, top, left + width, top + height); 998 } 999 1000 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1001 bool caching, int multipliedAlpha) { 1002 return renderer.drawPath(mPath, getPaint(renderer)); 1003 } 1004 1005 virtual void output(int level, uint32_t flags) { 1006 OP_LOG("Draw Path %p in "RECT_STRING, mPath, RECT_ARGS(mLocalBounds)); 1007 } 1008 1009 virtual const char* name() { return "DrawPath"; } 1010 1011 virtual DeferredDisplayList::OpBatchId getBatchId() { 1012 return DeferredDisplayList::kOpBatch_AlphaMaskTexture; 1013 } 1014private: 1015 SkPath* mPath; 1016}; 1017 1018class DrawLinesOp : public DrawBoundedOp { 1019public: 1020 DrawLinesOp(float* points, int count, SkPaint* paint) 1021 : DrawBoundedOp(points, count, paint), 1022 mPoints(points), mCount(count) { 1023 mLocalBounds.outset(strokeWidthOutset()); 1024 } 1025 1026 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1027 bool caching, int multipliedAlpha) { 1028 return renderer.drawLines(mPoints, mCount, getPaint(renderer)); 1029 } 1030 1031 virtual void output(int level, uint32_t flags) { 1032 OP_LOG("Draw Lines count %d", mCount); 1033 } 1034 1035 virtual const char* name() { return "DrawLines"; } 1036 1037 virtual DeferredDisplayList::OpBatchId getBatchId() { 1038 return mPaint->isAntiAlias() ? 1039 DeferredDisplayList::kOpBatch_AlphaVertices : 1040 DeferredDisplayList::kOpBatch_Vertices; 1041 } 1042 1043protected: 1044 float* mPoints; 1045 int mCount; 1046}; 1047 1048class DrawPointsOp : public DrawLinesOp { 1049public: 1050 DrawPointsOp(float* points, int count, SkPaint* paint) 1051 : DrawLinesOp(points, count, paint) {} 1052 1053 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1054 bool caching, int multipliedAlpha) { 1055 return renderer.drawPoints(mPoints, mCount, getPaint(renderer)); 1056 } 1057 1058 virtual void output(int level, uint32_t flags) { 1059 OP_LOG("Draw Points count %d", mCount); 1060 } 1061 1062 virtual const char* name() { return "DrawPoints"; } 1063}; 1064 1065class DrawSomeTextOp : public DrawOp { 1066public: 1067 DrawSomeTextOp(const char* text, int bytesCount, int count, SkPaint* paint) 1068 : DrawOp(paint), mText(text), mBytesCount(bytesCount), mCount(count) {}; 1069 1070 virtual void output(int level, uint32_t flags) { 1071 OP_LOG("Draw some text, %d bytes", mBytesCount); 1072 } 1073 1074 virtual DeferredDisplayList::OpBatchId getBatchId() { 1075 return mPaint->getColor() == 0xff000000 ? 1076 DeferredDisplayList::kOpBatch_Text : 1077 DeferredDisplayList::kOpBatch_ColorText; 1078 } 1079protected: 1080 const char* mText; 1081 int mBytesCount; 1082 int mCount; 1083}; 1084 1085class DrawTextOnPathOp : public DrawSomeTextOp { 1086public: 1087 DrawTextOnPathOp(const char* text, int bytesCount, int count, 1088 SkPath* path, float hOffset, float vOffset, SkPaint* paint) 1089 : DrawSomeTextOp(text, bytesCount, count, paint), 1090 mPath(path), mHOffset(hOffset), mVOffset(vOffset) { 1091 /* TODO: inherit from DrawBounded and init mLocalBounds */ 1092 } 1093 1094 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1095 bool caching, int multipliedAlpha) { 1096 return renderer.drawTextOnPath(mText, mBytesCount, mCount, mPath, 1097 mHOffset, mVOffset, getPaint(renderer)); 1098 } 1099 1100 virtual const char* name() { return "DrawTextOnPath"; } 1101 1102private: 1103 SkPath* mPath; 1104 float mHOffset; 1105 float mVOffset; 1106}; 1107 1108class DrawPosTextOp : public DrawSomeTextOp { 1109public: 1110 DrawPosTextOp(const char* text, int bytesCount, int count, 1111 const float* positions, SkPaint* paint) 1112 : DrawSomeTextOp(text, bytesCount, count, paint), mPositions(positions) { 1113 /* TODO: inherit from DrawBounded and init mLocalBounds */ 1114 } 1115 1116 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1117 bool caching, int multipliedAlpha) { 1118 return renderer.drawPosText(mText, mBytesCount, mCount, mPositions, getPaint(renderer)); 1119 } 1120 1121 virtual const char* name() { return "DrawPosText"; } 1122 1123private: 1124 const float* mPositions; 1125}; 1126 1127class DrawTextOp : public DrawBoundedOp { 1128public: 1129 DrawTextOp(const char* text, int bytesCount, int count, float x, float y, 1130 const float* positions, SkPaint* paint, float length) 1131 : DrawBoundedOp(paint), mText(text), mBytesCount(bytesCount), mCount(count), 1132 mX(x), mY(y), mPositions(positions), mLength(length) { 1133 SkPaint::FontMetrics metrics; 1134 paint->getFontMetrics(&metrics, 0.0f); 1135 mLocalBounds.set(mX, mY + metrics.fTop, mX + length, mY + metrics.fBottom); 1136 } 1137 1138 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1139 bool caching, int multipliedAlpha) { 1140 return renderer.drawText(mText, mBytesCount, mCount, mX, mY, 1141 mPositions, getPaint(renderer), mLength); 1142 } 1143 1144 virtual void output(int level, uint32_t flags) { 1145 OP_LOG("Draw Text of count %d, bytes %d", mCount, mBytesCount); 1146 } 1147 1148 virtual const char* name() { return "DrawText"; } 1149 1150 virtual DeferredDisplayList::OpBatchId getBatchId() { 1151 return mPaint->getColor() == 0xff000000 ? 1152 DeferredDisplayList::kOpBatch_Text : 1153 DeferredDisplayList::kOpBatch_ColorText; 1154 } 1155 1156private: 1157 const char* mText; 1158 int mBytesCount; 1159 int mCount; 1160 float mX; 1161 float mY; 1162 const float* mPositions; 1163 float mLength; 1164}; 1165 1166/////////////////////////////////////////////////////////////////////////////// 1167// SPECIAL DRAW OPERATIONS 1168/////////////////////////////////////////////////////////////////////////////// 1169 1170class DrawFunctorOp : public DrawOp { 1171public: 1172 DrawFunctorOp(Functor* functor) 1173 : DrawOp(0), mFunctor(functor) {} 1174 1175 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1176 bool caching, int multipliedAlpha) { 1177 renderer.startMark("GL functor"); 1178 status_t ret = renderer.callDrawGLFunction(mFunctor, dirty); 1179 renderer.endMark(); 1180 return ret; 1181 } 1182 1183 virtual void output(int level, uint32_t flags) { 1184 OP_LOG("Draw Functor %p", mFunctor); 1185 } 1186 1187 virtual const char* name() { return "DrawFunctor"; } 1188 1189private: 1190 Functor* mFunctor; 1191}; 1192 1193class DrawDisplayListOp : public DrawBoundedOp { 1194public: 1195 DrawDisplayListOp(DisplayList* displayList, int flags) 1196 : DrawBoundedOp(0, 0, displayList->getWidth(), displayList->getHeight(), 0), 1197 mDisplayList(displayList), mFlags(flags) {} 1198 1199 virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount, 1200 uint32_t level, bool caching, int multipliedAlpha, DeferredDisplayList* deferredList) { 1201 if (mDisplayList && mDisplayList->isRenderable()) { 1202 return mDisplayList->replay(renderer, dirty, mFlags, level + 1, deferredList); 1203 } 1204 return DrawGlInfo::kStatusDone; 1205 } 1206 1207 // NOT USED, since replay is overridden 1208 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1209 bool caching, int multipliedAlpha) { return DrawGlInfo::kStatusDone; } 1210 1211 virtual void output(int level, uint32_t flags) { 1212 OP_LOG("Draw Display List %p, flags %#x", mDisplayList, mFlags); 1213 if (mDisplayList && (flags & kOpLogFlag_Recurse)) { 1214 mDisplayList->output(level + 1); 1215 } 1216 } 1217 1218 virtual const char* name() { return "DrawDisplayList"; } 1219 1220private: 1221 DisplayList* mDisplayList; 1222 int mFlags; 1223}; 1224 1225class DrawLayerOp : public DrawOp { 1226public: 1227 DrawLayerOp(Layer* layer, float x, float y, SkPaint* paint) 1228 : DrawOp(paint), mLayer(layer), mX(x), mY(y) {} 1229 1230 virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, 1231 bool caching, int multipliedAlpha) { 1232 int oldAlpha = -1; 1233 1234 if (caching && multipliedAlpha < 255) { 1235 oldAlpha = mLayer->getAlpha(); 1236 mLayer->setAlpha(multipliedAlpha); 1237 } 1238 status_t ret = renderer.drawLayer(mLayer, mX, mY, getPaint(renderer)); 1239 if (oldAlpha >= 0) { 1240 mLayer->setAlpha(oldAlpha); 1241 } 1242 return ret; 1243 } 1244 1245 virtual void output(int level, uint32_t flags) { 1246 OP_LOG("Draw Layer %p at %f %f", mLayer, mX, mY); 1247 } 1248 1249 virtual const char* name() { return "DrawLayer"; } 1250 1251private: 1252 Layer* mLayer; 1253 float mX; 1254 float mY; 1255}; 1256 1257}; // namespace uirenderer 1258}; // namespace android 1259 1260#endif // ANDROID_HWUI_DISPLAY_OPERATION_H 1261