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:
Nicolas Silva 2021-09-01 17:07:46 +00:00
Родитель d7da7d12a4
Коммит 7d160f6bbc
5 изменённых файлов: 5 добавлений и 269 удалений

Просмотреть файл

@ -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