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