Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * vim: sw=2 ts=8 et :
3 : */
4 : /* This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 :
8 : #include "ShadowLayerUtilsX11.h"
9 : #include <X11/X.h> // for Drawable, XID
10 : #include <X11/Xlib.h> // for Display, Visual, etc
11 : #include <X11/extensions/Xrender.h> // for XRenderPictFormat, etc
12 : #include <X11/extensions/render.h> // for PictFormat
13 : #include "cairo-xlib.h"
14 : #include "X11UndefineNone.h"
15 : #include <stdint.h> // for uint32_t
16 : #include "GLDefs.h" // for GLenum
17 : #include "gfxPlatform.h" // for gfxPlatform
18 : #include "gfxXlibSurface.h" // for gfxXlibSurface
19 : #include "gfx2DGlue.h" // for Moz2D transistion helpers
20 : #include "mozilla/X11Util.h" // for DefaultXDisplay, FinishX, etc
21 : #include "mozilla/gfx/Point.h" // for IntSize
22 : #include "mozilla/layers/CompositableForwarder.h"
23 : #include "mozilla/layers/CompositorTypes.h" // for OpenMode
24 : #include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator, etc
25 : #include "mozilla/layers/LayerManagerComposite.h"
26 : #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
27 : #include "mozilla/layers/ShadowLayers.h" // for ShadowLayerForwarder, etc
28 : #include "mozilla/mozalloc.h" // for operator new
29 : #include "gfxEnv.h"
30 : #include "nsCOMPtr.h" // for already_AddRefed
31 : #include "nsDebug.h" // for NS_ERROR
32 :
33 : using namespace mozilla::gl;
34 :
35 : namespace mozilla {
36 : namespace gl {
37 : class GLContext;
38 : class TextureImage;
39 : }
40 :
41 : namespace layers {
42 :
43 : // Return true if we're likely compositing using X and so should use
44 : // Xlib surfaces in shadow layers.
45 : static bool
46 8 : UsingXCompositing()
47 : {
48 8 : if (!gfxEnv::LayersEnableXlibSurfaces()) {
49 8 : return false;
50 : }
51 : return (gfxSurfaceType::Xlib ==
52 0 : gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType());
53 : }
54 :
55 : // LookReturn a pointer to |aFormat| that lives in the Xrender library.
56 : // All code using render formats assumes it doesn't need to copy.
57 : static XRenderPictFormat*
58 0 : GetXRenderPictFormatFromId(Display* aDisplay, PictFormat aFormatId)
59 : {
60 : XRenderPictFormat tmplate;
61 0 : tmplate.id = aFormatId;
62 0 : return XRenderFindFormat(aDisplay, PictFormatID, &tmplate, 0);
63 : }
64 :
65 0 : SurfaceDescriptorX11::SurfaceDescriptorX11(gfxXlibSurface* aSurf,
66 0 : bool aForwardGLX)
67 0 : : mId(aSurf->XDrawable())
68 : , mSize(aSurf->GetSize())
69 0 : , mGLXPixmap(X11None)
70 : {
71 0 : const XRenderPictFormat *pictFormat = aSurf->XRenderFormat();
72 0 : if (pictFormat) {
73 0 : mFormat = pictFormat->id;
74 : } else {
75 0 : mFormat = cairo_xlib_surface_get_visual(aSurf->CairoSurface())->visualid;
76 : }
77 :
78 : #ifdef GL_PROVIDER_GLX
79 0 : if (aForwardGLX) {
80 0 : mGLXPixmap = aSurf->GetGLXPixmap();
81 : }
82 : #endif
83 0 : }
84 :
85 0 : SurfaceDescriptorX11::SurfaceDescriptorX11(Drawable aDrawable, XID aFormatID,
86 0 : const gfx::IntSize& aSize)
87 : : mId(aDrawable)
88 : , mFormat(aFormatID)
89 : , mSize(aSize)
90 0 : , mGLXPixmap(X11None)
91 0 : { }
92 :
93 : already_AddRefed<gfxXlibSurface>
94 0 : SurfaceDescriptorX11::OpenForeign() const
95 : {
96 0 : Display* display = DefaultXDisplay();
97 0 : Screen* screen = DefaultScreenOfDisplay(display);
98 :
99 0 : RefPtr<gfxXlibSurface> surf;
100 0 : XRenderPictFormat* pictFormat = GetXRenderPictFormatFromId(display, mFormat);
101 0 : if (pictFormat) {
102 0 : surf = new gfxXlibSurface(screen, mId, pictFormat, mSize);
103 : } else {
104 : Visual* visual;
105 : int depth;
106 0 : FindVisualAndDepth(display, mFormat, &visual, &depth);
107 0 : if (!visual)
108 0 : return nullptr;
109 :
110 0 : surf = new gfxXlibSurface(display, mId, visual, mSize);
111 : }
112 :
113 : #ifdef GL_PROVIDER_GLX
114 0 : if (mGLXPixmap)
115 0 : surf->BindGLXPixmap(mGLXPixmap);
116 : #endif
117 :
118 0 : return surf->CairoStatus() ? nullptr : surf.forget();
119 : }
120 :
121 : /*static*/ void
122 4 : ShadowLayerForwarder::PlatformSyncBeforeUpdate()
123 : {
124 4 : if (UsingXCompositing()) {
125 : // If we're using X surfaces, then we need to finish all pending
126 : // operations on the back buffers before handing them to the
127 : // parent, otherwise the surface might be used by the parent's
128 : // Display in between two operations queued by our Display.
129 0 : FinishX(DefaultXDisplay());
130 : }
131 4 : }
132 :
133 : /*static*/ void
134 4 : LayerManagerComposite::PlatformSyncBeforeReplyUpdate()
135 : {
136 4 : if (UsingXCompositing()) {
137 : // If we're using X surfaces, we need to finish all pending
138 : // operations on the *front buffers* before handing them back to
139 : // the child, even though they will be read operations.
140 : // Otherwise, the child might start scribbling on new back buffers
141 : // that are still participating in requests as old front buffers.
142 0 : FinishX(DefaultXDisplay());
143 : }
144 4 : }
145 :
146 : /*static*/ bool
147 0 : LayerManagerComposite::SupportsDirectTexturing()
148 : {
149 0 : return false;
150 : }
151 :
152 : } // namespace layers
153 : } // namespace mozilla
|