Chromium Code Reviews| Index: ui/base/x/x11_util.cc |
| diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc |
| index f36aa0101cebfc17d925b5d7a2c1fd764f98e6c1..a0d10805b897a078ad6e739ee1dee402832638fd 100644 |
| --- a/ui/base/x/x11_util.cc |
| +++ b/ui/base/x/x11_util.cc |
| @@ -14,6 +14,7 @@ |
| #include <list> |
| #include <map> |
| +#include <mutex> |
| #include <utility> |
| #include <vector> |
| @@ -22,6 +23,7 @@ |
| #include <X11/Xcursor/Xcursor.h> |
| #include "base/bind.h" |
| +#include "base/command_line.h" |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/memory/singleton.h" |
| @@ -52,6 +54,7 @@ |
| #include "ui/gfx/image/image_skia_rep.h" |
| #include "ui/gfx/skia_util.h" |
| #include "ui/gfx/x/x11_error_tracker.h" |
| +#include "ui/gfx/x/x11_switches.h" |
| #if defined(OS_FREEBSD) |
| #include <sys/sysctl.h> |
| @@ -1409,6 +1412,65 @@ void LogErrorEventDescription(XDisplay* dpy, |
| << " (" << request_str << ")"; |
| } |
| +static void ChooseARGBVisualForWindowOnce(Visual** visual, int* depth) { |
| + XDisplay* display = gfx::GetXDisplay(); |
| + XAtom NET_WM_CM_S0 = XInternAtom(display, "_NET_WM_CM_S0", False); |
| + |
| + // TODO(cwallez) make the switch be a constant again |
| + if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| + "enable-transparent-visuals") && |
| + XGetSelectionOwner(display, NET_WM_CM_S0) != None) { |
| + // Choose the first ARGB8888 visual |
| + XVisualInfo visual_template; |
| + visual_template.screen = 0; |
| + |
| + int visuals_len; |
| + gfx::XScopedPtr<XVisualInfo[]> visual_list(XGetVisualInfo( |
| + display, VisualScreenMask, &visual_template, &visuals_len)); |
| + for (int i = 0; i < visuals_len; ++i) { |
| + // Why support only 8888 ARGB? Because it's all that GTK+ supports. In |
| + // gdkvisual-x11.cc, they look for this specific visual and use it for all |
| + // their alpha channel using needs. |
| + // |
| + // TODO(erg): While the following does find a valid visual, some GL |
| + // drivers |
| + // don't believe that this has an alpha channel. According to marcheu@, |
| + // this should work on open source driver though. (It doesn't work with |
| + // NVidia's binaries currently.) http://crbug.com/369209 |
| + const XVisualInfo& info = visual_list[i]; |
| + if (info.depth == 32 && info.visual->red_mask == 0xff0000 && |
| + info.visual->green_mask == 0x00ff00 && |
| + info.visual->blue_mask == 0x0000ff) { |
| + *visual = info.visual; |
| + *depth = info.depth; |
| + } |
| + } |
| + } else { |
| + XWindowAttributes windowAttribs; |
| + Window root = XDefaultRootWindow(display); |
| + Status status = XGetWindowAttributes(display, root, &windowAttribs); |
| + DCHECK(status != 0); |
| + *visual = windowAttribs.visual; |
| + *depth = windowAttribs.depth; |
| + } |
| +} |
| + |
| +void ChooseARGBVisualForWindow(Visual** visual, int* depth) { |
| + static std::once_flag init_flag; |
| + static Visual* s_visual = NULL; |
| + static int s_depth = 0; |
| + |
| + std::call_once(init_flag, ChooseARGBVisualForWindowOnce, &s_visual, &s_depth); |
|
piman
2015/11/20 01:44:41
std::call_once is a c++11 library feature that is
Julien Isorce Samsung
2015/11/20 09:13:55
Acknowledged.
|
| + |
| + DCHECK(s_visual); |
| + DCHECK(s_depth > 0); |
| + |
| + if (visual) |
| + *visual = s_visual; |
| + if (depth) |
| + *depth = s_depth; |
| +} |
| + |
| // ---------------------------------------------------------------------------- |
| // End of x11_util_internal.h |