| Index: ui/base/x/x11_util.cc
|
| diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc
|
| index 681a2e19a0ebce40b4ae3cdb9a45f4cc2a2c3b88..29ef2d73c6e83e9ac19c19e0492375ba6e3dd4bf 100644
|
| --- a/ui/base/x/x11_util.cc
|
| +++ b/ui/base/x/x11_util.cc
|
| @@ -1412,67 +1412,110 @@ void LogErrorEventDescription(XDisplay* dpy,
|
| }
|
|
|
| #if !defined(OS_CHROMEOS)
|
| -void ChooseVisualForWindow(bool enable_transparent_visuals,
|
| - Visual** visual,
|
| - int* depth) {
|
| - static Visual* s_default_visual = nullptr;
|
| - static Visual* s_transparent_visual = nullptr;
|
| - static int s_default_depth = 0;
|
| - static int s_transparent_depth = 0;
|
|
|
| - if (!s_default_visual || !s_transparent_visual) {
|
| - XDisplay* display = gfx::GetXDisplay();
|
| - XAtom NET_WM_CM_S0 = XInternAtom(display, "_NET_WM_CM_S0", False);
|
| +// static
|
| +XVisualManager* XVisualManager::GetInstance() {
|
| + return base::Singleton<XVisualManager>::get();
|
| +}
|
|
|
| - if (enable_transparent_visuals &&
|
| - XGetSelectionOwner(display, NET_WM_CM_S0) != None) {
|
| - // Choose the first ARGB8888 visual
|
| - XVisualInfo visual_template;
|
| - visual_template.screen = 0;
|
| +XVisualManager::XVisualManager()
|
| + : display_(gfx::GetXDisplay()),
|
| + system_visual_id_(0),
|
| + transparent_visual_id_(0),
|
| + using_software_rendering_(false),
|
| + have_gpu_argb_visual_(false) {
|
| + int visuals_len;
|
| + XVisualInfo visual_template;
|
| + visual_template.screen = DefaultScreen(display_);
|
| + gfx::XScopedPtr<XVisualInfo[]> visual_list(XGetVisualInfo(
|
| + display_, VisualScreenMask, &visual_template, &visuals_len));
|
| + for (int i = 0; i < visuals_len; ++i)
|
| + visuals_[visual_list[i].visualid].reset(new XVisualData(visual_list[i]));
|
|
|
| - 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.
|
| - 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) {
|
| - s_transparent_visual = info.visual;
|
| - s_transparent_depth = info.depth;
|
| - DCHECK(s_transparent_visual);
|
| - break;
|
| - }
|
| - }
|
| - }
|
| + XAtom NET_WM_CM_S0 = XInternAtom(display_, "_NET_WM_CM_S0", False);
|
| + using_compositing_wm_ = XGetSelectionOwner(display_, NET_WM_CM_S0) != None;
|
|
|
| - XWindowAttributes attribs;
|
| - Window root = XDefaultRootWindow(display);
|
| - Status status = XGetWindowAttributes(display, root, &attribs);
|
| - DCHECK_NE(0, status);
|
| - s_default_visual = attribs.visual;
|
| - s_default_depth = attribs.depth;
|
| + // Choose the opaque visual.
|
| + XWindowAttributes attribs;
|
| + Window root = XDefaultRootWindow(display_);
|
| + Status status = XGetWindowAttributes(display_, root, &attribs);
|
| + DCHECK_NE(0, status);
|
| + system_visual_id_ = attribs.visual->visualid;
|
| + DCHECK(system_visual_id_);
|
| + DCHECK(visuals_.find(system_visual_id_) != visuals_.end());
|
|
|
| - if (!s_transparent_visual) {
|
| - s_transparent_visual = s_default_visual;
|
| - s_transparent_depth = s_default_depth;
|
| + // Choose the transparent visual.
|
| + for (const auto& pair : visuals_) {
|
| + // 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.
|
| + const XVisualInfo& info = pair.second->visual_info;
|
| + if (info.depth == 32 && info.visual->red_mask == 0xff0000 &&
|
| + info.visual->green_mask == 0x00ff00 &&
|
| + info.visual->blue_mask == 0x0000ff) {
|
| + transparent_visual_id_ = info.visualid;
|
| + break;
|
| }
|
| - } // !s_default_visual || !s_transparent_visual
|
| + }
|
| + DCHECK(transparent_visual_id_);
|
| + DCHECK(visuals_.find(transparent_visual_id_) != visuals_.end());
|
| +}
|
|
|
| - DCHECK(s_default_visual);
|
| - DCHECK(s_default_depth > 0);
|
| - DCHECK(s_transparent_visual);
|
| - DCHECK(s_transparent_depth > 0);
|
| +XVisualManager::~XVisualManager() {}
|
|
|
| +void XVisualManager::ChooseVisualForWindow(bool want_argb_visual,
|
| + Visual** visual,
|
| + int* depth,
|
| + Colormap* colormap,
|
| + bool* using_argb_visual) {
|
| + bool use_argb = want_argb_visual && using_compositing_wm_ &&
|
| + (using_software_rendering_ || have_gpu_argb_visual_);
|
| + XVisualData& visual_data =
|
| + *visuals_[use_argb ? transparent_visual_id_ : system_visual_id_];
|
| if (visual)
|
| - *visual =
|
| - enable_transparent_visuals ? s_transparent_visual : s_default_visual;
|
| + *visual = visual_data.visual_info.visual;
|
| if (depth)
|
| - *depth = enable_transparent_visuals ? s_transparent_depth : s_default_depth;
|
| + *depth = visual_data.visual_info.depth;
|
| + if (colormap)
|
| + *colormap = visual_data.GetColormap();
|
| + if (using_argb_visual)
|
| + *using_argb_visual = use_argb;
|
| }
|
| +
|
| +bool XVisualManager::OnGPUInfoChanged(bool software_rendering,
|
| + VisualID system_visual_id,
|
| + VisualID transparent_visual_id) {
|
| + // TODO(thomasanderson): Cache these visual IDs as a property of the root
|
| + // window so that newly created browser processes can get them immediately.
|
| + if ((system_visual_id && !visuals_.count(system_visual_id)) ||
|
| + (transparent_visual_id && !visuals_.count(transparent_visual_id)))
|
| + return false;
|
| + using_software_rendering_ = software_rendering;
|
| + have_gpu_argb_visual_ = have_gpu_argb_visual_ || transparent_visual_id;
|
| + if (system_visual_id)
|
| + system_visual_id_ = system_visual_id;
|
| + if (transparent_visual_id)
|
| + transparent_visual_id_ = transparent_visual_id;
|
| + return true;
|
| +}
|
| +
|
| +XVisualManager::XVisualData::XVisualData(XVisualInfo visual_info)
|
| + : visual_info(visual_info), colormap_(CopyFromParent) {}
|
| +
|
| +XVisualManager::XVisualData::~XVisualData() {
|
| + // Do not XFreeColormap as this would uninstall the colormap even for
|
| + // non-Chromium clients.
|
| +}
|
| +
|
| +Colormap XVisualManager::XVisualData::GetColormap() {
|
| + XDisplay* display = gfx::GetXDisplay();
|
| + if (colormap_ == CopyFromParent) {
|
| + colormap_ = XCreateColormap(display, DefaultRootWindow(display),
|
| + visual_info.visual, AllocNone);
|
| + }
|
| + return colormap_;
|
| +}
|
| +
|
| #endif
|
|
|
| // ----------------------------------------------------------------------------
|
|
|