Line data Source code
1 : /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
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 :
6 : #include "SharedSurfaceGLX.h"
7 : #include "gfxXlibSurface.h"
8 : #include "GLXLibrary.h"
9 : #include "GLContextProvider.h"
10 : #include "GLContextGLX.h"
11 : #include "GLScreenBuffer.h"
12 : #include "mozilla/gfx/SourceSurfaceCairo.h"
13 : #include "mozilla/layers/LayersSurfaces.h"
14 : #include "mozilla/layers/ShadowLayerUtilsX11.h"
15 : #include "mozilla/layers/ISurfaceAllocator.h"
16 : #include "mozilla/layers/TextureForwarder.h"
17 : #include "mozilla/X11Util.h"
18 :
19 : namespace mozilla {
20 : namespace gl {
21 :
22 : /* static */
23 : UniquePtr<SharedSurface_GLXDrawable>
24 0 : SharedSurface_GLXDrawable::Create(GLContext* prodGL,
25 : const SurfaceCaps& caps,
26 : const gfx::IntSize& size,
27 : bool deallocateClient,
28 : bool inSameProcess)
29 : {
30 0 : UniquePtr<SharedSurface_GLXDrawable> ret;
31 0 : Display* display = DefaultXDisplay();
32 0 : Screen* screen = XDefaultScreenOfDisplay(display);
33 0 : Visual* visual = gfxXlibSurface::FindVisual(screen, gfx::SurfaceFormat::A8R8G8B8_UINT32);
34 :
35 0 : RefPtr<gfxXlibSurface> surf = gfxXlibSurface::Create(screen, visual, size);
36 0 : if (!deallocateClient)
37 0 : surf->ReleasePixmap();
38 :
39 0 : ret.reset(new SharedSurface_GLXDrawable(prodGL, size, inSameProcess, surf));
40 0 : return Move(ret);
41 : }
42 :
43 :
44 0 : SharedSurface_GLXDrawable::SharedSurface_GLXDrawable(GLContext* gl,
45 : const gfx::IntSize& size,
46 : bool inSameProcess,
47 0 : const RefPtr<gfxXlibSurface>& xlibSurface)
48 : : SharedSurface(SharedSurfaceType::GLXDrawable,
49 : AttachmentType::Screen,
50 : gl,
51 : size,
52 : true,
53 : true)
54 : , mXlibSurface(xlibSurface)
55 0 : , mInSameProcess(inSameProcess)
56 0 : {}
57 :
58 : void
59 0 : SharedSurface_GLXDrawable::ProducerReleaseImpl()
60 : {
61 0 : mGL->MakeCurrent();
62 0 : mGL->fFlush();
63 0 : }
64 :
65 : void
66 0 : SharedSurface_GLXDrawable::LockProdImpl()
67 : {
68 0 : mGL->Screen()->SetReadBuffer(LOCAL_GL_FRONT);
69 0 : GLContextGLX::Cast(mGL)->OverrideDrawable(mXlibSurface->GetGLXPixmap());
70 0 : }
71 :
72 : void
73 0 : SharedSurface_GLXDrawable::UnlockProdImpl()
74 : {
75 0 : GLContextGLX::Cast(mGL)->RestoreDrawable();
76 0 : }
77 :
78 : bool
79 0 : SharedSurface_GLXDrawable::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
80 : {
81 0 : if (!mXlibSurface)
82 0 : return false;
83 :
84 0 : *out_descriptor = layers::SurfaceDescriptorX11(mXlibSurface, mInSameProcess);
85 0 : return true;
86 : }
87 :
88 : bool
89 0 : SharedSurface_GLXDrawable::ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface)
90 : {
91 0 : MOZ_ASSERT(out_surface);
92 : RefPtr<gfx::DataSourceSurface> dataSurf =
93 0 : new gfx::DataSourceSurfaceCairo(mXlibSurface->CairoSurface());
94 :
95 0 : gfx::DataSourceSurface::ScopedMap mapSrc(dataSurf, gfx::DataSourceSurface::READ);
96 0 : if (!mapSrc.IsMapped()) {
97 0 : return false;
98 : }
99 :
100 0 : gfx::DataSourceSurface::ScopedMap mapDest(out_surface, gfx::DataSourceSurface::WRITE);
101 0 : if (!mapDest.IsMapped()) {
102 0 : return false;
103 : }
104 :
105 0 : if (mapDest.GetStride() == mapSrc.GetStride()) {
106 0 : memcpy(mapDest.GetData(),
107 0 : mapSrc.GetData(),
108 0 : out_surface->GetSize().height * mapDest.GetStride());
109 : } else {
110 0 : for (int32_t i = 0; i < dataSurf->GetSize().height; i++) {
111 0 : memcpy(mapDest.GetData() + i * mapDest.GetStride(),
112 0 : mapSrc.GetData() + i * mapSrc.GetStride(),
113 0 : std::min(mapSrc.GetStride(), mapDest.GetStride()));
114 : }
115 : }
116 :
117 0 : return true;
118 : }
119 :
120 : /* static */
121 : UniquePtr<SurfaceFactory_GLXDrawable>
122 0 : SurfaceFactory_GLXDrawable::Create(GLContext* prodGL,
123 : const SurfaceCaps& caps,
124 : const RefPtr<layers::LayersIPCChannel>& allocator,
125 : const layers::TextureFlags& flags)
126 : {
127 0 : MOZ_ASSERT(caps.alpha, "GLX surfaces require an alpha channel!");
128 :
129 : typedef SurfaceFactory_GLXDrawable ptrT;
130 : UniquePtr<ptrT> ret(new ptrT(prodGL, caps, allocator,
131 0 : flags & ~layers::TextureFlags::ORIGIN_BOTTOM_LEFT));
132 0 : return Move(ret);
133 : }
134 :
135 : UniquePtr<SharedSurface>
136 0 : SurfaceFactory_GLXDrawable::CreateShared(const gfx::IntSize& size)
137 : {
138 0 : bool deallocateClient = !!(mFlags & layers::TextureFlags::DEALLOCATE_CLIENT);
139 0 : return SharedSurface_GLXDrawable::Create(mGL, mCaps, size, deallocateClient,
140 0 : mAllocator->IsSameProcess());
141 : }
142 :
143 : } // namespace gl
144 : } // namespace mozilla
|