Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/gl/SharedSurfaceGLX.cpp
Line
Count
Source (jump to first uncovered line)
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
SharedSurface_GLXDrawable::Create(GLContext* prodGL,
25
                                  const SurfaceCaps& caps,
26
                                  const gfx::IntSize& size,
27
                                  bool deallocateClient,
28
                                  bool inSameProcess)
29
0
{
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
0
35
0
    RefPtr<gfxXlibSurface> surf = gfxXlibSurface::Create(screen, visual, size);
36
0
    if (!deallocateClient)
37
0
        surf->ReleasePixmap();
38
0
39
0
    ret.reset(new SharedSurface_GLXDrawable(prodGL, size, inSameProcess, surf));
40
0
    return ret;
41
0
}
42
43
44
SharedSurface_GLXDrawable::SharedSurface_GLXDrawable(GLContext* gl,
45
                                                     const gfx::IntSize& size,
46
                                                     bool inSameProcess,
47
                                                     const RefPtr<gfxXlibSurface>& xlibSurface)
48
    : SharedSurface(SharedSurfaceType::GLXDrawable,
49
                    AttachmentType::Screen,
50
                    gl,
51
                    size,
52
                    true,
53
                    true)
54
    , mXlibSurface(xlibSurface)
55
    , mInSameProcess(inSameProcess)
56
0
{}
57
58
void
59
SharedSurface_GLXDrawable::ProducerReleaseImpl()
60
0
{
61
0
    mGL->MakeCurrent();
62
0
    mGL->fFlush();
63
0
}
64
65
void
66
SharedSurface_GLXDrawable::LockProdImpl()
67
0
{
68
0
    mGL->Screen()->SetReadBuffer(LOCAL_GL_FRONT);
69
0
    GLContextGLX::Cast(mGL)->OverrideDrawable(mXlibSurface->GetGLXPixmap());
70
0
}
71
72
void
73
SharedSurface_GLXDrawable::UnlockProdImpl()
74
0
{
75
0
    GLContextGLX::Cast(mGL)->RestoreDrawable();
76
0
}
77
78
bool
79
SharedSurface_GLXDrawable::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
80
0
{
81
0
    if (!mXlibSurface)
82
0
        return false;
83
0
84
0
    *out_descriptor = layers::SurfaceDescriptorX11(mXlibSurface, mInSameProcess);
85
0
    return true;
86
0
}
87
88
bool
89
SharedSurface_GLXDrawable::ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface)
90
0
{
91
0
    MOZ_ASSERT(out_surface);
92
0
    RefPtr<gfx::DataSourceSurface> dataSurf =
93
0
        new gfx::DataSourceSurfaceCairo(mXlibSurface->CairoSurface());
94
0
95
0
    gfx::DataSourceSurface::ScopedMap mapSrc(dataSurf, gfx::DataSourceSurface::READ);
96
0
    if (!mapSrc.IsMapped()) {
97
0
        return false;
98
0
    }
99
0
100
0
    gfx::DataSourceSurface::ScopedMap mapDest(out_surface, gfx::DataSourceSurface::WRITE);
101
0
    if (!mapDest.IsMapped()) {
102
0
        return false;
103
0
    }
104
0
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
0
    } 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
0
        }
115
0
    }
116
0
117
0
    return true;
118
0
}
119
120
/* static */
121
UniquePtr<SurfaceFactory_GLXDrawable>
122
SurfaceFactory_GLXDrawable::Create(GLContext* prodGL,
123
                                   const SurfaceCaps& caps,
124
                                   const RefPtr<layers::LayersIPCChannel>& allocator,
125
                                   const layers::TextureFlags& flags)
126
0
{
127
0
    MOZ_ASSERT(caps.alpha, "GLX surfaces require an alpha channel!");
128
0
129
0
    typedef SurfaceFactory_GLXDrawable ptrT;
130
0
    UniquePtr<ptrT> ret(new ptrT(prodGL, caps, allocator,
131
0
                                 flags & ~layers::TextureFlags::ORIGIN_BOTTOM_LEFT));
132
0
    return ret;
133
0
}
134
135
UniquePtr<SharedSurface>
136
SurfaceFactory_GLXDrawable::CreateShared(const gfx::IntSize& size)
137
0
{
138
0
    bool deallocateClient = !!(mFlags & layers::TextureFlags::DEALLOCATE_CLIENT);
139
0
    return SharedSurface_GLXDrawable::Create(mGL, mCaps, size, deallocateClient,
140
0
                                             mAllocator->IsSameProcess());
141
0
}
142
143
} // namespace gl
144
} // namespace mozilla