gl_surface_glx.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" { 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <X11/Xlib.h> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_surface_glx.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h" 13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/lazy_instance.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/cancellation_flag.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/non_thread_safe.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/mesa/src/include/GL/osmesa.h" 2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/gfx/x/x11_types.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_bindings.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_implementation.h" 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/gl/sync_control_vsync_provider.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// scoped_ptr functor for XFree(). Use as follows: 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// scoped_ptr<XVisualInfo, ScopedPtrXFree> foo(...); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// where "XVisualInfo" is any X type that is freed with XFree. 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)struct ScopedPtrXFree { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void operator()(void* x) const { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::XFree(x); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)Display* g_display = NULL; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* g_glx_extensions = NULL; 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool g_glx_context_create = false; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_glx_create_context_robustness_supported = false; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_glx_texture_from_pixmap_supported = false; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_glx_oml_sync_control_supported = false; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Track support of glXGetMscRateOML separately from GLX_OML_sync_control as a 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// whole since on some platforms (e.g. crosbug.com/34585), glXGetMscRateOML 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// always fails even though GLX_OML_sync_control is reported as being supported. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_glx_get_msc_rate_oml_supported = false; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_glx_sgi_video_sync_supported = false; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OMLSyncControlVSyncProvider 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public gfx::SyncControlVSyncProvider { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit OMLSyncControlVSyncProvider(gfx::AcceleratedWidget window) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : SyncControlVSyncProvider(), 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window_(window) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~OMLSyncControlVSyncProvider() { } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool GetSyncValues(int64* system_time, 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64* media_stream_counter, 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64* swap_buffer_counter) OVERRIDE { 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return glXGetSyncValuesOML(g_display, window_, system_time, 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) media_stream_counter, swap_buffer_counter); 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool GetMscRate(int32* numerator, int32* denominator) OVERRIDE { 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!g_glx_get_msc_rate_oml_supported) 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!glXGetMscRateOML(g_display, window_, numerator, denominator)) { 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Once glXGetMscRateOML has been found to fail, don't try again, 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // since each failing call may spew an error message. 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_glx_get_msc_rate_oml_supported = false; 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XID window_; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(OMLSyncControlVSyncProvider); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SGIVideoSyncThread 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public base::Thread, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public base::NonThreadSafe, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public base::RefCounted<SGIVideoSyncThread> { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static scoped_refptr<SGIVideoSyncThread> Create() { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!g_video_sync_thread) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_video_sync_thread = new SGIVideoSyncThread(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_video_sync_thread->Start(); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_video_sync_thread; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCounted<SGIVideoSyncThread>; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SGIVideoSyncThread() : base::Thread("SGI_video_sync") { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~SGIVideoSyncThread() { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_video_sync_thread = NULL; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static SGIVideoSyncThread* g_video_sync_thread; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncThread); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class SGIVideoSyncProviderThreadShim { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit SGIVideoSyncProviderThreadShim(XID window) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : window_(window), 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_(NULL), 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_(base::MessageLoopProxy::current()), 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cancel_vsync_flag_(), 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vsync_lock_() { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This ensures that creation of |window_| has occured when this shim 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is executing in the same process as the call to create |window_|. 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) XSync(g_display, False); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual ~SGIVideoSyncProviderThreadShim() { 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (context_) { 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) glXDestroyContext(display_, context_); 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) context_ = NULL; 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::CancellationFlag* cancel_vsync_flag() { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &cancel_vsync_flag_; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Lock* vsync_lock() { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &vsync_lock_; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Initialize() { 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(display_); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XWindowAttributes attributes; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!XGetWindowAttributes(display_, window_, &attributes)) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "XGetWindowAttributes failed for window " << 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_ << "."; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XVisualInfo visual_info_template; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visual_info_template.visualid = XVisualIDFromVisual(attributes.visual); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int visual_info_count = 0; 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<XVisualInfo, ScopedPtrXFree> visual_info_list( 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) XGetVisualInfo(display_, VisualIDMask, 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &visual_info_template, &visual_info_count)); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(visual_info_list.get()); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (visual_info_count == 0) { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "No visual info for visual ID."; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_ = glXCreateContext(display_, visual_info_list.get(), NULL, True); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(NULL != context_); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void GetVSyncParameters(const VSyncProvider::UpdateVSyncCallback& callback) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks now; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't allow |window_| destruction while we're probing vsync. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(vsync_lock_); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!context_ || cancel_vsync_flag_.IsSet()) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) glXMakeCurrent(display_, window_, context_); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int retrace_count = 0; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (glXWaitVideoSyncSGI(1, 0, &retrace_count) != 0) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_EVENT_INSTANT0("gpu", "vblank", TRACE_EVENT_SCOPE_THREAD); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) now = base::TimeTicks::HighResNow(); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) glXMakeCurrent(display_, 0, 0); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::TimeDelta kDefaultInterval = 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromSeconds(1) / 60; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_->PostTask( 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, now, kDefaultInterval)); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For initialization of display_ in GLSurface::InitializeOneOff before 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the sandbox goes up. 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class gfx::GLSurfaceGLX; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static Display* display_; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XID window_; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLXContext context_; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> message_loop_; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::CancellationFlag cancel_vsync_flag_; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Lock vsync_lock_; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncProviderThreadShim); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SGIVideoSyncVSyncProvider 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public gfx::VSyncProvider, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public base::SupportsWeakPtr<SGIVideoSyncVSyncProvider> { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit SGIVideoSyncVSyncProvider(gfx::AcceleratedWidget window) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : vsync_thread_(SGIVideoSyncThread::Create()), 23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) shim_(new SGIVideoSyncProviderThreadShim(window)), 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cancel_vsync_flag_(shim_->cancel_vsync_flag()), 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vsync_lock_(shim_->vsync_lock()) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vsync_thread_->message_loop()->PostTask( 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&SGIVideoSyncProviderThreadShim::Initialize, 24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Unretained(shim_.get()))); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~SGIVideoSyncVSyncProvider() { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(*vsync_lock_); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cancel_vsync_flag_->Set(); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Hand-off |shim_| to be deleted on the |vsync_thread_|. 25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) vsync_thread_->message_loop()->DeleteSoon( 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) shim_.release()); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void GetVSyncParameters( 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const VSyncProvider::UpdateVSyncCallback& callback) OVERRIDE { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only one outstanding request per surface. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pending_callback_) { 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_callback_.reset( 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new VSyncProvider::UpdateVSyncCallback(callback)); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vsync_thread_->message_loop()->PostTask( 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&SGIVideoSyncProviderThreadShim::GetVSyncParameters, 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Unretained(shim_.get()), 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind( 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SGIVideoSyncVSyncProvider::PendingCallbackRunner, 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AsWeakPtr()))); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PendingCallbackRunner(const base::TimeTicks timebase, 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta interval) { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pending_callback_); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_callback_->Run(timebase, interval); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_callback_.reset(); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SGIVideoSyncThread> vsync_thread_; 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Thread shim through which the sync provider is accessed on |vsync_thread_|. 28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SGIVideoSyncProviderThreadShim> shim_; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<VSyncProvider::UpdateVSyncCallback> pending_callback_; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Raw pointers to sync primitives owned by the shim_. 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These will only be referenced before we post a task to destroy 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the shim_, so they are safe to access. 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::CancellationFlag* cancel_vsync_flag_; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Lock* vsync_lock_; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncVSyncProvider); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SGIVideoSyncThread* SGIVideoSyncThread::g_video_sync_thread = NULL; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In order to take advantage of GLX_SGI_video_sync, we need a display 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for use on a separate thread. We must allocate this before the sandbox 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// goes up (rather than on-demand when we start the thread). 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Display* SGIVideoSyncProviderThreadShim::display_ = NULL; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 302d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(TOOLKIT_GTK) 303d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// A mechanism for forwarding XExpose events from one window to another. 304d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Because in the workaround for http://crbug.com/145600 the child window 305d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// is placed on top of the parent window, only the child window will receive 306d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// all expose events. These need to be forwared to the parent window to inform 307d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// it that it should paint. 308d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class XExposeEventForwarder : public base::MessagePumpObserver { 309d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public: 310d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) XExposeEventForwarder() {} 311d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual ~XExposeEventForwarder() { 312d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(child_to_parent_map_.empty()); 313d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 314d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void AddParentChildPair(gfx::AcceleratedWidget parent_window, 315d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) gfx::AcceleratedWidget child_window) { 316d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (child_to_parent_map_.empty()) 317d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::MessagePumpX11::Current()->AddObserver(this); 318d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 319d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(child_to_parent_map_.find(child_window) == 320d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) child_to_parent_map_.end()); 321d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) child_to_parent_map_.insert(std::make_pair( 322d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) child_window, parent_window)); 323d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 324d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void RemoveParentChildPair(gfx::AcceleratedWidget parent_window, 325d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) gfx::AcceleratedWidget child_window) { 326d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(child_to_parent_map_.find(child_window) != 327d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) child_to_parent_map_.end()); 328d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) child_to_parent_map_.erase(child_window); 329d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 330d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (child_to_parent_map_.empty()) 331d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::MessagePumpX11::Current()->RemoveObserver(this); 332d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 334d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private: 335d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual base::EventStatus WillProcessEvent ( 336d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const base::NativeEvent& xevent) OVERRIDE { 337d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (xevent->type != Expose) 338d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return base::EVENT_CONTINUE; 339d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 340d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WindowMap::const_iterator found = child_to_parent_map_.find( 341d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) xevent->xexpose.window); 342d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (found == child_to_parent_map_.end()) 343d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return base::EVENT_CONTINUE; 344d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 345d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) gfx::AcceleratedWidget target_window = found->second; 346d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) XEvent forwarded_event = *xevent; 347d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) forwarded_event.xexpose.window = target_window; 348d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) XSendEvent(g_display, target_window, False, ExposureMask, 349d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &forwarded_event); 350d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return base::EVENT_CONTINUE; 351d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 352d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void DidProcessEvent(const base::NativeEvent& xevent) OVERRIDE { 353d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 354d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 355d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) typedef std::map<gfx::AcceleratedWidget, gfx::AcceleratedWidget> WindowMap; 356d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WindowMap child_to_parent_map_; 357d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 358d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(XExposeEventForwarder); 359d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}; 360d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 361d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)static base::LazyInstance<XExposeEventForwarder> g_xexpose_event_forwarder = 362d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LAZY_INSTANCE_INITIALIZER; 363d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 364d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Do not use this workaround when running in test harnesses that do not have 365d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// a message loop or do not have a TYPE_GPU message loop. 366d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool g_create_child_windows = false; 367d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif 368d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLSurfaceGLX::GLSurfaceGLX() {} 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLSurfaceGLX::InitializeOneOff() { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool initialized = false; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (initialized) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // http://crbug.com/245466 379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) setenv("force_s3tc_enable", "true", 1); 380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SGIVideoSyncProviderShim (if instantiated) will issue X commands on 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it's own thread. 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XInitThreads(); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(TOOLKIT_GTK) 386d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Be sure to use the X display handle and not the GTK display handle if this 387d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // is the GPU process. 388d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) g_create_child_windows = 389d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::MessageLoop::current() && 390d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::MessageLoop::current()->type() == base::MessageLoop::TYPE_GPU; 391d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 392d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (g_create_child_windows) 393d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) g_display = base::MessagePumpX11::GetDefaultXDisplay(); 394d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) else 395d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) g_display = base::MessagePumpForUI::GetDefaultXDisplay(); 396d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#else 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_display = base::MessagePumpForUI::GetDefaultXDisplay(); 398d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif 399d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!g_display) { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "XOpenDisplay failed."; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int major, minor; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!glXQueryVersion(g_display, &major, &minor)) { 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "glxQueryVersion failed"; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (major == 1 && minor < 3) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "GLX 1.3 or later is required."; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_glx_extensions = glXQueryExtensionsString(g_display, 0); 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_glx_context_create = 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HasGLXExtension("GLX_ARB_create_context"); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_glx_create_context_robustness_supported = 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HasGLXExtension("GLX_ARB_create_context_robustness"); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_glx_texture_from_pixmap_supported = 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HasGLXExtension("GLX_EXT_texture_from_pixmap"); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_glx_oml_sync_control_supported = 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HasGLXExtension("GLX_OML_sync_control"); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_glx_get_msc_rate_oml_supported = g_glx_oml_sync_control_supported; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_glx_sgi_video_sync_supported = 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HasGLXExtension("GLX_SGI_video_sync"); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!g_glx_get_msc_rate_oml_supported && g_glx_sgi_video_sync_supported) 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SGIVideoSyncProviderThreadShim::display_ = XOpenDisplay(NULL); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialized = true; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* GLSurfaceGLX::GetGLXExtensions() { 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_glx_extensions; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLSurfaceGLX::HasGLXExtension(const char* name) { 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ExtensionsContain(GetGLXExtensions(), name); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GLSurfaceGLX::IsCreateContextSupported() { 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return g_glx_context_create; 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLSurfaceGLX::IsCreateContextRobustnessSupported() { 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_glx_create_context_robustness_supported; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLSurfaceGLX::IsTextureFromPixmapSupported() { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_glx_texture_from_pixmap_supported; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLSurfaceGLX::IsOMLSyncControlSupported() { 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_glx_oml_sync_control_supported; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* GLSurfaceGLX::GetDisplay() { 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_display; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLSurfaceGLX::~GLSurfaceGLX() {} 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 472d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(TOOLKIT_GTK) 473d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool NativeViewGLSurfaceGLX::SetBackbufferAllocation(bool allocated) { 474d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) backbuffer_allocated_ = allocated; 475d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) AdjustBufferAllocation(); 476d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return true; 477d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 478d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 479d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void NativeViewGLSurfaceGLX::SetFrontbufferAllocation(bool allocated) { 480d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) frontbuffer_allocated_ = allocated; 481d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) AdjustBufferAllocation(); 482d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 483d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 484d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void NativeViewGLSurfaceGLX::AdjustBufferAllocation() { 485d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!g_create_child_windows) 486d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 487d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 488d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (frontbuffer_allocated_ || backbuffer_allocated_) 489d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) CreateChildWindow(); 490d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) else 491d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DestroyChildWindow(); 492d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 493d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 494d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void NativeViewGLSurfaceGLX::CreateChildWindow() { 495d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(g_create_child_windows); 496d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 497d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (child_window_) 498d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 499d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 500d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) XSetWindowAttributes set_window_attributes; 501d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) set_window_attributes.event_mask = ExposureMask; 502d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) child_window_ = XCreateWindow( 503d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) g_display, parent_window_, 0, 0, size_.width(), size_.height(), 0, 504d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) CopyFromParent, InputOutput, CopyFromParent, CWEventMask, 505d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &set_window_attributes); 506d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) g_xexpose_event_forwarder.Pointer()->AddParentChildPair( 507d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) parent_window_, child_window_); 508d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 509d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) XMapWindow(g_display, child_window_); 510d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) XFlush(g_display); 511d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 512d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 513d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void NativeViewGLSurfaceGLX::DestroyChildWindow() { 514d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!child_window_) 515d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 516d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 517d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) g_xexpose_event_forwarder.Pointer()->RemoveParentChildPair( 518d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) parent_window_, child_window_); 519d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) XDestroyWindow(g_display, child_window_); 520d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) XFlush(g_display); 521d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) child_window_ = 0; 522d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 523d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif 524d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window) 526d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : parent_window_(window), 527d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(TOOLKIT_GTK) 528d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) child_window_(0), 529d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) dummy_window_(0), 530d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) backbuffer_allocated_(true), 531d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) frontbuffer_allocated_(true), 532d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_(NULL) { 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 536d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)gfx::AcceleratedWidget NativeViewGLSurfaceGLX::GetDrawableHandle() const { 537d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(TOOLKIT_GTK) 538d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (g_create_child_windows) { 539d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (child_window_) 540d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return child_window_; 541d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return dummy_window_; 542d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 543d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif 544d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return parent_window_; 545d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 546d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeViewGLSurfaceGLX::Initialize() { 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XWindowAttributes attributes; 549d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!XGetWindowAttributes(g_display, parent_window_, &attributes)) { 550d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_ 551d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << "."; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_ = gfx::Size(attributes.width, attributes.height); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 556d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) gfx::AcceleratedWidget window_for_vsync = parent_window_; 557d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 558d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(TOOLKIT_GTK) 559d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (g_create_child_windows) { 560d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) dummy_window_ = XCreateWindow( 561d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) g_display, 562d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RootWindow(g_display, XScreenNumberOfScreen(attributes.screen)), 563d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 0, 0, 1, 1, 0, CopyFromParent, InputOutput, attributes.visual, 0, NULL); 564d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) window_for_vsync = dummy_window_; 565d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) CreateChildWindow(); 566d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 567d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif 568d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (g_glx_oml_sync_control_supported) 570d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) vsync_provider_.reset(new OMLSyncControlVSyncProvider(window_for_vsync)); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (g_glx_sgi_video_sync_supported) 572d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) vsync_provider_.reset(new SGIVideoSyncVSyncProvider(window_for_vsync)); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeViewGLSurfaceGLX::Destroy() { 578d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(TOOLKIT_GTK) 579d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DestroyChildWindow(); 580d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (dummy_window_) 581d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) XDestroyWindow(g_display, dummy_window_); 582d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) dummy_window_ = 0; 583d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeViewGLSurfaceGLX::Resize(const gfx::Size& size) { 587d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(TOOLKIT_GTK) 588d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (child_window_) { 589d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) XResizeWindow(g_display, child_window_, size.width(), size.height()); 590d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) XFlush(g_display); 591d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 592d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_ = size; 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeViewGLSurfaceGLX::IsOffscreen() { 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeViewGLSurfaceGLX::SwapBuffers() { 6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TRACE_EVENT2("gpu", "NativeViewGLSurfaceGLX:RealSwapBuffers", 6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "width", GetSize().width(), 6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "height", GetSize().height()); 6055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 606d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) glXSwapBuffers(g_display, GetDrawableHandle()); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size NativeViewGLSurfaceGLX::GetSize() { 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size_; 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* NativeViewGLSurfaceGLX::GetHandle() { 615d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return reinterpret_cast<void*>(GetDrawableHandle()); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 618effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool NativeViewGLSurfaceGLX::SupportsPostSubBuffer() { 619effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer; 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* NativeViewGLSurfaceGLX::GetConfig() { 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!config_) { 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This code path is expensive, but we only take it when 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // attempting to use GLX_ARB_create_context_robustness, in which 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // case we need a GLXFBConfig for the window in order to create a 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // context for it. 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kbr): this is not a reliable code path. On platforms which 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // support it, we should use glXChooseFBConfig in the browser 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // process to choose the FBConfig and from there the X Visual to 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // use when creating the window in the first place. Then we can 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pass that FBConfig down rather than attempting to reconstitute 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it. 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XWindowAttributes attributes; 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!XGetWindowAttributes( 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_display, 639d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) parent_window_, 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &attributes)) { 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "XGetWindowAttributes failed for window " << 642d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) parent_window_ << "."; 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int visual_id = XVisualIDFromVisual(attributes.visual); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_elements = 0; 649a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<GLXFBConfig, ScopedPtrXFree> configs( 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glXGetFBConfigs(g_display, 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DefaultScreen(g_display), 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &num_elements)); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!configs.get()) { 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "glXGetFBConfigs failed."; 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!num_elements) { 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "glXGetFBConfigs returned 0 elements."; 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool found = false; 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_elements; ++i) { 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int value; 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (glXGetFBConfigAttrib( 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_display, configs.get()[i], GLX_VISUAL_ID, &value)) { 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "glXGetFBConfigAttrib failed."; 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value == visual_id) { 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found = true; 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found) { 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_ = configs.get()[i]; 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return config_; 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeViewGLSurfaceGLX::PostSubBuffer( 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x, int y, int width, int height) { 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer); 686d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) glXCopySubBufferMESA(g_display, GetDrawableHandle(), x, y, width, height); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)VSyncProvider* NativeViewGLSurfaceGLX::GetVSyncProvider() { 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return vsync_provider_.get(); 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX() 695d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : parent_window_(0), 696d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(TOOLKIT_GTK) 697d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) child_window_(0), 698d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) dummy_window_(0), 699d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) backbuffer_allocated_(true), 700d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) frontbuffer_allocated_(true), 701d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_(NULL) { 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() { 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Destroy(); 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PbufferGLSurfaceGLX::PbufferGLSurfaceGLX(const gfx::Size& size) 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : size_(size), 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_(NULL), 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pbuffer_(0) { 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PbufferGLSurfaceGLX::Initialize() { 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!pbuffer_); 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int config_attributes[] = { 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_BUFFER_SIZE, 32, 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_ALPHA_SIZE, 8, 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_BLUE_SIZE, 8, 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_GREEN_SIZE, 8, 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_RED_SIZE, 8, 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_RENDER_TYPE, GLX_RGBA_BIT, 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_DOUBLEBUFFER, False, 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_elements = 0; 731a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<GLXFBConfig, ScopedPtrXFree> configs( 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glXChooseFBConfig(g_display, 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DefaultScreen(g_display), 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_attributes, 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &num_elements)); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!configs.get()) { 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "glXChooseFBConfig failed."; 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!num_elements) { 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "glXChooseFBConfig returned 0 elements."; 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_ = configs.get()[0]; 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int pbuffer_attributes[] = { 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_PBUFFER_WIDTH, size_.width(), 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_PBUFFER_HEIGHT, size_.height(), 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pbuffer_ = glXCreatePbuffer(g_display, 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<GLXFBConfig>(config_), 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pbuffer_attributes); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pbuffer_) { 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Destroy(); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "glXCreatePbuffer failed."; 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PbufferGLSurfaceGLX::Destroy() { 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pbuffer_) { 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glXDestroyPbuffer(g_display, pbuffer_); 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pbuffer_ = 0; 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_ = NULL; 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PbufferGLSurfaceGLX::IsOffscreen() { 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PbufferGLSurfaceGLX::SwapBuffers() { 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Attempted to call SwapBuffers on a pbuffer."; 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size PbufferGLSurfaceGLX::GetSize() { 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size_; 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* PbufferGLSurfaceGLX::GetHandle() { 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<void*>(pbuffer_); 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* PbufferGLSurfaceGLX::GetConfig() { 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return config_; 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() { 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Destroy(); 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gfx 799