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" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/single_thread_task_runner.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/cancellation_flag.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/thread_task_runner_handle.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/non_thread_safe.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/events/platform/platform_event_source.h" 26a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/gfx/x/x11_connection.h" 2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/gfx/x/x11_types.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_bindings.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_implementation.h" 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/gl/sync_control_vsync_provider.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// scoped_ptr functor for XFree(). Use as follows: 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// scoped_ptr<XVisualInfo, ScopedPtrXFree> foo(...); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// where "XVisualInfo" is any X type that is freed with XFree. 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)struct ScopedPtrXFree { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void operator()(void* x) const { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::XFree(x); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)Display* g_display = NULL; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* g_glx_extensions = NULL; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool g_glx_context_create = false; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_glx_create_context_robustness_supported = false; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_glx_texture_from_pixmap_supported = false; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_glx_oml_sync_control_supported = false; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Track support of glXGetMscRateOML separately from GLX_OML_sync_control as a 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// whole since on some platforms (e.g. crosbug.com/34585), glXGetMscRateOML 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// always fails even though GLX_OML_sync_control is reported as being supported. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_glx_get_msc_rate_oml_supported = false; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_glx_sgi_video_sync_supported = false; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic const base::TimeDelta kGetVSyncParametersMinPeriod = 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_LINUX) 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // See crbug.com/373489 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // On Linux, querying the vsync parameters might burn CPU for up to an 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // entire vsync, so we only query periodically to reduce CPU usage. 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 5 seconds is chosen somewhat abitrarily as a balance between: 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // a) Drift in the phase of our signal. 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // b) Potential janks from periodically pegging the CPU. 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeDelta::FromSeconds(5); 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#else 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeDelta::FromSeconds(0); 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OMLSyncControlVSyncProvider 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public gfx::SyncControlVSyncProvider { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit OMLSyncControlVSyncProvider(gfx::AcceleratedWidget window) 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : SyncControlVSyncProvider(), 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window_(window) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~OMLSyncControlVSyncProvider() { } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool GetSyncValues(int64* system_time, 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64* media_stream_counter, 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64* swap_buffer_counter) OVERRIDE { 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return glXGetSyncValuesOML(g_display, window_, system_time, 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) media_stream_counter, swap_buffer_counter); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool GetMscRate(int32* numerator, int32* denominator) OVERRIDE { 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!g_glx_get_msc_rate_oml_supported) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!glXGetMscRateOML(g_display, window_, numerator, denominator)) { 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Once glXGetMscRateOML has been found to fail, don't try again, 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // since each failing call may spew an error message. 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_glx_get_msc_rate_oml_supported = false; 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XID window_; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(OMLSyncControlVSyncProvider); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SGIVideoSyncThread 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public base::Thread, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public base::NonThreadSafe, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public base::RefCounted<SGIVideoSyncThread> { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static scoped_refptr<SGIVideoSyncThread> Create() { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!g_video_sync_thread) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_video_sync_thread = new SGIVideoSyncThread(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_video_sync_thread->Start(); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_video_sync_thread; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCounted<SGIVideoSyncThread>; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SGIVideoSyncThread() : base::Thread("SGI_video_sync") { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~SGIVideoSyncThread() { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_video_sync_thread = NULL; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static SGIVideoSyncThread* g_video_sync_thread; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncThread); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class SGIVideoSyncProviderThreadShim { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit SGIVideoSyncProviderThreadShim(XID window) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : window_(window), 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_(NULL), 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci task_runner_(base::ThreadTaskRunnerHandle::Get()), 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cancel_vsync_flag_(), 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vsync_lock_() { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This ensures that creation of |window_| has occured when this shim 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is executing in the same process as the call to create |window_|. 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) XSync(g_display, False); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual ~SGIVideoSyncProviderThreadShim() { 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (context_) { 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) glXDestroyContext(display_, context_); 15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) context_ = NULL; 15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::CancellationFlag* cancel_vsync_flag() { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &cancel_vsync_flag_; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Lock* vsync_lock() { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &vsync_lock_; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Initialize() { 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(display_); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XWindowAttributes attributes; 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!XGetWindowAttributes(display_, window_, &attributes)) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "XGetWindowAttributes failed for window " << 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_ << "."; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XVisualInfo visual_info_template; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visual_info_template.visualid = XVisualIDFromVisual(attributes.visual); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int visual_info_count = 0; 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<XVisualInfo, ScopedPtrXFree> visual_info_list( 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) XGetVisualInfo(display_, VisualIDMask, 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &visual_info_template, &visual_info_count)); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(visual_info_list.get()); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (visual_info_count == 0) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "No visual info for visual ID."; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_ = glXCreateContext(display_, visual_info_list.get(), NULL, True); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(NULL != context_); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void GetVSyncParameters(const VSyncProvider::UpdateVSyncCallback& callback) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks now; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't allow |window_| destruction while we're probing vsync. 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(vsync_lock_); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!context_ || cancel_vsync_flag_.IsSet()) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) glXMakeCurrent(display_, window_, context_); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int retrace_count = 0; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (glXWaitVideoSyncSGI(1, 0, &retrace_count) != 0) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_EVENT_INSTANT0("gpu", "vblank", TRACE_EVENT_SCOPE_THREAD); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) now = base::TimeTicks::HighResNow(); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) glXMakeCurrent(display_, 0, 0); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::TimeDelta kDefaultInterval = 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromSeconds(1) / 60; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci task_runner_->PostTask( 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(callback, now, kDefaultInterval)); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For initialization of display_ in GLSurface::InitializeOneOff before 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the sandbox goes up. 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class gfx::GLSurfaceGLX; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static Display* display_; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XID window_; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLXContext context_; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::CancellationFlag cancel_vsync_flag_; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Lock vsync_lock_; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncProviderThreadShim); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SGIVideoSyncVSyncProvider 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public gfx::VSyncProvider, 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public base::SupportsWeakPtr<SGIVideoSyncVSyncProvider> { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit SGIVideoSyncVSyncProvider(gfx::AcceleratedWidget window) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : vsync_thread_(SGIVideoSyncThread::Create()), 25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) shim_(new SGIVideoSyncProviderThreadShim(window)), 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cancel_vsync_flag_(shim_->cancel_vsync_flag()), 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vsync_lock_(shim_->vsync_lock()) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vsync_thread_->message_loop()->PostTask( 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&SGIVideoSyncProviderThreadShim::Initialize, 25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Unretained(shim_.get()))); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~SGIVideoSyncVSyncProvider() { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(*vsync_lock_); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cancel_vsync_flag_->Set(); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Hand-off |shim_| to be deleted on the |vsync_thread_|. 26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) vsync_thread_->message_loop()->DeleteSoon( 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) shim_.release()); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void GetVSyncParameters( 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const VSyncProvider::UpdateVSyncCallback& callback) OVERRIDE { 2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (kGetVSyncParametersMinPeriod > base::TimeDelta()) { 2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeTicks now = base::TimeTicks::Now(); 2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeDelta delta = now - last_get_vsync_parameters_time_; 2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (delta < kGetVSyncParametersMinPeriod) 2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci last_get_vsync_parameters_time_ = now; 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only one outstanding request per surface. 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pending_callback_) { 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_callback_.reset( 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new VSyncProvider::UpdateVSyncCallback(callback)); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vsync_thread_->message_loop()->PostTask( 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&SGIVideoSyncProviderThreadShim::GetVSyncParameters, 28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Unretained(shim_.get()), 28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind( 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &SGIVideoSyncVSyncProvider::PendingCallbackRunner, 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AsWeakPtr()))); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PendingCallbackRunner(const base::TimeTicks timebase, 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta interval) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pending_callback_); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_callback_->Run(timebase, interval); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_callback_.reset(); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SGIVideoSyncThread> vsync_thread_; 30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Thread shim through which the sync provider is accessed on |vsync_thread_|. 30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<SGIVideoSyncProviderThreadShim> shim_; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<VSyncProvider::UpdateVSyncCallback> pending_callback_; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Raw pointers to sync primitives owned by the shim_. 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These will only be referenced before we post a task to destroy 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the shim_, so they are safe to access. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::CancellationFlag* cancel_vsync_flag_; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Lock* vsync_lock_; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeTicks last_get_vsync_parameters_time_; 3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncVSyncProvider); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SGIVideoSyncThread* SGIVideoSyncThread::g_video_sync_thread = NULL; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In order to take advantage of GLX_SGI_video_sync, we need a display 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for use on a separate thread. We must allocate this before the sandbox 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// goes up (rather than on-demand when we start the thread). 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Display* SGIVideoSyncProviderThreadShim::display_ = NULL; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLSurfaceGLX::GLSurfaceGLX() {} 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLSurfaceGLX::InitializeOneOff() { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool initialized = false; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (initialized) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // http://crbug.com/245466 338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) setenv("force_s3tc_enable", "true", 1); 339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SGIVideoSyncProviderShim (if instantiated) will issue X commands on 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it's own thread. 342a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::InitializeThreadedX11(); 343a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch g_display = gfx::GetXDisplay(); 344d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!g_display) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "XOpenDisplay failed."; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int major, minor; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!glXQueryVersion(g_display, &major, &minor)) { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "glxQueryVersion failed"; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (major == 1 && minor < 3) { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "GLX 1.3 or later is required."; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_glx_extensions = glXQueryExtensionsString(g_display, 0); 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_glx_context_create = 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HasGLXExtension("GLX_ARB_create_context"); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_glx_create_context_robustness_supported = 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HasGLXExtension("GLX_ARB_create_context_robustness"); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_glx_texture_from_pixmap_supported = 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HasGLXExtension("GLX_EXT_texture_from_pixmap"); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_glx_oml_sync_control_supported = 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HasGLXExtension("GLX_OML_sync_control"); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_glx_get_msc_rate_oml_supported = g_glx_oml_sync_control_supported; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_glx_sgi_video_sync_supported = 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HasGLXExtension("GLX_SGI_video_sync"); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!g_glx_get_msc_rate_oml_supported && g_glx_sgi_video_sync_supported) 375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SGIVideoSyncProviderThreadShim::display_ = gfx::OpenNewXDisplay(); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialized = true; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* GLSurfaceGLX::GetGLXExtensions() { 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_glx_extensions; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLSurfaceGLX::HasGLXExtension(const char* name) { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ExtensionsContain(GetGLXExtensions(), name); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GLSurfaceGLX::IsCreateContextSupported() { 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return g_glx_context_create; 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLSurfaceGLX::IsCreateContextRobustnessSupported() { 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_glx_create_context_robustness_supported; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLSurfaceGLX::IsTextureFromPixmapSupported() { 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_glx_texture_from_pixmap_supported; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLSurfaceGLX::IsOMLSyncControlSupported() { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_glx_oml_sync_control_supported; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* GLSurfaceGLX::GetDisplay() { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_display; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLSurfaceGLX::~GLSurfaceGLX() {} 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window) 418d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : parent_window_(window), 419cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) window_(0), 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_(NULL) { 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 423d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)gfx::AcceleratedWidget NativeViewGLSurfaceGLX::GetDrawableHandle() const { 424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return window_; 425d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 426d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeViewGLSurfaceGLX::Initialize() { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XWindowAttributes attributes; 429d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!XGetWindowAttributes(g_display, parent_window_, &attributes)) { 430d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_ 431d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << "."; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_ = gfx::Size(attributes.width, attributes.height); 435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Create a child window, with a CopyFromParent visual (to avoid inducing 436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // extra blits in the driver), that we can resize exactly in Resize(), 437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // correctly ordered with GL, so that we don't have invalid transient states. 438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // See https://crbug.com/326995. 439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) window_ = XCreateWindow(g_display, 440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) parent_window_, 441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 0, 442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 0, 443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_.width(), 444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_.height(), 445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 0, 446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CopyFromParent, 447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) InputOutput, 448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CopyFromParent, 449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 0, 450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NULL); 451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) XMapWindow(g_display, window_); 452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::PlatformEventSource* event_source = 454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::PlatformEventSource::GetInstance(); 455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Can be NULL in tests, when we don't care about Exposes. 456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (event_source) { 457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) XSelectInput(g_display, window_, ExposureMask); 458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); 459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) XFlush(g_display); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gfx::AcceleratedWidget window_for_vsync = window_; 463d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (g_glx_oml_sync_control_supported) 465d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) vsync_provider_.reset(new OMLSyncControlVSyncProvider(window_for_vsync)); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (g_glx_sgi_video_sync_supported) 467d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) vsync_provider_.reset(new SGIVideoSyncVSyncProvider(window_for_vsync)); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeViewGLSurfaceGLX::Destroy() { 473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (window_) { 474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::PlatformEventSource* event_source = 475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::PlatformEventSource::GetInstance(); 476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (event_source) 477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) event_source->RemovePlatformEventDispatcher(this); 478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) XDestroyWindow(g_display, window_); 479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) XFlush(g_display); 480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool NativeViewGLSurfaceGLX::CanDispatchEvent(const ui::PlatformEvent& event) { 484cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return event->type == Expose && event->xexpose.window == window_; 485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)uint32_t NativeViewGLSurfaceGLX::DispatchEvent(const ui::PlatformEvent& event) { 488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) XEvent forwarded_event = *event; 489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) forwarded_event.xexpose.window = parent_window_; 490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) XSendEvent(g_display, parent_window_, False, ExposureMask, 491cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &forwarded_event); 492cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) XFlush(g_display); 493cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ui::POST_DISPATCH_STOP_PROPAGATION; 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeViewGLSurfaceGLX::Resize(const gfx::Size& size) { 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_ = size; 498cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) glXWaitGL(); 499cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) XResizeWindow(g_display, window_, size.width(), size.height()); 500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) glXWaitX(); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeViewGLSurfaceGLX::IsOffscreen() { 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeViewGLSurfaceGLX::SwapBuffers() { 5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TRACE_EVENT2("gpu", "NativeViewGLSurfaceGLX:RealSwapBuffers", 5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "width", GetSize().width(), 5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "height", GetSize().height()); 5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 513d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) glXSwapBuffers(g_display, GetDrawableHandle()); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size NativeViewGLSurfaceGLX::GetSize() { 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size_; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* NativeViewGLSurfaceGLX::GetHandle() { 522d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return reinterpret_cast<void*>(GetDrawableHandle()); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool NativeViewGLSurfaceGLX::SupportsPostSubBuffer() { 526effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* NativeViewGLSurfaceGLX::GetConfig() { 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!config_) { 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This code path is expensive, but we only take it when 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // attempting to use GLX_ARB_create_context_robustness, in which 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // case we need a GLXFBConfig for the window in order to create a 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // context for it. 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kbr): this is not a reliable code path. On platforms which 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // support it, we should use glXChooseFBConfig in the browser 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // process to choose the FBConfig and from there the X Visual to 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // use when creating the window in the first place. Then we can 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pass that FBConfig down rather than attempting to reconstitute 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it. 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XWindowAttributes attributes; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!XGetWindowAttributes( 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_display, 546cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) window_, 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &attributes)) { 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "XGetWindowAttributes failed for window " << 549cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) window_ << "."; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int visual_id = XVisualIDFromVisual(attributes.visual); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_elements = 0; 556a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<GLXFBConfig, ScopedPtrXFree> configs( 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glXGetFBConfigs(g_display, 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DefaultScreen(g_display), 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &num_elements)); 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!configs.get()) { 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "glXGetFBConfigs failed."; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!num_elements) { 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "glXGetFBConfigs returned 0 elements."; 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool found = false; 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_elements; ++i) { 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int value; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (glXGetFBConfigAttrib( 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_display, configs.get()[i], GLX_VISUAL_ID, &value)) { 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "glXGetFBConfigAttrib failed."; 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value == visual_id) { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found = true; 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found) { 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_ = configs.get()[i]; 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return config_; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeViewGLSurfaceGLX::PostSubBuffer( 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x, int y, int width, int height) { 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer); 593d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) glXCopySubBufferMESA(g_display, GetDrawableHandle(), x, y, width, height); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)VSyncProvider* NativeViewGLSurfaceGLX::GetVSyncProvider() { 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return vsync_provider_.get(); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() { 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Destroy(); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PbufferGLSurfaceGLX::PbufferGLSurfaceGLX(const gfx::Size& size) 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : size_(size), 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_(NULL), 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pbuffer_(0) { 609cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Some implementations of Pbuffer do not support having a 0 size. For such 610cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // cases use a (1, 1) surface. 611cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (size_.GetArea() == 0) 612cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_.SetSize(1, 1); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PbufferGLSurfaceGLX::Initialize() { 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!pbuffer_); 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int config_attributes[] = { 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_BUFFER_SIZE, 32, 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_ALPHA_SIZE, 8, 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_BLUE_SIZE, 8, 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_GREEN_SIZE, 8, 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_RED_SIZE, 8, 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_RENDER_TYPE, GLX_RGBA_BIT, 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_DOUBLEBUFFER, False, 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_elements = 0; 631a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<GLXFBConfig, ScopedPtrXFree> configs( 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glXChooseFBConfig(g_display, 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DefaultScreen(g_display), 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_attributes, 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &num_elements)); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!configs.get()) { 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "glXChooseFBConfig failed."; 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!num_elements) { 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "glXChooseFBConfig returned 0 elements."; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_ = configs.get()[0]; 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int pbuffer_attributes[] = { 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_PBUFFER_WIDTH, size_.width(), 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_PBUFFER_HEIGHT, size_.height(), 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pbuffer_ = glXCreatePbuffer(g_display, 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<GLXFBConfig>(config_), 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pbuffer_attributes); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pbuffer_) { 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Destroy(); 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "glXCreatePbuffer failed."; 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PbufferGLSurfaceGLX::Destroy() { 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pbuffer_) { 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glXDestroyPbuffer(g_display, pbuffer_); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pbuffer_ = 0; 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_ = NULL; 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PbufferGLSurfaceGLX::IsOffscreen() { 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PbufferGLSurfaceGLX::SwapBuffers() { 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Attempted to call SwapBuffers on a pbuffer."; 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size PbufferGLSurfaceGLX::GetSize() { 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size_; 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* PbufferGLSurfaceGLX::GetHandle() { 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<void*>(pbuffer_); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* PbufferGLSurfaceGLX::GetConfig() { 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return config_; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() { 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Destroy(); 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gfx 699