forked from Floorp-Projects/Floorp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSharedSurfaceGralloc.cpp
155 lines (122 loc) · 4.68 KB
/
SharedSurfaceGralloc.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Preferences.h"
#include "SharedSurfaceGralloc.h"
#include "GLContext.h"
#include "SharedSurfaceGL.h"
#include "SurfaceFactory.h"
#include "GLLibraryEGL.h"
#include "mozilla/layers/GrallocTextureClient.h"
#include "mozilla/layers/ShadowLayers.h"
#include "ui/GraphicBuffer.h"
#include "../layers/ipc/ShadowLayers.h"
#include "ScopedGLHelpers.h"
#include "gfxPlatform.h"
#include "gfx2DGlue.h"
#include "gfxPrefs.h"
#define DEBUG_GRALLOC
#ifdef DEBUG_GRALLOC
#define DEBUG_PRINT(...) do { printf_stderr(__VA_ARGS__); } while (0)
#else
#define DEBUG_PRINT(...) do { } while (0)
#endif
using namespace mozilla;
using namespace mozilla::gfx;
using namespace gl;
using namespace layers;
using namespace android;
SurfaceFactory_Gralloc::SurfaceFactory_Gralloc(GLContext* prodGL,
const SurfaceCaps& caps,
layers::ISurfaceAllocator* allocator)
: SurfaceFactory_GL(prodGL, SharedSurfaceType::Gralloc, caps)
{
if (caps.surfaceAllocator) {
allocator = caps.surfaceAllocator;
}
MOZ_ASSERT(allocator);
mAllocator = allocator;
}
SharedSurface_Gralloc*
SharedSurface_Gralloc::Create(GLContext* prodGL,
const GLFormats& formats,
const gfx::IntSize& size,
bool hasAlpha,
ISurfaceAllocator* allocator)
{
GLLibraryEGL* egl = &sEGLLibrary;
MOZ_ASSERT(egl);
DEBUG_PRINT("SharedSurface_Gralloc::Create -------\n");
if (!HasExtensions(egl, prodGL))
return nullptr;
gfxContentType type = hasAlpha ? gfxContentType::COLOR_ALPHA
: gfxContentType::COLOR;
gfxImageFormat format
= gfxPlatform::GetPlatform()->OptimalFormatForContent(type);
RefPtr<GrallocTextureClientOGL> grallocTC =
new GrallocTextureClientOGL(
allocator,
gfx::ImageFormatToSurfaceFormat(format),
gfx::BackendType::NONE, // we don't need to use it with a DrawTarget
TEXTURE_FLAGS_DEFAULT);
if (!grallocTC->AllocateForGLRendering(size)) {
return nullptr;
}
sp<GraphicBuffer> buffer = grallocTC->GetGraphicBuffer();
EGLDisplay display = egl->Display();
EGLClientBuffer clientBuffer = buffer->getNativeBuffer();
EGLint attrs[] = {
LOCAL_EGL_NONE, LOCAL_EGL_NONE
};
EGLImage image = egl->fCreateImage(display,
EGL_NO_CONTEXT,
LOCAL_EGL_NATIVE_BUFFER_ANDROID,
clientBuffer, attrs);
if (!image) {
return nullptr;
}
prodGL->MakeCurrent();
GLuint prodTex = 0;
prodGL->fGenTextures(1, &prodTex);
ScopedBindTexture autoTex(prodGL, prodTex);
prodGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
prodGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
prodGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
prodGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
prodGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, image);
egl->fDestroyImage(display, image);
SharedSurface_Gralloc *surf = new SharedSurface_Gralloc(prodGL, size, hasAlpha, egl, allocator, grallocTC, prodTex);
DEBUG_PRINT("SharedSurface_Gralloc::Create: success -- surface %p, GraphicBuffer %p.\n", surf, buffer.get());
return surf;
}
bool
SharedSurface_Gralloc::HasExtensions(GLLibraryEGL* egl, GLContext* gl)
{
return egl->HasKHRImageBase() &&
gl->IsExtensionSupported(GLContext::OES_EGL_image);
}
SharedSurface_Gralloc::~SharedSurface_Gralloc()
{
DEBUG_PRINT("[SharedSurface_Gralloc %p] destroyed\n", this);
mGL->MakeCurrent();
mGL->fDeleteTextures(1, &mProdTex);
}
void
SharedSurface_Gralloc::Fence()
{
// We should be able to rely on genlock write locks/read locks.
// But they're broken on some configs, and even a glFinish doesn't
// work. glReadPixels seems to, though.
if (gfxPrefs::GrallocFenceWithReadPixels()) {
mGL->MakeCurrent();
// read a 1x1 pixel
unsigned char pixels[4];
mGL->fReadPixels(0, 0, 1, 1, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, &pixels[0]);
}
}
bool
SharedSurface_Gralloc::WaitSync()
{
return true;
}