|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "BasicLayersImpl.h" // for FillRectWithMask, etc |
|
7 #include "ImageContainer.h" // for AutoLockImage, etc |
|
8 #include "ImageLayers.h" // for ImageLayer |
|
9 #include "Layers.h" // for Layer (ptr only), etc |
|
10 #include "basic/BasicImplData.h" // for BasicImplData |
|
11 #include "basic/BasicLayers.h" // for BasicLayerManager |
|
12 #include "mozilla/mozalloc.h" // for operator new |
|
13 #include "nsAutoPtr.h" // for nsRefPtr, getter_AddRefs, etc |
|
14 #include "nsCOMPtr.h" // for already_AddRefed |
|
15 #include "nsDebug.h" // for NS_ASSERTION |
|
16 #include "nsISupportsImpl.h" // for gfxPattern::Release, etc |
|
17 #include "nsRect.h" // for nsIntRect |
|
18 #include "nsRegion.h" // for nsIntRegion |
|
19 #include "mozilla/gfx/Point.h" // for IntSize |
|
20 |
|
21 using namespace mozilla::gfx; |
|
22 |
|
23 namespace mozilla { |
|
24 namespace layers { |
|
25 |
|
26 class BasicImageLayer : public ImageLayer, public BasicImplData { |
|
27 public: |
|
28 BasicImageLayer(BasicLayerManager* aLayerManager) : |
|
29 ImageLayer(aLayerManager, |
|
30 static_cast<BasicImplData*>(MOZ_THIS_IN_INITIALIZER_LIST())), |
|
31 mSize(-1, -1) |
|
32 { |
|
33 MOZ_COUNT_CTOR(BasicImageLayer); |
|
34 } |
|
35 virtual ~BasicImageLayer() |
|
36 { |
|
37 MOZ_COUNT_DTOR(BasicImageLayer); |
|
38 } |
|
39 |
|
40 virtual void SetVisibleRegion(const nsIntRegion& aRegion) |
|
41 { |
|
42 NS_ASSERTION(BasicManager()->InConstruction(), |
|
43 "Can only set properties in construction phase"); |
|
44 ImageLayer::SetVisibleRegion(aRegion); |
|
45 } |
|
46 |
|
47 virtual void Paint(DrawTarget* aDT, |
|
48 const gfx::Point& aDeviceOffset, |
|
49 Layer* aMaskLayer) MOZ_OVERRIDE; |
|
50 |
|
51 virtual TemporaryRef<SourceSurface> GetAsSourceSurface() MOZ_OVERRIDE; |
|
52 |
|
53 protected: |
|
54 BasicLayerManager* BasicManager() |
|
55 { |
|
56 return static_cast<BasicLayerManager*>(mManager); |
|
57 } |
|
58 |
|
59 // only paints the image if aContext is non-null |
|
60 void |
|
61 GetAndPaintCurrentImage(DrawTarget* aTarget, |
|
62 float aOpacity, |
|
63 SourceSurface* aMaskSurface); |
|
64 |
|
65 gfx::IntSize mSize; |
|
66 }; |
|
67 |
|
68 void |
|
69 BasicImageLayer::Paint(DrawTarget* aDT, |
|
70 const gfx::Point& aDeviceOffset, |
|
71 Layer* aMaskLayer) |
|
72 { |
|
73 if (IsHidden() || !mContainer) { |
|
74 return; |
|
75 } |
|
76 |
|
77 mContainer->SetImageFactory(mManager->IsCompositingCheap() ? nullptr : BasicManager()->GetImageFactory()); |
|
78 |
|
79 RefPtr<gfx::SourceSurface> surface; |
|
80 AutoLockImage autoLock(mContainer, &surface); |
|
81 Image *image = autoLock.GetImage(); |
|
82 gfx::IntSize size = mSize = autoLock.GetSize(); |
|
83 |
|
84 if (!surface || !surface->IsValid()) { |
|
85 return; |
|
86 } |
|
87 |
|
88 FillRectWithMask(aDT, aDeviceOffset, Rect(0, 0, size.width, size.height), |
|
89 surface, ToFilter(mFilter), |
|
90 DrawOptions(GetEffectiveOpacity(), GetEffectiveOperator(this)), |
|
91 aMaskLayer); |
|
92 |
|
93 GetContainer()->NotifyPaintedImage(image); |
|
94 } |
|
95 |
|
96 void |
|
97 BasicImageLayer::GetAndPaintCurrentImage(DrawTarget* aTarget, |
|
98 float aOpacity, |
|
99 SourceSurface* aMaskSurface) |
|
100 { |
|
101 if (!mContainer) { |
|
102 return; |
|
103 } |
|
104 |
|
105 mContainer->SetImageFactory(mManager->IsCompositingCheap() ? |
|
106 nullptr : |
|
107 BasicManager()->GetImageFactory()); |
|
108 IntSize size; |
|
109 Image* image = nullptr; |
|
110 RefPtr<SourceSurface> surf = |
|
111 mContainer->LockCurrentAsSourceSurface(&size, &image); |
|
112 |
|
113 if (!surf) { |
|
114 return; |
|
115 } |
|
116 |
|
117 if (aTarget) { |
|
118 // The visible region can extend outside the image, so just draw |
|
119 // within the image bounds. |
|
120 SurfacePattern pat(surf, ExtendMode::CLAMP, Matrix(), ToFilter(mFilter)); |
|
121 CompositionOp op = GetEffectiveOperator(this); |
|
122 DrawOptions opts(aOpacity, op); |
|
123 |
|
124 aTarget->MaskSurface(pat, aMaskSurface, Point(0, 0), opts); |
|
125 |
|
126 GetContainer()->NotifyPaintedImage(image); |
|
127 } |
|
128 |
|
129 mContainer->UnlockCurrentImage(); |
|
130 } |
|
131 |
|
132 TemporaryRef<SourceSurface> |
|
133 BasicImageLayer::GetAsSourceSurface() |
|
134 { |
|
135 if (!mContainer) { |
|
136 return nullptr; |
|
137 } |
|
138 |
|
139 gfx::IntSize dontCare; |
|
140 return mContainer->GetCurrentAsSourceSurface(&dontCare); |
|
141 } |
|
142 |
|
143 already_AddRefed<ImageLayer> |
|
144 BasicLayerManager::CreateImageLayer() |
|
145 { |
|
146 NS_ASSERTION(InConstruction(), "Only allowed in construction phase"); |
|
147 nsRefPtr<ImageLayer> layer = new BasicImageLayer(this); |
|
148 return layer.forget(); |
|
149 } |
|
150 |
|
151 } |
|
152 } |