1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef GFX_LayerManagerComposite_H 8 #define GFX_LayerManagerComposite_H 9 10 #include <cstdint> // for uint64_t, int32_t 11 #include <deque> // for deque 12 #include <new> // for operator new 13 #include <type_traits> // for remove_reference<>::type 14 #include <utility> // for move, forward 15 #include "CompositableHost.h" // for ImageCompositeNotificationInfo 16 #include "Units.h" // for LayerIntRegion, ParentLayerIntRect, RenderTargetIntRect 17 #include "mozilla/AlreadyAddRefed.h" // for already_AddRefed 18 #include "mozilla/Assertions.h" // for MOZ_CRASH, AssertionConditionType, MOZ_ASSERT, MOZ_AS... 19 #include "mozilla/Maybe.h" // for Maybe 20 #include "mozilla/RefPtr.h" // for RefPtr 21 #include "mozilla/TimeStamp.h" // for TimeStamp, BaseTimeDuration 22 #include "mozilla/UniquePtr.h" // for UniquePtr 23 #include "mozilla/gfx/2D.h" // for DrawTarget 24 #include "mozilla/gfx/Matrix.h" // for Matrix4x4 25 #include "mozilla/gfx/Point.h" // for IntSize 26 #include "mozilla/gfx/Polygon.h" // for Polygon 27 #include "mozilla/gfx/Rect.h" // for IntRect 28 #include "mozilla/gfx/Types.h" // for DeviceColor (ptr only), SurfaceFormat 29 #include "mozilla/layers/CompositionRecorder.h" // for CompositionRecorder, CollectedFrames (ptr only) 30 #include "mozilla/layers/Compositor.h" // for Compositor 31 #include "mozilla/layers/CompositorTypes.h" // for DiagnosticTypes, TextureFactoryIdentifier 32 #include "mozilla/layers/LayerManager.h" // for LayerManager::END_DEFAULT, LayerManager::EndTransacti... 33 #include "mozilla/layers/LayersTypes.h" // for CompositionOpportunityId, LayersBackend, LayersBacken... 34 #include "mozilla/layers/ScreenshotGrabber.h" // for ScreenshotGrabber 35 #include "nsDebug.h" // for NS_WARNING 36 #include "nsIThread.h" // for TimeDuration 37 #include "nsRegion.h" // for nsIntRegion 38 #include "nsRegionFwd.h" // for IntRegion 39 #include "nsStringFwd.h" // for nsCString, nsAString 40 #include "nsTArray.h" // for nsTArray 41 42 class gfxContext; 43 44 #ifdef XP_WIN 45 # include <windows.h> 46 #endif 47 48 namespace mozilla { 49 namespace layers { 50 51 class CanvasLayer; 52 class CanvasLayerComposite; 53 class ColorLayer; 54 class ColorLayerComposite; 55 class ContainerLayer; 56 class ContainerLayerComposite; 57 class Diagnostics; 58 struct EffectChain; 59 class ImageLayer; 60 class ImageLayerComposite; 61 class LayerComposite; 62 class NativeLayer; 63 class NativeLayerRoot; 64 class RefLayerComposite; 65 class PaintTiming; 66 class PaintedLayer; 67 class PaintedLayerComposite; 68 class RefLayer; 69 class SurfacePoolHandle; 70 class TextRenderer; 71 class TextureSourceProvider; 72 class CompositingRenderTarget; 73 struct FPSState; 74 class PaintCounter; 75 class UiCompositorControllerParent; 76 class Layer; 77 struct LayerProperties; 78 79 static const int kVisualWarningDuration = 150; // ms 80 81 // An implementation of LayerManager that acts as a pair with ClientLayerManager 82 // and is mirrored across IPDL. This gets managed/updated by 83 // LayerTransactionParent. 84 class HostLayerManager : public LayerManager { 85 public: 86 HostLayerManager(); 87 virtual ~HostLayerManager(); 88 BeginTransactionWithTarget(gfxContext * aTarget,const nsCString & aURL)89 bool BeginTransactionWithTarget(gfxContext* aTarget, 90 const nsCString& aURL) override { 91 MOZ_CRASH("GFX: Use BeginTransactionWithDrawTarget"); 92 } 93 94 bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) override { 95 MOZ_CRASH("GFX: Use EndTransaction(aTimeStamp)"); 96 return false; 97 } 98 99 void EndTransaction(DrawPaintedLayerCallback aCallback, void* aCallbackData, 100 EndTransactionFlags aFlags = END_DEFAULT) override { 101 MOZ_CRASH("GFX: Use EndTransaction(aTimeStamp)"); 102 } 103 GetMaxTextureSize()104 int32_t GetMaxTextureSize() const override { 105 MOZ_CRASH("GFX: Call on compositor, not LayerManagerComposite"); 106 } 107 GetBackendName(nsAString & name)108 void GetBackendName(nsAString& name) override { 109 MOZ_CRASH("GFX: Shouldn't be called for composited layer manager"); 110 } 111 112 virtual void ForcePresent() = 0; 113 virtual void AddInvalidRegion(const nsIntRegion& aRegion) = 0; 114 NotifyShadowTreeTransaction()115 virtual void NotifyShadowTreeTransaction() {} 116 virtual void BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget, 117 const gfx::IntRect& aRect) = 0; 118 virtual Compositor* GetCompositor() const = 0; 119 virtual TextureSourceProvider* GetTextureSourceProvider() const = 0; 120 virtual void EndTransaction(const TimeStamp& aTimeStamp, 121 EndTransactionFlags aFlags = END_DEFAULT) = 0; UpdateRenderBounds(const gfx::IntRect & aRect)122 virtual void UpdateRenderBounds(const gfx::IntRect& aRect) {} SetDiagnosticTypes(DiagnosticTypes aDiagnostics)123 virtual void SetDiagnosticTypes(DiagnosticTypes aDiagnostics) {} 124 virtual void InvalidateAll() = 0; 125 AsHostLayerManager()126 HostLayerManager* AsHostLayerManager() override { return this; } 127 ExtractImageCompositeNotifications(nsTArray<ImageCompositeNotificationInfo> * aNotifications)128 void ExtractImageCompositeNotifications( 129 nsTArray<ImageCompositeNotificationInfo>* aNotifications) { 130 aNotifications->AppendElements(std::move(mImageCompositeNotifications)); 131 } 132 AppendImageCompositeNotification(const ImageCompositeNotificationInfo & aNotification)133 void AppendImageCompositeNotification( 134 const ImageCompositeNotificationInfo& aNotification) { 135 // Only send composite notifications when we're drawing to the screen, 136 // because that's what they mean. 137 // Also when we're not drawing to the screen, DidComposite will not be 138 // called to extract and send these notifications, so they might linger 139 // and contain stale ImageContainerParent pointers. 140 if (IsCompositingToScreen()) { 141 mImageCompositeNotifications.AppendElement(aNotification); 142 } 143 } 144 145 /** 146 * LayerManagerComposite provides sophisticated debug overlays 147 * that can request a next frame. 148 */ DebugOverlayWantsNextFrame()149 bool DebugOverlayWantsNextFrame() { return mDebugOverlayWantsNextFrame; } SetDebugOverlayWantsNextFrame(bool aVal)150 void SetDebugOverlayWantsNextFrame(bool aVal) { 151 mDebugOverlayWantsNextFrame = aVal; 152 } 153 154 /** 155 * Add an on frame warning. 156 * @param severity ranges from 0 to 1. It's used to compute the warning color. 157 */ VisualFrameWarning(float severity)158 void VisualFrameWarning(float severity) { 159 mozilla::TimeStamp now = TimeStamp::Now(); 160 if (mWarnTime.IsNull() || severity > mWarningLevel || 161 mWarnTime + TimeDuration::FromMilliseconds(kVisualWarningDuration) < 162 now) { 163 mWarnTime = now; 164 mWarningLevel = severity; 165 } 166 } 167 SetPaintTime(const TimeDuration & aPaintTime)168 void SetPaintTime(const TimeDuration& aPaintTime) { 169 mLastPaintTime = aPaintTime; 170 } 171 AlwaysScheduleComposite()172 virtual bool AlwaysScheduleComposite() const { return false; } IsCompositingToScreen()173 virtual bool IsCompositingToScreen() const { return false; } 174 175 void RecordPaintTimes(const PaintTiming& aTiming); 176 void RecordUpdateTime(float aValue); 177 GetCompositionOpportunityId()178 CompositionOpportunityId GetCompositionOpportunityId() const { 179 return mCompositionOpportunityId; 180 } 181 GetCompositionTime()182 TimeStamp GetCompositionTime() const { return mCompositionTime; } SetCompositionTime(TimeStamp aTimeStamp)183 void SetCompositionTime(TimeStamp aTimeStamp) { 184 mCompositionTime = aTimeStamp; 185 if (!mCompositionTime.IsNull() && !mCompositeUntilTime.IsNull() && 186 mCompositionTime >= mCompositeUntilTime) { 187 mCompositeUntilTime = TimeStamp(); 188 } 189 } 190 CompositeUntil(TimeStamp aTimeStamp)191 void CompositeUntil(TimeStamp aTimeStamp) { 192 if (mCompositeUntilTime.IsNull() || mCompositeUntilTime < aTimeStamp) { 193 mCompositeUntilTime = aTimeStamp; 194 } 195 } GetCompositeUntilTime()196 TimeStamp GetCompositeUntilTime() const { return mCompositeUntilTime; } 197 198 // We maintaining a global mapping from ID to CompositorBridgeParent for 199 // async compositables. GetCompositorBridgeID()200 uint64_t GetCompositorBridgeID() const { return mCompositorBridgeID; } SetCompositorBridgeID(uint64_t aID)201 void SetCompositorBridgeID(uint64_t aID) { 202 MOZ_ASSERT(mCompositorBridgeID == 0, 203 "The compositor ID must be set only once."); 204 mCompositorBridgeID = aID; 205 } 206 SetCompositionRecorder(UniquePtr<CompositionRecorder> aRecorder)207 void SetCompositionRecorder(UniquePtr<CompositionRecorder> aRecorder) { 208 mCompositionRecorder = std::move(aRecorder); 209 } 210 211 /** 212 * Write the frames collected by the |CompositionRecorder| to disk. 213 * 214 * If there is not currently a |CompositionRecorder|, this is a no-op. 215 */ 216 void WriteCollectedFrames(); 217 218 Maybe<CollectedFrames> GetCollectedFrames(); 219 220 protected: 221 bool mDebugOverlayWantsNextFrame; 222 nsTArray<ImageCompositeNotificationInfo> mImageCompositeNotifications; 223 // Testing property. If hardware composer is supported, this will return 224 // true if the last frame was deemed 'too complicated' to be rendered. 225 float mWarningLevel; 226 mozilla::TimeStamp mWarnTime; 227 UniquePtr<Diagnostics> mDiagnostics; 228 uint64_t mCompositorBridgeID; 229 230 TimeDuration mLastPaintTime; 231 TimeStamp mRenderStartTime; 232 UniquePtr<CompositionRecorder> mCompositionRecorder = nullptr; 233 234 // Render time for the current composition. 235 TimeStamp mCompositionTime; 236 237 // CompositionOpportunityId of the current composition. 238 CompositionOpportunityId mCompositionOpportunityId; 239 240 // When nonnull, during rendering, some compositable indicated that it will 241 // change its rendering at this time. In order not to miss it, we composite 242 // on every vsync until this time occurs (this is the latest such time). 243 TimeStamp mCompositeUntilTime; 244 #if defined(MOZ_WIDGET_ANDROID) 245 public: 246 // Used by UiCompositorControllerParent to set itself as the target for the 247 // contents of the frame buffer after a composite. 248 // Implemented in LayerManagerComposite RequestScreenPixels(UiCompositorControllerParent * aController)249 virtual void RequestScreenPixels(UiCompositorControllerParent* aController) {} 250 #endif // defined(MOZ_WIDGET_ANDROID) 251 }; 252 253 // A layer manager implementation that uses the Compositor API 254 // to render layers. 255 class LayerManagerComposite final : public HostLayerManager { 256 typedef mozilla::gfx::DrawTarget DrawTarget; 257 typedef mozilla::gfx::IntSize IntSize; 258 typedef mozilla::gfx::SurfaceFormat SurfaceFormat; 259 260 public: 261 explicit LayerManagerComposite(Compositor* aCompositor); 262 virtual ~LayerManagerComposite(); 263 264 void Destroy() override; 265 266 /** 267 * Sets the clipping region for this layer manager. This is important on 268 * windows because using OGL we no longer have GDI's native clipping. Therefor 269 * widget must tell us what part of the screen is being invalidated, 270 * and we should clip to this. 271 * 272 * \param aClippingRegion Region to clip to. Setting an empty region 273 * will disable clipping. 274 */ SetClippingRegion(const nsIntRegion & aClippingRegion)275 void SetClippingRegion(const nsIntRegion& aClippingRegion) { 276 mClippingRegion = aClippingRegion; 277 } 278 279 /** 280 * LayerManager implementation. 281 */ AsLayerManagerComposite()282 LayerManagerComposite* AsLayerManagerComposite() override { return this; } 283 284 void UpdateRenderBounds(const gfx::IntRect& aRect) override; 285 286 bool BeginTransaction(const nsCString& aURL) override; 287 void BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget, 288 const gfx::IntRect& aRect) override; 289 void EndTransaction(const TimeStamp& aTimeStamp, 290 EndTransactionFlags aFlags = END_DEFAULT) override; 291 virtual void EndTransaction( 292 DrawPaintedLayerCallback aCallback, void* aCallbackData, 293 EndTransactionFlags aFlags = END_DEFAULT) override { 294 MOZ_CRASH("GFX: Use EndTransaction(aTimeStamp)"); 295 } 296 297 void SetRoot(Layer* aLayer) override; 298 299 // XXX[nrc]: never called, we should move this logic to ClientLayerManager 300 // (bug 946926). 301 bool CanUseCanvasLayerForSize(const gfx::IntSize& aSize) override; 302 303 void ClearCachedResources(Layer* aSubtree = nullptr) override; 304 305 already_AddRefed<PaintedLayer> CreatePaintedLayer() override; 306 already_AddRefed<ContainerLayer> CreateContainerLayer() override; 307 already_AddRefed<ImageLayer> CreateImageLayer() override; 308 already_AddRefed<ColorLayer> CreateColorLayer() override; 309 already_AddRefed<CanvasLayer> CreateCanvasLayer() override; 310 already_AddRefed<RefLayer> CreateRefLayer() override; 311 312 bool AreComponentAlphaLayersEnabled() override; 313 314 already_AddRefed<DrawTarget> CreateOptimalMaskDrawTarget( 315 const IntSize& aSize) override; 316 Name()317 const char* Name() const override { return ""; } 318 bool IsCompositingToScreen() const override; 319 320 bool AlwaysScheduleComposite() const override; 321 322 /** 323 * Post-processes layers before composition. This performs the following: 324 * 325 * - Applies occlusion culling. This restricts the shadow visible region of 326 * layers that are covered with opaque content. |aOpaqueRegion| is the 327 * region already known to be covered with opaque content, in the 328 * post-transform coordinate space of aLayer. 329 * 330 * - Recomputes visible regions to account for async transforms. 331 * Each layer accumulates into |aVisibleRegion| its post-transform 332 * (including async transforms) visible region. 333 * 334 * - aRenderTargetClip is the exact clip required for aLayer, in the 335 * coordinates of the nearest render target (the same as 336 * GetEffectiveTransform). 337 * 338 * - aClipFromAncestors is the approximate combined clip from all 339 * ancestors, in the coordinate space of our parent, but maybe be an 340 * overestimate in the presence of complex transforms. 341 */ 342 void PostProcessLayers(nsIntRegion& aOpaqueRegion); 343 void PostProcessLayers(Layer* aLayer, nsIntRegion& aOpaqueRegion, 344 LayerIntRegion& aVisibleRegion, 345 const Maybe<RenderTargetIntRect>& aRenderTargetClip, 346 const Maybe<ParentLayerIntRect>& aClipFromAncestors, 347 bool aCanContributeOpaque); 348 349 /** 350 * RAII helper class to add a mask effect with the compositable from 351 * aMaskLayer to the EffectChain aEffect and notify the compositable when we 352 * are done. 353 */ 354 class AutoAddMaskEffect { 355 public: 356 AutoAddMaskEffect(Layer* aMaskLayer, EffectChain& aEffect); 357 ~AutoAddMaskEffect(); 358 Failed()359 bool Failed() const { return mFailed; } 360 361 private: 362 CompositableHost* mCompositable; 363 bool mFailed; 364 }; 365 366 /** 367 * returns true if PlatformAllocBuffer will return a buffer that supports 368 * direct texturing 369 */ 370 static bool SupportsDirectTexturing(); 371 372 static void PlatformSyncBeforeReplyUpdate(); 373 AddInvalidRegion(const nsIntRegion & aRegion)374 void AddInvalidRegion(const nsIntRegion& aRegion) override { 375 mInvalidRegion.Or(mInvalidRegion, aRegion); 376 } 377 GetCompositor()378 Compositor* GetCompositor() const override { return mCompositor; } GetTextureSourceProvider()379 TextureSourceProvider* GetTextureSourceProvider() const override { 380 return mCompositor; 381 } 382 383 void NotifyShadowTreeTransaction() override; 384 GetTextRenderer()385 TextRenderer* GetTextRenderer() { return mTextRenderer; } 386 UnusedApzTransformWarning()387 void UnusedApzTransformWarning() { mUnusedApzTransformWarning = true; } DisabledApzWarning()388 void DisabledApzWarning() { mDisabledApzWarning = true; } 389 390 bool AsyncPanZoomEnabled() const override; 391 392 public: GetTextureFactoryIdentifier()393 TextureFactoryIdentifier GetTextureFactoryIdentifier() override { 394 return mCompositor->GetTextureFactoryIdentifier(); 395 } GetBackendType()396 LayersBackend GetBackendType() override { 397 return mCompositor ? mCompositor->GetBackendType() 398 : LayersBackend::LAYERS_NONE; 399 } SetDiagnosticTypes(DiagnosticTypes aDiagnostics)400 void SetDiagnosticTypes(DiagnosticTypes aDiagnostics) override { 401 mCompositor->SetDiagnosticTypes(aDiagnostics); 402 } 403 InvalidateAll()404 void InvalidateAll() override { 405 AddInvalidRegion(nsIntRegion(mRenderBounds)); 406 } 407 ForcePresent()408 void ForcePresent() override { mCompositor->ForcePresent(); } 409 410 private: 411 /** Region we're clipping our current drawing to. */ 412 nsIntRegion mClippingRegion; 413 gfx::IntRect mRenderBounds; 414 415 /** Current root layer. */ 416 LayerComposite* RootLayer() const; 417 418 /** 419 * Update the invalid region and render it. 420 */ 421 void UpdateAndRender(); 422 423 /** 424 * Render the current layer tree to the active target. 425 * Returns true if the current invalid region can be cleared, false if 426 * rendering was canceled. 427 */ 428 bool Render(const nsIntRegion& aInvalidRegion, 429 const nsIntRegion& aOpaqueRegion); 430 #if defined(MOZ_WIDGET_ANDROID) 431 void RenderToPresentationSurface(); 432 // Shifts the content down so the toolbar does not cover it. 433 // Returns the Y shift of the content in screen pixels 434 ScreenCoord GetContentShiftForToolbar(); 435 // Renders the static snapshot after the content has been rendered. 436 void RenderToolbar(); 437 // Used by robocop tests to get a snapshot of the frame buffer. 438 void HandlePixelsTarget(); 439 #endif 440 441 /** 442 * We need to know our invalid region before we're ready to render. 443 */ 444 void InvalidateDebugOverlay(nsIntRegion& aInvalidRegion, 445 const gfx::IntRect& aBounds); 446 447 /** 448 * Render debug overlays such as the FPS/FrameCounter above the frame. 449 */ 450 void RenderDebugOverlay(const gfx::IntRect& aBounds); 451 452 void DrawBorder(const gfx::IntRect& aOuter, int32_t aBorderWidth, 453 const gfx::DeviceColor& aColor, 454 const gfx::Matrix4x4& aTransform); 455 void DrawTranslationWarningOverlay(const gfx::IntRect& aBounds); 456 457 void UpdateDebugOverlayNativeLayers(); 458 459 RefPtr<CompositingRenderTarget> PushGroupForLayerEffects(); 460 void PopGroupForLayerEffects(RefPtr<CompositingRenderTarget> aPreviousTarget, 461 gfx::IntRect aClipRect, bool aGrayscaleEffect, 462 bool aInvertEffect, float aContrastEffect); 463 464 /** 465 * Create or recycle native layers to cover aRegion or aRect. 466 * This method takes existing layers from the front of aLayersToRecycle (or 467 * creates new layers if no layers are left to recycle) and appends them to 468 * the end of mNativeLayers. The "take from front, add to back" approach keeps 469 * the layer to rect assignment stable between frames. 470 * Updates the rect and opaqueness on the layers. For layers that moved or 471 * resized, *aWindowInvalidRegion is updated to include the area impacted by 472 * the move. 473 * Any layers left in aLayersToRecycle are not needed and can be disposed of. 474 */ 475 void PlaceNativeLayers(const gfx::IntRegion& aRegion, bool aOpaque, 476 std::deque<RefPtr<NativeLayer>>* aLayersToRecycle, 477 gfx::IntRegion* aWindowInvalidRegion); 478 void PlaceNativeLayer(const gfx::IntRect& aRect, bool aOpaque, 479 std::deque<RefPtr<NativeLayer>>* aLayersToRecycle, 480 gfx::IntRegion* aWindowInvalidRegion); 481 482 bool mUnusedApzTransformWarning; 483 bool mDisabledApzWarning; 484 RefPtr<Compositor> mCompositor; 485 UniquePtr<LayerProperties> mClonedLayerTreeProperties; 486 487 /** 488 * Context target, nullptr when drawing directly to our swap chain. 489 */ 490 RefPtr<gfx::DrawTarget> mTarget; 491 gfx::IntRect mTargetBounds; 492 493 nsIntRegion mInvalidRegion; 494 495 bool mInTransaction; 496 bool mIsCompositorReady; 497 498 RefPtr<CompositingRenderTarget> mTwoPassTmpTarget; 499 ScreenshotGrabber mProfilerScreenshotGrabber; 500 RefPtr<TextRenderer> mTextRenderer; 501 RefPtr<NativeLayerRoot> mNativeLayerRoot; 502 RefPtr<SurfacePoolHandle> mSurfacePoolHandle; 503 std::deque<RefPtr<NativeLayer>> mNativeLayers; 504 RefPtr<NativeLayer> mGPUStatsLayer; 505 RefPtr<NativeLayer> mUnusedTransformWarningLayer; 506 RefPtr<NativeLayer> mDisabledApzWarningLayer; 507 508 #ifdef USE_SKIA 509 /** 510 * Render paint and composite times above the frame. 511 */ 512 void DrawPaintTimes(Compositor* aCompositor); 513 RefPtr<PaintCounter> mPaintCounter; 514 #endif 515 #if defined(MOZ_WIDGET_ANDROID) 516 public: RequestScreenPixels(UiCompositorControllerParent * aController)517 virtual void RequestScreenPixels( 518 UiCompositorControllerParent* aController) override { 519 mScreenPixelsTarget = aController; 520 } 521 522 private: 523 UiCompositorControllerParent* mScreenPixelsTarget; 524 #endif // defined(MOZ_WIDGET_ANDROID) 525 }; 526 527 /** 528 * Compositor layers are for use with OMTC on the compositor thread only. There 529 * must be corresponding Client layers on the content thread. For composite 530 * layers, the layer manager only maintains the layer tree. 531 */ 532 class HostLayer { 533 public: HostLayer(HostLayerManager * aManager)534 explicit HostLayer(HostLayerManager* aManager) 535 : mCompositorManager(aManager), 536 mShadowOpacity(1.0), 537 mShadowTransformSetByAnimation(false), 538 mShadowOpacitySetByAnimation(false) {} 539 SetLayerManager(HostLayerManager * aManager)540 virtual void SetLayerManager(HostLayerManager* aManager) { 541 mCompositorManager = aManager; 542 } GetLayerManager()543 HostLayerManager* GetLayerManager() const { return mCompositorManager; } 544 545 virtual ~HostLayer() = default; 546 GetFirstChildComposite()547 virtual LayerComposite* GetFirstChildComposite() { return nullptr; } 548 549 virtual Layer* GetLayer() = 0; 550 SetCompositableHost(CompositableHost *)551 virtual bool SetCompositableHost(CompositableHost*) { 552 // We must handle this gracefully, see bug 967824 553 NS_WARNING( 554 "called SetCompositableHost for a layer type not accepting a " 555 "compositable"); 556 return false; 557 } 558 virtual CompositableHost* GetCompositableHost() = 0; 559 560 /** 561 * The following methods are 562 * 563 * CONSTRUCTION PHASE ONLY 564 * 565 * They are analogous to the Layer interface. 566 */ SetShadowVisibleRegion(const LayerIntRegion & aRegion)567 void SetShadowVisibleRegion(const LayerIntRegion& aRegion) { 568 mShadowVisibleRegion = aRegion; 569 } SetShadowVisibleRegion(LayerIntRegion && aRegion)570 void SetShadowVisibleRegion(LayerIntRegion&& aRegion) { 571 mShadowVisibleRegion = std::move(aRegion); 572 } 573 SetShadowOpacity(float aOpacity)574 void SetShadowOpacity(float aOpacity) { mShadowOpacity = aOpacity; } SetShadowOpacitySetByAnimation(bool aSetByAnimation)575 void SetShadowOpacitySetByAnimation(bool aSetByAnimation) { 576 mShadowOpacitySetByAnimation = aSetByAnimation; 577 } 578 SetShadowClipRect(const Maybe<ParentLayerIntRect> & aRect)579 void SetShadowClipRect(const Maybe<ParentLayerIntRect>& aRect) { 580 mShadowClipRect = aRect; 581 } 582 SetShadowBaseTransform(const gfx::Matrix4x4 & aMatrix)583 void SetShadowBaseTransform(const gfx::Matrix4x4& aMatrix) { 584 mShadowTransform = aMatrix; 585 } SetShadowTransformSetByAnimation(bool aSetByAnimation)586 void SetShadowTransformSetByAnimation(bool aSetByAnimation) { 587 mShadowTransformSetByAnimation = aSetByAnimation; 588 } 589 590 // These getters can be used anytime. GetShadowOpacity()591 float GetShadowOpacity() { return mShadowOpacity; } GetShadowClipRect()592 const Maybe<ParentLayerIntRect>& GetShadowClipRect() { 593 return mShadowClipRect; 594 } GetShadowVisibleRegion()595 virtual const LayerIntRegion& GetShadowVisibleRegion() { 596 return mShadowVisibleRegion; 597 } GetShadowBaseTransform()598 const gfx::Matrix4x4& GetShadowBaseTransform() { return mShadowTransform; } 599 gfx::Matrix4x4 GetShadowTransform(); GetShadowTransformSetByAnimation()600 bool GetShadowTransformSetByAnimation() { 601 return mShadowTransformSetByAnimation; 602 } GetShadowOpacitySetByAnimation()603 bool GetShadowOpacitySetByAnimation() { return mShadowOpacitySetByAnimation; } 604 605 void RecomputeShadowVisibleRegionFromChildren(); 606 607 protected: 608 HostLayerManager* mCompositorManager; 609 610 gfx::Matrix4x4 mShadowTransform; 611 LayerIntRegion mShadowVisibleRegion; 612 Maybe<ParentLayerIntRect> mShadowClipRect; 613 float mShadowOpacity; 614 bool mShadowTransformSetByAnimation; 615 bool mShadowOpacitySetByAnimation; 616 }; 617 618 /** 619 * Composite layers are for use with OMTC on the compositor thread only. There 620 * must be corresponding Client layers on the content thread. For composite 621 * layers, the layer manager only maintains the layer tree, all rendering is 622 * done by a Compositor (see Compositor.h). As such, composite layers are 623 * platform-independent and can be used on any platform for which there is a 624 * Compositor implementation. 625 * 626 * The composite layer tree reflects exactly the basic layer tree. To 627 * composite to screen, the layer manager walks the layer tree calling render 628 * methods which in turn call into their CompositableHosts' Composite methods. 629 * These call Compositor::DrawQuad to do the rendering. 630 * 631 * Mostly, layers are updated during the layers transaction. This is done from 632 * CompositableClient to CompositableHost without interacting with the layer. 633 * 634 * A reference to the Compositor is stored in LayerManagerComposite. 635 */ 636 class LayerComposite : public HostLayer { 637 public: 638 explicit LayerComposite(LayerManagerComposite* aManager); 639 640 virtual ~LayerComposite(); 641 642 void SetLayerManager(HostLayerManager* aManager) override; 643 GetFirstChildComposite()644 LayerComposite* GetFirstChildComposite() override { return nullptr; } 645 646 /* Do NOT call this from the generic LayerComposite destructor. Only from the 647 * concrete class destructor 648 */ 649 virtual void Destroy(); Cleanup()650 virtual void Cleanup() {} 651 652 /** 653 * Perform a first pass over the layer tree to render all of the intermediate 654 * surfaces that we can. This allows us to avoid framebuffer switches in the 655 * middle of our render which is inefficient especially on mobile GPUs. This 656 * must be called before RenderLayer. 657 */ Prepare(const RenderTargetIntRect & aClipRect)658 virtual void Prepare(const RenderTargetIntRect& aClipRect) {} 659 660 // TODO: This should also take RenderTargetIntRect like Prepare. 661 virtual void RenderLayer(const gfx::IntRect& aClipRect, 662 const Maybe<gfx::Polygon>& aGeometry) = 0; 663 SetCompositableHost(CompositableHost *)664 bool SetCompositableHost(CompositableHost*) override { 665 // We must handle this gracefully, see bug 967824 666 NS_WARNING( 667 "called SetCompositableHost for a layer type not accepting a " 668 "compositable"); 669 return false; 670 } 671 672 virtual void CleanupResources() = 0; 673 DestroyFrontBuffer()674 virtual void DestroyFrontBuffer() {} 675 676 void AddBlendModeEffect(EffectChain& aEffectChain); 677 GenEffectChain(EffectChain & aEffect)678 virtual void GenEffectChain(EffectChain& aEffect) {} 679 SetLayerComposited(bool value)680 void SetLayerComposited(bool value) { mLayerComposited = value; } 681 SetClearRect(const gfx::IntRect & aRect)682 void SetClearRect(const gfx::IntRect& aRect) { mClearRect = aRect; } 683 HasLayerBeenComposited()684 bool HasLayerBeenComposited() { return mLayerComposited; } GetClearRect()685 gfx::IntRect GetClearRect() { return mClearRect; } 686 687 // Returns false if the layer is attached to an older compositor. 688 bool HasStaleCompositor() const; 689 690 /** 691 * Return the part of the visible region that has been fully rendered. 692 * While progressive drawing is in progress this region will be 693 * a subset of the shadow visible region. 694 */ 695 virtual nsIntRegion GetFullyRenderedRegion(); 696 697 protected: 698 LayerManagerComposite* mCompositeManager; 699 700 RefPtr<Compositor> mCompositor; 701 bool mDestroyed; 702 bool mLayerComposited; 703 gfx::IntRect mClearRect; 704 }; 705 706 class WindowLMC : public profiler_screenshots::Window { 707 public: WindowLMC(Compositor * aCompositor)708 explicit WindowLMC(Compositor* aCompositor) : mCompositor(aCompositor) {} 709 710 already_AddRefed<profiler_screenshots::RenderSource> GetWindowContents( 711 const gfx::IntSize& aWindowSize) override; 712 already_AddRefed<profiler_screenshots::DownscaleTarget> CreateDownscaleTarget( 713 const gfx::IntSize& aSize) override; 714 already_AddRefed<profiler_screenshots::AsyncReadbackBuffer> 715 CreateAsyncReadbackBuffer(const gfx::IntSize& aSize) override; 716 717 protected: 718 Compositor* mCompositor; 719 }; 720 721 } // namespace layers 722 } // namespace mozilla 723 724 #endif /* GFX_LayerManagerComposite_H */ 725