Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; 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 "ImageLayerComposite.h"
7 : #include "CompositableHost.h" // for CompositableHost
8 : #include "Layers.h" // for WriteSnapshotToDumpFile, etc
9 : #include "gfx2DGlue.h" // for ToFilter
10 : #include "gfxEnv.h" // for gfxEnv
11 : #include "gfxRect.h" // for gfxRect
12 : #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
13 : #include "mozilla/gfx/Matrix.h" // for Matrix4x4
14 : #include "mozilla/gfx/Point.h" // for IntSize, Point
15 : #include "mozilla/gfx/Rect.h" // for Rect
16 : #include "mozilla/layers/Compositor.h" // for Compositor
17 : #include "mozilla/layers/Effects.h" // for EffectChain
18 : #include "mozilla/layers/ImageHost.h" // for ImageHost
19 : #include "mozilla/layers/TextureHost.h" // for TextureHost, etc
20 : #include "mozilla/mozalloc.h" // for operator delete
21 : #include "nsAString.h"
22 : #include "mozilla/RefPtr.h" // for nsRefPtr
23 : #include "nsDebug.h" // for NS_ASSERTION
24 : #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
25 : #include "nsString.h" // for nsAutoCString
26 :
27 : namespace mozilla {
28 : namespace layers {
29 :
30 : using namespace mozilla::gfx;
31 :
32 0 : ImageLayerComposite::ImageLayerComposite(LayerManagerComposite* aManager)
33 : : ImageLayer(aManager, nullptr)
34 : , LayerComposite(aManager)
35 0 : , mImageHost(nullptr)
36 : {
37 0 : MOZ_COUNT_CTOR(ImageLayerComposite);
38 0 : mImplData = static_cast<LayerComposite*>(this);
39 0 : }
40 :
41 0 : ImageLayerComposite::~ImageLayerComposite()
42 : {
43 0 : MOZ_COUNT_DTOR(ImageLayerComposite);
44 0 : MOZ_ASSERT(mDestroyed);
45 :
46 0 : CleanupResources();
47 0 : }
48 :
49 : bool
50 0 : ImageLayerComposite::SetCompositableHost(CompositableHost* aHost)
51 : {
52 0 : switch (aHost->GetType()) {
53 : case CompositableType::IMAGE:
54 0 : mImageHost = static_cast<ImageHost*>(aHost);
55 0 : return true;
56 : default:
57 0 : return false;
58 : }
59 : }
60 :
61 : void
62 0 : ImageLayerComposite::Disconnect()
63 : {
64 0 : Destroy();
65 0 : }
66 :
67 : Layer*
68 0 : ImageLayerComposite::GetLayer()
69 : {
70 0 : return this;
71 : }
72 :
73 : void
74 0 : ImageLayerComposite::SetLayerManager(HostLayerManager* aManager)
75 : {
76 0 : LayerComposite::SetLayerManager(aManager);
77 0 : mManager = aManager;
78 0 : if (mImageHost) {
79 0 : mImageHost->SetTextureSourceProvider(mCompositor);
80 : }
81 0 : }
82 :
83 : void
84 0 : ImageLayerComposite::RenderLayer(const IntRect& aClipRect,
85 : const Maybe<gfx::Polygon>& aGeometry)
86 : {
87 0 : if (!mImageHost || !mImageHost->IsAttached()) {
88 0 : return;
89 : }
90 :
91 : #ifdef MOZ_DUMP_PAINTING
92 0 : if (gfxEnv::DumpCompositorTextures()) {
93 0 : RefPtr<gfx::DataSourceSurface> surf = mImageHost->GetAsSurface();
94 0 : if (surf) {
95 0 : WriteSnapshotToDumpFile(this, surf);
96 : }
97 : }
98 : #endif
99 :
100 0 : mCompositor->MakeCurrent();
101 :
102 0 : RenderWithAllMasks(this, mCompositor, aClipRect,
103 0 : [&](EffectChain& effectChain, const IntRect& clipRect) {
104 0 : mImageHost->SetTextureSourceProvider(mCompositor);
105 0 : mImageHost->Composite(mCompositor, this, effectChain,
106 : GetEffectiveOpacity(),
107 0 : GetEffectiveTransformForBuffer(),
108 : GetSamplingFilter(),
109 0 : clipRect);
110 0 : });
111 0 : mImageHost->BumpFlashCounter();
112 : }
113 :
114 : void
115 0 : ImageLayerComposite::ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface)
116 : {
117 0 : gfx::Matrix4x4 local = GetLocalTransform();
118 :
119 : // Snap image edges to pixel boundaries
120 0 : gfxRect sourceRect(0, 0, 0, 0);
121 0 : if (mImageHost &&
122 0 : mImageHost->IsAttached()) {
123 0 : IntSize size = mImageHost->GetImageSize();
124 0 : sourceRect.SizeTo(size.width, size.height);
125 : }
126 : // Snap our local transform first, and snap the inherited transform as well.
127 : // This makes our snapping equivalent to what would happen if our content
128 : // was drawn into a PaintedLayer (gfxContext would snap using the local
129 : // transform, then we'd snap again when compositing the PaintedLayer).
130 0 : mEffectiveTransform =
131 0 : SnapTransform(local, sourceRect, nullptr) *
132 0 : SnapTransformTranslation(aTransformToSurface, nullptr);
133 :
134 0 : if (mScaleMode != ScaleMode::SCALE_NONE &&
135 0 : sourceRect.width != 0.0 && sourceRect.height != 0.0) {
136 0 : NS_ASSERTION(mScaleMode == ScaleMode::STRETCH,
137 : "No other scalemodes than stretch and none supported yet.");
138 0 : local.PreScale(mScaleToSize.width / sourceRect.width,
139 0 : mScaleToSize.height / sourceRect.height, 1.0);
140 :
141 0 : mEffectiveTransformForBuffer =
142 0 : SnapTransform(local, sourceRect, nullptr) *
143 0 : SnapTransformTranslation(aTransformToSurface, nullptr);
144 : } else {
145 0 : mEffectiveTransformForBuffer = mEffectiveTransform;
146 : }
147 :
148 0 : ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
149 0 : }
150 :
151 : bool
152 0 : ImageLayerComposite::IsOpaque()
153 : {
154 0 : if (!mImageHost ||
155 0 : !mImageHost->IsAttached()) {
156 0 : return false;
157 : }
158 :
159 0 : if (mScaleMode == ScaleMode::STRETCH) {
160 0 : return mImageHost->IsOpaque();
161 : }
162 0 : return false;
163 : }
164 :
165 : nsIntRegion
166 0 : ImageLayerComposite::GetFullyRenderedRegion()
167 : {
168 0 : if (!mImageHost ||
169 0 : !mImageHost->IsAttached()) {
170 0 : return GetShadowVisibleRegion().ToUnknownRegion();
171 : }
172 :
173 0 : if (mScaleMode == ScaleMode::STRETCH) {
174 0 : nsIntRegion shadowVisibleRegion;
175 0 : shadowVisibleRegion.And(GetShadowVisibleRegion().ToUnknownRegion(), nsIntRegion(gfx::IntRect(0, 0, mScaleToSize.width, mScaleToSize.height)));
176 0 : return shadowVisibleRegion;
177 : }
178 :
179 0 : return GetShadowVisibleRegion().ToUnknownRegion();
180 : }
181 :
182 : CompositableHost*
183 0 : ImageLayerComposite::GetCompositableHost()
184 : {
185 0 : if (mImageHost && mImageHost->IsAttached()) {
186 0 : return mImageHost.get();
187 : }
188 :
189 0 : return nullptr;
190 : }
191 :
192 : void
193 0 : ImageLayerComposite::CleanupResources()
194 : {
195 0 : if (mImageHost) {
196 0 : mImageHost->CleanupResources();
197 0 : mImageHost->Detach(this);
198 : }
199 0 : mImageHost = nullptr;
200 0 : }
201 :
202 : gfx::SamplingFilter
203 0 : ImageLayerComposite::GetSamplingFilter()
204 : {
205 0 : return mSamplingFilter;
206 : }
207 :
208 : void
209 0 : ImageLayerComposite::GenEffectChain(EffectChain& aEffect)
210 : {
211 0 : aEffect.mLayerRef = this;
212 0 : aEffect.mPrimaryEffect = mImageHost->GenEffect(GetSamplingFilter());
213 0 : }
214 :
215 : void
216 0 : ImageLayerComposite::PrintInfo(std::stringstream& aStream, const char* aPrefix)
217 : {
218 0 : ImageLayer::PrintInfo(aStream, aPrefix);
219 0 : if (mImageHost && mImageHost->IsAttached()) {
220 0 : aStream << "\n";
221 0 : nsAutoCString pfx(aPrefix);
222 0 : pfx += " ";
223 0 : mImageHost->PrintInfo(aStream, pfx.get());
224 : }
225 0 : }
226 :
227 : } // namespace layers
228 : } // namespace mozilla
|