Coverage Report

Created: 2018-09-25 14:53

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