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