Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/layers/basic/TextureClientX11.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
#include "mozilla/layers/TextureClientX11.h"
7
#include "mozilla/layers/CompositableClient.h"
8
#include "mozilla/layers/CompositableForwarder.h"
9
#include "mozilla/layers/ISurfaceAllocator.h"
10
#include "mozilla/layers/ShadowLayerUtilsX11.h"
11
#include "mozilla/gfx/2D.h"
12
#include "mozilla/gfx/Logging.h"
13
#include "gfxXlibSurface.h"
14
#include "gfx2DGlue.h"
15
16
#include "mozilla/X11Util.h"
17
#include <X11/Xlib.h>
18
19
using namespace mozilla;
20
using namespace mozilla::gfx;
21
22
namespace mozilla {
23
namespace layers {
24
25
X11TextureData::X11TextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
26
                               bool aClientDeallocation, bool aIsCrossProcess,
27
                               gfxXlibSurface* aSurface)
28
: mSize(aSize)
29
, mFormat(aFormat)
30
, mSurface(aSurface)
31
, mClientDeallocation(aClientDeallocation)
32
, mIsCrossProcess(aIsCrossProcess)
33
0
{
34
0
  MOZ_ASSERT(mSurface);
35
0
}
36
37
bool
38
X11TextureData::Lock(OpenMode aMode)
39
0
{
40
0
  return true;
41
0
}
42
43
void
44
X11TextureData::Unlock()
45
0
{
46
0
  if (mSurface && mIsCrossProcess) {
47
0
    FinishX(DefaultXDisplay());
48
0
  }
49
0
}
50
51
void
52
X11TextureData::FillInfo(TextureData::Info& aInfo) const
53
0
{
54
0
  aInfo.size = mSize;
55
0
  aInfo.format = mFormat;
56
0
  aInfo.supportsMoz2D = true;
57
0
  aInfo.hasIntermediateBuffer = false;
58
0
  aInfo.hasSynchronization = false;
59
0
  aInfo.canExposeMappedData = false;
60
0
}
61
62
bool
63
X11TextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
64
0
{
65
0
  MOZ_ASSERT(mSurface);
66
0
  if (!mSurface) {
67
0
    return false;
68
0
  }
69
0
70
0
  if (!mClientDeallocation) {
71
0
    // Pass to the host the responsibility of freeing the pixmap. ReleasePixmap means
72
0
    // the underlying pixmap will not be deallocated in mSurface's destructor.
73
0
    // ToSurfaceDescriptor is at most called once per TextureClient.
74
0
    mSurface->ReleasePixmap();
75
0
  }
76
0
77
0
  aOutDescriptor = SurfaceDescriptorX11(mSurface);
78
0
  return true;
79
0
}
80
81
already_AddRefed<gfx::DrawTarget>
82
X11TextureData::BorrowDrawTarget()
83
0
{
84
0
  MOZ_ASSERT(mSurface);
85
0
  if (!mSurface) {
86
0
    return nullptr;
87
0
  }
88
0
89
0
  IntSize size = mSurface->GetSize();
90
0
  RefPtr<gfx::DrawTarget> dt = Factory::CreateDrawTargetForCairoSurface(mSurface->CairoSurface(), size);
91
0
92
0
  return dt.forget();
93
0
}
94
95
bool
96
X11TextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
97
0
{
98
0
  RefPtr<DrawTarget> dt = BorrowDrawTarget();
99
0
100
0
  if (!dt) {
101
0
    return false;
102
0
  }
103
0
104
0
  dt->CopySurface(aSurface, IntRect(IntPoint(), aSurface->GetSize()), IntPoint());
105
0
106
0
  return true;
107
0
}
108
109
void
110
X11TextureData::Deallocate(LayersIPCChannel*)
111
0
{
112
0
  mSurface = nullptr;
113
0
}
114
115
TextureData*
116
X11TextureData::CreateSimilar(LayersIPCChannel* aAllocator,
117
                              LayersBackend aLayersBackend,
118
                              TextureFlags aFlags,
119
                              TextureAllocationFlags aAllocFlags) const
120
0
{
121
0
  return X11TextureData::Create(mSize, mFormat, aFlags, aAllocator);
122
0
}
123
124
X11TextureData*
125
X11TextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
126
                       TextureFlags aFlags, LayersIPCChannel* aAllocator)
127
0
{
128
0
  MOZ_ASSERT(aSize.width >= 0 && aSize.height >= 0);
129
0
  if (aSize.width <= 0 || aSize.height <= 0 ||
130
0
      aSize.width > XLIB_IMAGE_SIDE_SIZE_LIMIT ||
131
0
      aSize.height > XLIB_IMAGE_SIDE_SIZE_LIMIT) {
132
0
    gfxDebug() << "Asking for X11 surface of invalid size " << aSize.width << "x" << aSize.height;
133
0
    return nullptr;
134
0
  }
135
0
  gfxImageFormat imageFormat = SurfaceFormatToImageFormat(aFormat);
136
0
  RefPtr<gfxASurface> surface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(aSize, imageFormat);
137
0
  if (!surface || surface->GetType() != gfxSurfaceType::Xlib) {
138
0
    NS_ERROR("creating Xlib surface failed!");
139
0
    return nullptr;
140
0
  }
141
0
142
0
  gfxXlibSurface* xlibSurface = static_cast<gfxXlibSurface*>(surface.get());
143
0
144
0
  bool crossProcess = !aAllocator->IsSameProcess();
145
0
  X11TextureData* texture = new X11TextureData(aSize, aFormat,
146
0
                                               !!(aFlags & TextureFlags::DEALLOCATE_CLIENT),
147
0
                                               crossProcess,
148
0
                                               xlibSurface);
149
0
  if (crossProcess) {
150
0
    FinishX(DefaultXDisplay());
151
0
  }
152
0
153
0
  return texture;
154
0
}
155
156
} // namespace
157
} // namespace