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