зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1728350 - Remove remaining texture-from-pixmap usage. r=gfx-reviewers,jgilbert
Differential Revision: https://phabricator.services.mozilla.com/D124093
This commit is contained in:
Родитель
d7da7d12a4
Коммит
7d160f6bbc
|
@ -164,9 +164,6 @@ bool GLXLibrary::EnsureInitialized(Display* aDisplay) {
|
|||
}
|
||||
}
|
||||
|
||||
const SymLoadStruct symbols_texturefrompixmap[] = {
|
||||
SYMBOL(BindTexImageEXT), SYMBOL(ReleaseTexImageEXT), END_OF_SYMBOLS};
|
||||
|
||||
const SymLoadStruct symbols_createcontext[] = {
|
||||
SYMBOL(CreateContextAttribsARB), END_OF_SYMBOLS};
|
||||
|
||||
|
@ -191,14 +188,6 @@ bool GLXLibrary::EnsureInitialized(Display* aDisplay) {
|
|||
fQueryServerString(aDisplay, screen, LOCAL_GLX_VENDOR);
|
||||
const char* extensionsStr = fQueryExtensionsString(aDisplay, screen);
|
||||
|
||||
if (HasExtension(extensionsStr, "GLX_EXT_texture_from_pixmap") &&
|
||||
fnLoadSymbols(symbols_texturefrompixmap)) {
|
||||
mUseTextureFromPixmap = StaticPrefs::gfx_use_glx_texture_from_pixmap();
|
||||
} else {
|
||||
mUseTextureFromPixmap = false;
|
||||
NS_WARNING("Texture from pixmap disabled");
|
||||
}
|
||||
|
||||
if (HasExtension(extensionsStr, "GLX_ARB_create_context") &&
|
||||
HasExtension(extensionsStr, "GLX_ARB_create_context_profile") &&
|
||||
fnLoadSymbols(symbols_createcontext)) {
|
||||
|
@ -244,19 +233,6 @@ bool GLXLibrary::EnsureInitialized(Display* aDisplay) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GLXLibrary::SupportsTextureFromPixmap(gfxASurface* aSurface) {
|
||||
if (aSurface->GetType() != gfxSurfaceType::Xlib) {
|
||||
return false;
|
||||
}
|
||||
|
||||
gfxXlibSurface* xs = static_cast<gfxXlibSurface*>(aSurface);
|
||||
if (!EnsureInitialized(xs->XDisplay())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return mUseTextureFromPixmap;
|
||||
}
|
||||
|
||||
bool GLXLibrary::SupportsVideoSync(Display* aDisplay) {
|
||||
if (!EnsureInitialized(aDisplay)) {
|
||||
return false;
|
||||
|
@ -265,187 +241,6 @@ bool GLXLibrary::SupportsVideoSync(Display* aDisplay) {
|
|||
return mHasVideoSync;
|
||||
}
|
||||
|
||||
GLXPixmap GLXLibrary::CreatePixmap(gfxASurface* aSurface) {
|
||||
if (!SupportsTextureFromPixmap(aSurface)) {
|
||||
return X11None;
|
||||
}
|
||||
|
||||
gfxXlibSurface* xs = static_cast<gfxXlibSurface*>(aSurface);
|
||||
const XRenderPictFormat* format = xs->XRenderFormat();
|
||||
if (!format || format->type != PictTypeDirect) {
|
||||
return X11None;
|
||||
}
|
||||
const XRenderDirectFormat& direct = format->direct;
|
||||
int alphaSize = FloorLog2(direct.alphaMask + 1);
|
||||
NS_ASSERTION((1 << alphaSize) - 1 == direct.alphaMask,
|
||||
"Unexpected render format with non-adjacent alpha bits");
|
||||
|
||||
int attribs[] = {LOCAL_GLX_DOUBLEBUFFER,
|
||||
X11False,
|
||||
LOCAL_GLX_DRAWABLE_TYPE,
|
||||
LOCAL_GLX_PIXMAP_BIT,
|
||||
LOCAL_GLX_ALPHA_SIZE,
|
||||
alphaSize,
|
||||
(alphaSize ? LOCAL_GLX_BIND_TO_TEXTURE_RGBA_EXT
|
||||
: LOCAL_GLX_BIND_TO_TEXTURE_RGB_EXT),
|
||||
X11True,
|
||||
LOCAL_GLX_RENDER_TYPE,
|
||||
LOCAL_GLX_RGBA_BIT,
|
||||
X11None};
|
||||
|
||||
int numConfigs = 0;
|
||||
Display* display = xs->XDisplay();
|
||||
int xscreen = DefaultScreen(display);
|
||||
|
||||
ScopedXFree<GLXFBConfig> cfgs(
|
||||
fChooseFBConfig(display, xscreen, attribs, &numConfigs));
|
||||
|
||||
// Find an fbconfig that matches the pixel format used on the Pixmap.
|
||||
int matchIndex = -1;
|
||||
unsigned long redMask = static_cast<unsigned long>(direct.redMask)
|
||||
<< direct.red;
|
||||
unsigned long greenMask = static_cast<unsigned long>(direct.greenMask)
|
||||
<< direct.green;
|
||||
unsigned long blueMask = static_cast<unsigned long>(direct.blueMask)
|
||||
<< direct.blue;
|
||||
// This is true if the Pixmap has bits for alpha or unused bits.
|
||||
bool haveNonColorBits =
|
||||
~(redMask | greenMask | blueMask) != -1UL << format->depth;
|
||||
|
||||
for (int i = 0; i < numConfigs; i++) {
|
||||
int id = X11None;
|
||||
sGLXLibrary.fGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_VISUAL_ID, &id);
|
||||
Visual* visual;
|
||||
int depth;
|
||||
FindVisualAndDepth(display, id, &visual, &depth);
|
||||
if (!visual || visual->c_class != TrueColor ||
|
||||
visual->red_mask != redMask || visual->green_mask != greenMask ||
|
||||
visual->blue_mask != blueMask) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Historically Xlib Visuals did not try to represent an alpha channel
|
||||
// and there was no means to use an alpha channel on a Pixmap. The
|
||||
// Xlib Visual from the fbconfig was not intended to have any
|
||||
// information about alpha bits.
|
||||
//
|
||||
// Since then, RENDER has added formats for 32 bit depth Pixmaps.
|
||||
// Some of these formats have bits for alpha and some have unused
|
||||
// bits.
|
||||
//
|
||||
// Then the Composite extension added a 32 bit depth Visual intended
|
||||
// for Windows with an alpha channel, so bits not in the visual color
|
||||
// masks were expected to be treated as alpha bits.
|
||||
//
|
||||
// Usually GLX counts only color bits in the Visual depth, but the
|
||||
// depth of Composite's ARGB Visual includes alpha bits. However,
|
||||
// bits not in the color masks are not necessarily alpha bits because
|
||||
// sometimes (NVIDIA) 32 bit Visuals are added for fbconfigs with 32
|
||||
// bit BUFFER_SIZE but zero alpha bits and 24 color bits (NVIDIA
|
||||
// again).
|
||||
//
|
||||
// This checks that the depth matches in one of the two ways.
|
||||
// NVIDIA now forces format->depth == depth so only the first way
|
||||
// is checked for NVIDIA
|
||||
if (depth != format->depth &&
|
||||
(mIsNVIDIA || depth != format->depth - alphaSize)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If all bits of the Pixmap are color bits and the Pixmap depth
|
||||
// matches the depth of the fbconfig visual, then we can assume that
|
||||
// the driver will do whatever is necessary to ensure that any
|
||||
// GLXPixmap alpha bits are treated as set. We can skip the
|
||||
// ALPHA_SIZE check in this situation. We need to skip this check for
|
||||
// situations (ATI) where there are no fbconfigs without alpha bits.
|
||||
//
|
||||
// glXChooseFBConfig should prefer configs with smaller
|
||||
// LOCAL_GLX_BUFFER_SIZE, so we should still get zero alpha bits if
|
||||
// available, except perhaps with NVIDIA drivers where buffer size is
|
||||
// not the specified sum of the component sizes.
|
||||
if (haveNonColorBits) {
|
||||
// There are bits in the Pixmap format that haven't been matched
|
||||
// against the fbconfig visual. These bits could either represent
|
||||
// alpha or be unused, so just check that the number of alpha bits
|
||||
// matches.
|
||||
int size = 0;
|
||||
sGLXLibrary.fGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_ALPHA_SIZE,
|
||||
&size);
|
||||
if (size != alphaSize) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
matchIndex = i;
|
||||
break;
|
||||
}
|
||||
if (matchIndex == -1) {
|
||||
// GLX can't handle A8 surfaces, so this is not really unexpected. The
|
||||
// caller should deal with this situation.
|
||||
NS_WARNING_ASSERTION(
|
||||
format->depth == 8,
|
||||
"[GLX] Couldn't find a FBConfig matching Pixmap format");
|
||||
return X11None;
|
||||
}
|
||||
|
||||
int pixmapAttribs[] = {LOCAL_GLX_TEXTURE_TARGET_EXT, LOCAL_GLX_TEXTURE_2D_EXT,
|
||||
LOCAL_GLX_TEXTURE_FORMAT_EXT,
|
||||
(alphaSize ? LOCAL_GLX_TEXTURE_FORMAT_RGBA_EXT
|
||||
: LOCAL_GLX_TEXTURE_FORMAT_RGB_EXT),
|
||||
X11None};
|
||||
|
||||
GLXPixmap glxpixmap =
|
||||
fCreatePixmap(display, cfgs[matchIndex], xs->XDrawable(), pixmapAttribs);
|
||||
|
||||
return glxpixmap;
|
||||
}
|
||||
|
||||
void GLXLibrary::DestroyPixmap(Display* aDisplay, GLXPixmap aPixmap) {
|
||||
if (!mUseTextureFromPixmap) {
|
||||
return;
|
||||
}
|
||||
|
||||
fDestroyPixmap(aDisplay, aPixmap);
|
||||
}
|
||||
|
||||
void GLXLibrary::BindTexImage(Display* aDisplay, GLXPixmap aPixmap) {
|
||||
if (!mUseTextureFromPixmap) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure all X drawing to the surface has finished before binding to a
|
||||
// texture.
|
||||
if (mClientIsMesa) {
|
||||
// Using XSync instead of Mesa's glXWaitX, because its glxWaitX is a
|
||||
// noop when direct rendering unless the current drawable is a
|
||||
// single-buffer window.
|
||||
FinishX(aDisplay);
|
||||
} else {
|
||||
fWaitX();
|
||||
}
|
||||
fBindTexImage(aDisplay, aPixmap, LOCAL_GLX_FRONT_LEFT_EXT, nullptr);
|
||||
}
|
||||
|
||||
void GLXLibrary::ReleaseTexImage(Display* aDisplay, GLXPixmap aPixmap) {
|
||||
if (!mUseTextureFromPixmap) {
|
||||
return;
|
||||
}
|
||||
|
||||
fReleaseTexImage(aDisplay, aPixmap, LOCAL_GLX_FRONT_LEFT_EXT);
|
||||
}
|
||||
|
||||
void GLXLibrary::UpdateTexImage(Display* aDisplay, GLXPixmap aPixmap) {
|
||||
// NVIDIA drivers don't require a rebind of the pixmap in order
|
||||
// to display an updated image, and it's faster not to do it.
|
||||
if (mIsNVIDIA) {
|
||||
fWaitX();
|
||||
return;
|
||||
}
|
||||
|
||||
ReleaseTexImage(aDisplay, aPixmap);
|
||||
BindTexImage(aDisplay, aPixmap);
|
||||
}
|
||||
|
||||
static int (*sOldErrorHandler)(Display*, XErrorEvent*);
|
||||
ScopedXErrorHandler::ErrorEvent sErrorEvent;
|
||||
static int GLXErrorHandler(Display* display, XErrorEvent* ev) {
|
||||
|
|
|
@ -207,15 +207,6 @@ class GLXLibrary final {
|
|||
|
||||
////
|
||||
|
||||
GLXPixmap CreatePixmap(gfxASurface* aSurface);
|
||||
void DestroyPixmap(Display* aDisplay, GLXPixmap aPixmap);
|
||||
void BindTexImage(Display* aDisplay, GLXPixmap aPixmap);
|
||||
void ReleaseTexImage(Display* aDisplay, GLXPixmap aPixmap);
|
||||
void UpdateTexImage(Display* aDisplay, GLXPixmap aPixmap);
|
||||
|
||||
////
|
||||
|
||||
bool UseTextureFromPixmap() { return mUseTextureFromPixmap; }
|
||||
bool HasRobustness() { return mHasRobustness; }
|
||||
bool HasVideoMemoryPurge() { return mHasVideoMemoryPurge; }
|
||||
bool HasCreateContextAttribs() { return mHasCreateContextAttribs; }
|
||||
|
@ -271,7 +262,6 @@ class GLXLibrary final {
|
|||
|
||||
bool mInitialized = false;
|
||||
bool mTriedInitializing = false;
|
||||
bool mUseTextureFromPixmap = false;
|
||||
bool mDebug = false;
|
||||
bool mHasRobustness = false;
|
||||
bool mHasVideoMemoryPurge = false;
|
||||
|
|
|
@ -26,8 +26,7 @@ using namespace mozilla::gfx;
|
|||
gfxXlibSurface::gfxXlibSurface(Display* dpy, Drawable drawable, Visual* visual)
|
||||
: mPixmapTaken(false),
|
||||
mDisplay(XlibDisplay::Borrow(dpy)),
|
||||
mDrawable(drawable),
|
||||
mGLXPixmap(X11None) {
|
||||
mDrawable(drawable) {
|
||||
const gfx::IntSize size = DoSizeQuery();
|
||||
cairo_surface_t* surf =
|
||||
cairo_xlib_surface_create(dpy, drawable, visual, size.width, size.height);
|
||||
|
@ -41,10 +40,7 @@ gfxXlibSurface::gfxXlibSurface(Display* dpy, Drawable drawable, Visual* visual,
|
|||
gfxXlibSurface::gfxXlibSurface(const std::shared_ptr<XlibDisplay>& dpy,
|
||||
Drawable drawable, Visual* visual,
|
||||
const gfx::IntSize& size)
|
||||
: mPixmapTaken(false),
|
||||
mDisplay(dpy),
|
||||
mDrawable(drawable),
|
||||
mGLXPixmap(X11None) {
|
||||
: mPixmapTaken(false), mDisplay(dpy), mDrawable(drawable) {
|
||||
NS_ASSERTION(Factory::CheckSurfaceSize(size, XLIB_IMAGE_SIDE_SIZE_LIMIT),
|
||||
"Bad size");
|
||||
|
||||
|
@ -58,8 +54,7 @@ gfxXlibSurface::gfxXlibSurface(Screen* screen, Drawable drawable,
|
|||
const gfx::IntSize& size)
|
||||
: mPixmapTaken(false),
|
||||
mDisplay(XlibDisplay::Borrow(DisplayOfScreen(screen))),
|
||||
mDrawable(drawable),
|
||||
mGLXPixmap(X11None) {
|
||||
mDrawable(drawable) {
|
||||
NS_ASSERTION(Factory::CheckSurfaceSize(size, XLIB_IMAGE_SIDE_SIZE_LIMIT),
|
||||
"Bad Size");
|
||||
|
||||
|
@ -68,8 +63,7 @@ gfxXlibSurface::gfxXlibSurface(Screen* screen, Drawable drawable,
|
|||
Init(surf);
|
||||
}
|
||||
|
||||
gfxXlibSurface::gfxXlibSurface(cairo_surface_t* csurf)
|
||||
: mPixmapTaken(false), mGLXPixmap(X11None) {
|
||||
gfxXlibSurface::gfxXlibSurface(cairo_surface_t* csurf) : mPixmapTaken(false) {
|
||||
MOZ_ASSERT(cairo_surface_status(csurf) == 0,
|
||||
"Not expecting an error surface");
|
||||
|
||||
|
@ -82,9 +76,6 @@ gfxXlibSurface::gfxXlibSurface(cairo_surface_t* csurf)
|
|||
gfxXlibSurface::~gfxXlibSurface() {
|
||||
// gfxASurface's destructor calls RecordMemoryFreed().
|
||||
if (mPixmapTaken) {
|
||||
if (mGLXPixmap) {
|
||||
gl::sGLXLibrary.DestroyPixmap(*mDisplay, mGLXPixmap);
|
||||
}
|
||||
XFreePixmap(*mDisplay, mDrawable);
|
||||
}
|
||||
}
|
||||
|
@ -199,13 +190,7 @@ already_AddRefed<gfxXlibSurface> gfxXlibSurface::Create(
|
|||
return result.forget();
|
||||
}
|
||||
|
||||
void gfxXlibSurface::Finish() {
|
||||
if (mPixmapTaken && mGLXPixmap) {
|
||||
gl::sGLXLibrary.DestroyPixmap(*mDisplay, mGLXPixmap);
|
||||
mGLXPixmap = X11None;
|
||||
}
|
||||
gfxASurface::Finish();
|
||||
}
|
||||
void gfxXlibSurface::Finish() { gfxASurface::Finish(); }
|
||||
|
||||
const gfx::IntSize gfxXlibSurface::GetSize() const {
|
||||
if (!mSurfaceValid) return gfx::IntSize(0, 0);
|
||||
|
@ -481,23 +466,3 @@ Screen* gfxXlibSurface::XScreen() {
|
|||
XRenderPictFormat* gfxXlibSurface::XRenderFormat() {
|
||||
return cairo_xlib_surface_get_xrender_format(CairoSurface());
|
||||
}
|
||||
|
||||
GLXPixmap gfxXlibSurface::GetGLXPixmap() {
|
||||
if (!mGLXPixmap) {
|
||||
#ifdef DEBUG
|
||||
// cairo_surface_has_show_text_glyphs is used solely for the
|
||||
// side-effect of setting the error on surface if
|
||||
// cairo_surface_finish() has been called.
|
||||
cairo_surface_has_show_text_glyphs(CairoSurface());
|
||||
NS_ASSERTION(CairoStatus() != CAIRO_STATUS_SURFACE_FINISHED,
|
||||
"GetGLXPixmap called after surface finished");
|
||||
#endif
|
||||
mGLXPixmap = gl::sGLXLibrary.CreatePixmap(this);
|
||||
}
|
||||
return mGLXPixmap;
|
||||
}
|
||||
|
||||
void gfxXlibSurface::BindGLXPixmap(GLXPixmap aPixmap) {
|
||||
MOZ_ASSERT(!mGLXPixmap, "A GLXPixmap is already bound!");
|
||||
mGLXPixmap = aPixmap;
|
||||
}
|
||||
|
|
|
@ -88,11 +88,6 @@ class gfxXlibSurface final : public gfxASurface {
|
|||
// Find a visual and colormap pair suitable for rendering to this surface.
|
||||
bool GetColormapAndVisual(Colormap* colormap, Visual** visual);
|
||||
|
||||
GLXPixmap GetGLXPixmap();
|
||||
// Binds a GLXPixmap backed by this context's surface.
|
||||
// Primarily for use in sharing surfaces.
|
||||
void BindGLXPixmap(GLXPixmap aPixmap);
|
||||
|
||||
// Return true if cairo will take its slow path when this surface is used
|
||||
// in a pattern with EXTEND_PAD. As a workaround for XRender's RepeatPad
|
||||
// not being implemented correctly on old X servers, cairo avoids XRender
|
||||
|
@ -113,8 +108,6 @@ class gfxXlibSurface final : public gfxASurface {
|
|||
Drawable mDrawable;
|
||||
|
||||
const mozilla::gfx::IntSize DoSizeQuery();
|
||||
|
||||
GLXPixmap mGLXPixmap;
|
||||
};
|
||||
|
||||
#endif /* GFX_XLIBSURFACE_H */
|
||||
|
|
|
@ -5012,13 +5012,6 @@
|
|||
value: false
|
||||
mirror: once
|
||||
|
||||
# Disable surface sharing due to issues with compatible FBConfigs on
|
||||
# NVIDIA drivers as described in bug 1193015.
|
||||
- name: gfx.use-glx-texture-from-pixmap
|
||||
type: RelaxedAtomicBool
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
- name: gfx.use-iosurface-textures
|
||||
type: bool
|
||||
value: false
|
||||
|
|
Загрузка…
Ссылка в новой задаче