Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/tests/gtest/TestCompositor.cpp
Line
Count
Source (jump to first uncovered line)
1
/* vim:set ts=2 sw=2 sts=2 et: */
2
/* Any copyright is dedicated to the Public Domain.
3
 * http://creativecommons.org/publicdomain/zero/1.0/
4
 */
5
6
#include "gfxPrefs.h"
7
#include "gfxUtils.h"
8
#include "gtest/gtest.h"
9
#include "TestLayers.h"
10
#include "mozilla/gfx/2D.h"
11
#include "mozilla/RefPtr.h"
12
#include "mozilla/layers/BasicCompositor.h"  // for BasicCompositor
13
#include "mozilla/layers/Compositor.h"  // for Compositor
14
#include "mozilla/layers/CompositorOGL.h"  // for CompositorOGL
15
#include "mozilla/layers/CompositorTypes.h"
16
#include "mozilla/layers/LayerManagerComposite.h"
17
#include "MockWidget.h"
18
#include "nsBaseWidget.h"
19
#include <vector>
20
21
const int gCompWidth = 256;
22
const int gCompHeight = 256;
23
24
using namespace mozilla;
25
using namespace mozilla::gfx;
26
using namespace mozilla::layers;
27
using namespace mozilla::gl;
28
29
struct LayerManagerData {
30
  RefPtr<MockWidget> mWidget;
31
  RefPtr<Compositor> mCompositor;
32
  RefPtr<widget::CompositorWidget> mCompositorWidget;
33
  RefPtr<LayerManagerComposite> mLayerManager;
34
35
  LayerManagerData(Compositor* compositor,
36
                   MockWidget* widget,
37
                   widget::CompositorWidget* aWidget,
38
                   LayerManagerComposite* layerManager)
39
    : mWidget(widget)
40
    , mCompositor(compositor)
41
    , mCompositorWidget(aWidget)
42
    , mLayerManager(layerManager)
43
0
  {}
44
};
45
46
static already_AddRefed<Compositor> CreateTestCompositor(LayersBackend backend, widget::CompositorWidget* widget)
47
0
{
48
0
  gfxPlatform::GetPlatform();
49
0
50
0
  RefPtr<Compositor> compositor;
51
0
52
0
  if (backend == LayersBackend::LAYERS_OPENGL) {
53
0
    compositor = new CompositorOGL(nullptr,
54
0
                                   widget,
55
0
                                   gCompWidth,
56
0
                                   gCompHeight,
57
0
                                   true);
58
0
    compositor->SetDestinationSurfaceSize(IntSize(gCompWidth, gCompHeight));
59
0
  } else if (backend == LayersBackend::LAYERS_BASIC) {
60
0
    compositor = new BasicCompositor(nullptr, widget);
61
#ifdef XP_WIN
62
  } else if (backend == LayersBackend::LAYERS_D3D11) {
63
    //compositor = new CompositorD3D11();
64
    MOZ_CRASH(); // No support yet
65
#endif
66
  }
67
0
  nsCString failureReason;
68
0
  if (!compositor || !compositor->Initialize(&failureReason)) {
69
0
    printf_stderr("Failed to construct layer manager for the requested backend\n");
70
0
    abort();
71
0
  }
72
0
73
0
  return compositor.forget();
74
0
}
75
76
/**
77
 * Get a list of layers managers for the platform to run the test on.
78
 */
79
static std::vector<LayerManagerData> GetLayerManagers(std::vector<LayersBackend> aBackends)
80
0
{
81
0
  std::vector<LayerManagerData> managers;
82
0
83
0
  for (size_t i = 0; i < aBackends.size(); i++) {
84
0
    auto backend = aBackends[i];
85
0
86
0
    RefPtr<MockWidget> widget = new MockWidget(gCompWidth, gCompHeight);
87
0
    CompositorOptions options;
88
0
    RefPtr<widget::CompositorWidget> proxy = new widget::InProcessCompositorWidget(options, widget);
89
0
    RefPtr<Compositor> compositor = CreateTestCompositor(backend, proxy);
90
0
91
0
    RefPtr<LayerManagerComposite> layerManager = new LayerManagerComposite(compositor);
92
0
93
0
    managers.push_back(LayerManagerData(compositor, widget, proxy, layerManager));
94
0
  }
95
0
96
0
  return managers;
97
0
}
98
99
/**
100
 * This will return the default list of backends that
101
 * units test should run against.
102
 */
103
static std::vector<LayersBackend> GetPlatformBackends()
104
0
{
105
0
  std::vector<LayersBackend> backends;
106
0
107
0
  // For now we only support Basic for gtest
108
0
  backends.push_back(LayersBackend::LAYERS_BASIC);
109
0
110
#ifdef XP_MACOSX
111
  backends.push_back(LayersBackend::LAYERS_OPENGL);
112
#endif
113
114
0
  // TODO Support OGL/D3D backends with unit test
115
0
  return backends;
116
0
}
117
118
static already_AddRefed<DrawTarget> CreateDT()
119
0
{
120
0
  return gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
121
0
    IntSize(gCompWidth, gCompHeight), SurfaceFormat::B8G8R8A8);
122
0
}
123
124
static bool CompositeAndCompare(RefPtr<LayerManagerComposite> layerManager, DrawTarget* refDT)
125
0
{
126
0
  RefPtr<DrawTarget> drawTarget = CreateDT();
127
0
128
0
  layerManager->BeginTransactionWithDrawTarget(drawTarget, IntRect(0, 0, gCompWidth, gCompHeight));
129
0
  layerManager->EndTransaction(TimeStamp::Now());
130
0
131
0
  RefPtr<SourceSurface> ss = drawTarget->Snapshot();
132
0
  RefPtr<DataSourceSurface> dss = ss->GetDataSurface();
133
0
  DataSourceSurface::ScopedMap dssMap(dss, DataSourceSurface::READ);
134
0
  uint8_t* bitmap = dssMap.GetData();
135
0
136
0
  RefPtr<SourceSurface> ssRef = refDT->Snapshot();
137
0
  RefPtr<DataSourceSurface> dssRef = ssRef->GetDataSurface();
138
0
  DataSourceSurface::ScopedMap dssRefMap(dssRef, DataSourceSurface::READ);
139
0
  uint8_t* bitmapRef = dssRefMap.GetData();
140
0
141
0
  for (int y = 0; y < gCompHeight; y++) {
142
0
    for (int x = 0; x < gCompWidth; x++) {
143
0
      for (size_t channel = 0; channel < 4; channel++) {
144
0
        uint8_t bit = bitmap[y * dssMap.GetStride() + x * 4 + channel];
145
0
        uint8_t bitRef = bitmapRef[y * dssRefMap.GetStride() + x * 4 + channel];
146
0
        if (bit != bitRef) {
147
0
          printf("Layer Tree:\n");
148
0
          layerManager->Dump();
149
0
          printf("Original:\n");
150
0
          gfxUtils::DumpAsDataURI(drawTarget);
151
0
          printf("\n\n");
152
0
153
0
          printf("Reference:\n");
154
0
          gfxUtils::DumpAsDataURI(refDT);
155
0
          printf("\n\n");
156
0
157
0
          return false;
158
0
        }
159
0
      }
160
0
    }
161
0
  }
162
0
163
0
  return true;
164
0
}
165
166
TEST(Gfx, CompositorConstruct)
167
0
{
168
0
  auto layerManagers = GetLayerManagers(GetPlatformBackends());
169
0
}
170
171
TEST(Gfx, CompositorSimpleTree)
172
0
{
173
0
  auto layerManagers = GetLayerManagers(GetPlatformBackends());
174
0
  for (size_t i = 0; i < layerManagers.size(); i++) {
175
0
    RefPtr<LayerManagerComposite> layerManager = layerManagers[i].mLayerManager;
176
0
    RefPtr<LayerManager> lmBase = layerManager.get();
177
0
    nsTArray<RefPtr<Layer>> layers;
178
0
    nsIntRegion layerVisibleRegion[] = {
179
0
      nsIntRegion(IntRect(0, 0, gCompWidth, gCompHeight)),
180
0
      nsIntRegion(IntRect(0, 0, gCompWidth, gCompHeight)),
181
0
      nsIntRegion(IntRect(0, 0, 100, 100)),
182
0
      nsIntRegion(IntRect(0, 50, 100, 100)),
183
0
    };
184
0
    RefPtr<Layer> root = CreateLayerTree("c(ooo)", layerVisibleRegion, nullptr, lmBase, layers);
185
0
186
0
    { // background
187
0
      ColorLayer* colorLayer = layers[1]->AsColorLayer();
188
0
      colorLayer->SetColor(Color(1.f, 0.f, 1.f, 1.f));
189
0
      colorLayer->SetBounds(colorLayer->GetVisibleRegion().GetBounds().ToUnknownRect());
190
0
    }
191
0
192
0
    {
193
0
      ColorLayer* colorLayer = layers[2]->AsColorLayer();
194
0
      colorLayer->SetColor(Color(1.f, 0.f, 0.f, 1.f));
195
0
      colorLayer->SetBounds(colorLayer->GetVisibleRegion().GetBounds().ToUnknownRect());
196
0
    }
197
0
198
0
    {
199
0
      ColorLayer* colorLayer = layers[3]->AsColorLayer();
200
0
      colorLayer->SetColor(Color(0.f, 0.f, 1.f, 1.f));
201
0
      colorLayer->SetBounds(colorLayer->GetVisibleRegion().GetBounds().ToUnknownRect());
202
0
    }
203
0
204
0
    RefPtr<DrawTarget> refDT = CreateDT();
205
0
    refDT->FillRect(Rect(0, 0, gCompWidth, gCompHeight), ColorPattern(Color(1.f, 0.f, 1.f, 1.f)));
206
0
    refDT->FillRect(Rect(0, 0, 100, 100), ColorPattern(Color(1.f, 0.f, 0.f, 1.f)));
207
0
    refDT->FillRect(Rect(0, 50, 100, 100), ColorPattern(Color(0.f, 0.f, 1.f, 1.f)));
208
0
    EXPECT_TRUE(CompositeAndCompare(layerManager, refDT));
209
0
  }
210
0
}
211