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)#include "ui/gl/gl_surface_egl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <android/native_window_jni.h>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/command_line.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/debug/trace_event.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h"
17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/gfx/geometry/rect.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/egl_util.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_context.h"
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/gl/gl_implementation.h"
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/gl/gl_surface_stub.h"
227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ui/gl/gl_switches.h"
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/gl/scoped_make_current.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/gl/sync_control_vsync_provider.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_X11)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <X11/Xlib.h>
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined (USE_OZONE)
336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "ui/ozone/public/surface_factory_ozone.h"
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if !defined(EGL_FIXED_SIZE_ANGLE)
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define EGL_FIXED_SIZE_ANGLE 0x3201
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_WIN)
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// From ANGLE's egl/eglext.h.
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if !defined(EGL_PLATFORM_ANGLE_ANGLE)
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define EGL_PLATFORM_ANGLE_ANGLE 0x3201
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if !defined(EGL_PLATFORM_ANGLE_TYPE_ANGLE)
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3202
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if !defined(EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE)
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE 0x3206
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif  // defined(OS_WIN)
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ui::GetLastEGLErrorString;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EGLConfig g_config;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EGLDisplay g_display;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EGLNativeDisplayType g_native_display;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* g_egl_extensions = NULL;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_egl_create_context_robustness_supported = false;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool g_egl_sync_control_supported = false;
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool g_egl_window_fixed_size_supported = false;
670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)bool g_egl_surfaceless_context_supported = false;
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class EGLSyncControlVSyncProvider
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public gfx::SyncControlVSyncProvider {
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit EGLSyncControlVSyncProvider(EGLSurface surface)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : SyncControlVSyncProvider(),
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        surface_(surface) {
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~EGLSyncControlVSyncProvider() { }
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool GetSyncValues(int64* system_time,
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             int64* media_stream_counter,
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             int64* swap_buffer_counter) OVERRIDE {
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint64 u_system_time, u_media_stream_counter, u_swap_buffer_counter;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool result = eglGetSyncValuesCHROMIUM(
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        g_display, surface_, &u_system_time,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &u_media_stream_counter, &u_swap_buffer_counter) == EGL_TRUE;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (result) {
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *system_time = static_cast<int64>(u_system_time);
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *media_stream_counter = static_cast<int64>(u_media_stream_counter);
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *swap_buffer_counter = static_cast<int64>(u_swap_buffer_counter);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return result;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool GetMscRate(int32* numerator, int32* denominator) OVERRIDE {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EGLSurface surface_;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(EGLSyncControlVSyncProvider);
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)GLSurfaceEGL::GLSurfaceEGL() {}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLSurfaceEGL::InitializeOneOff() {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool initialized = false;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (initialized)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  g_native_display = GetPlatformDefaultEGLNativeDisplay();
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_WIN)
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  g_display = GetPlatformDisplay(g_native_display);
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#else
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_display = eglGetDisplay(g_native_display);
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!g_display) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "eglGetDisplay failed with error " << GetLastEGLErrorString();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!eglInitialize(g_display, NULL, NULL)) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Choose an EGL configuration.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // On X this is only used for PBuffer surfaces.
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  static const EGLint kConfigAttribs[] = {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EGL_BUFFER_SIZE, 32,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EGL_ALPHA_SIZE, 8,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EGL_BLUE_SIZE, 8,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EGL_GREEN_SIZE, 8,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EGL_RED_SIZE, 8,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EGL_NONE
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(USE_OZONE)
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const EGLint* config_attribs =
1476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      ui::SurfaceFactoryOzone::GetInstance()->GetEGLSurfaceProperties(
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          kConfigAttribs);
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#else
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const EGLint* config_attribs = kConfigAttribs;
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EGLint num_configs;
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!eglChooseConfig(g_display,
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       config_attribs,
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       NULL,
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       0,
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       &num_configs)) {
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LOG(ERROR) << "eglChooseConfig failed with error "
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)               << GetLastEGLErrorString();
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (num_configs == 0) {
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LOG(ERROR) << "No suitable EGL configs found.";
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!eglChooseConfig(g_display,
1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       config_attribs,
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       &g_config,
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       1,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       &num_configs)) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "eglChooseConfig failed with error "
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << GetLastEGLErrorString();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_egl_extensions = eglQueryString(g_display, EGL_EXTENSIONS);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_egl_create_context_robustness_supported =
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HasEGLExtension("EGL_EXT_create_context_robustness");
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  g_egl_sync_control_supported =
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HasEGLExtension("EGL_CHROMIUM_sync_control");
184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  g_egl_window_fixed_size_supported =
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      HasEGLExtension("EGL_ANGLE_window_fixed_size");
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // TODO(oetuaho@nvidia.com): Surfaceless is disabled on Android as a temporary
188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // workaround, since code written for Android WebView takes different paths
189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // based on whether GL surface objects have underlying EGL surface handles,
190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // conflicting with the use of surfaceless. See https://crbug.com/382349
191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_ANDROID)
192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(!g_egl_surfaceless_context_supported);
193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#else
1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Check if SurfacelessEGL is supported.
1950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  g_egl_surfaceless_context_supported =
1960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      HasEGLExtension("EGL_KHR_surfaceless_context");
1970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (g_egl_surfaceless_context_supported) {
1980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // EGL_KHR_surfaceless_context is supported but ensure
1990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // GL_OES_surfaceless_context is also supported. We need a current context
2000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // to query for supported GL extensions.
2010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    scoped_refptr<GLSurface> surface = new SurfacelessEGL(Size(1, 1));
2020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    scoped_refptr<GLContext> context = GLContext::CreateGLContext(
2030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      NULL, surface.get(), PreferIntegratedGpu);
2040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (!context->MakeCurrent(surface.get()))
2050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      g_egl_surfaceless_context_supported = false;
2060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // Ensure context supports GL_OES_surfaceless_context.
2080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (g_egl_surfaceless_context_supported) {
2090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      g_egl_surfaceless_context_supported = context->HasExtension(
2100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          "GL_OES_surfaceless_context");
2110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      context->ReleaseCurrent(surface.get());
2120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
2130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif
2150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initialized = true;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EGLDisplay GLSurfaceEGL::GetDisplay() {
2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return g_display;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EGLDisplay GLSurfaceEGL::GetHardwareDisplay() {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_display;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EGLNativeDisplayType GLSurfaceEGL::GetNativeDisplay() {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_native_display;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* GLSurfaceEGL::GetEGLExtensions() {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_egl_extensions;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLSurfaceEGL::HasEGLExtension(const char* name) {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ExtensionsContain(GetEGLExtensions(), name);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLSurfaceEGL::IsCreateContextRobustnessSupported() {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_egl_create_context_robustness_supported;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool GLSurfaceEGL::IsEGLSurfacelessContextSupported() {
246effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return g_egl_surfaceless_context_supported;
247effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
248effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLSurfaceEGL::~GLSurfaceEGL() {}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_WIN)
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic const EGLint kDisplayAttribsWarp[] {
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EGL_PLATFORM_ANGLE_TYPE_ANGLE,
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE,
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EGL_NONE
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEGLDisplay GLSurfaceEGL::GetPlatformDisplay(
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EGLNativeDisplayType native_display) {
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseWarp)) {
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Check for availability of WARP via ANGLE extension.
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool supports_warp = false;
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* no_display_extensions = eglQueryString(EGL_NO_DISPLAY,
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        EGL_EXTENSIONS);
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // If EGL_EXT_client_extensions not supported this call to eglQueryString
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // will return NULL.
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (no_display_extensions)
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      supports_warp =
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          ExtensionsContain(no_display_extensions, "ANGLE_platform_angle") &&
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          ExtensionsContain(no_display_extensions, "ANGLE_platform_angle_d3d");
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!supports_warp)
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return NULL;
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, native_display,
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        kDisplayAttribsWarp);
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return eglGetDisplay(native_display);
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
284effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochNativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : window_(window),
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      surface_(NULL),
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      supports_post_sub_buffer_(false),
288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      config_(NULL),
289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      size_(1, 1) {
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID)
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (window)
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ANativeWindow_acquire(window);
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
294c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
295c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if defined(OS_WIN)
296c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  RECT windowRect;
297c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (GetClientRect(window_, &windowRect))
298c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    size_ = gfx::Rect(windowRect).size();
299c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeViewGLSurfaceEGL::Initialize() {
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return Initialize(scoped_ptr<VSyncProvider>());
30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool NativeViewGLSurfaceEGL::Initialize(
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<VSyncProvider> sync_provider) {
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!surface_);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetDisplay()) {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Trying to create surface with invalid display.";
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::vector<EGLint> egl_window_attributes;
316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (g_egl_window_fixed_size_supported) {
318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    egl_window_attributes.push_back(EGL_FIXED_SIZE_ANGLE);
319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    egl_window_attributes.push_back(EGL_TRUE);
320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    egl_window_attributes.push_back(EGL_WIDTH);
321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    egl_window_attributes.push_back(size_.width());
322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    egl_window_attributes.push_back(EGL_HEIGHT);
323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    egl_window_attributes.push_back(size_.height());
324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (gfx::g_driver_egl.ext.b_EGL_NV_post_sub_buffer) {
327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    egl_window_attributes.push_back(EGL_POST_SUB_BUFFER_SUPPORTED_NV);
328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    egl_window_attributes.push_back(EGL_TRUE);
329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  egl_window_attributes.push_back(EGL_NONE);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a surface for the native window.
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  surface_ = eglCreateWindowSurface(
334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GetDisplay(), GetConfig(), window_, &egl_window_attributes[0]);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!surface_) {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "eglCreateWindowSurface failed with error "
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << GetLastEGLErrorString();
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Destroy();
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EGLint surfaceVal;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EGLBoolean retVal = eglQuerySurface(GetDisplay(),
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      surface_,
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      EGL_POST_SUB_BUFFER_SUPPORTED_NV,
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      &surfaceVal);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  supports_post_sub_buffer_ = (surfaceVal && retVal) == EGL_TRUE;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (sync_provider)
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    vsync_provider_.reset(sync_provider.release());
35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  else if (g_egl_sync_control_supported)
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vsync_provider_.reset(new EGLSyncControlVSyncProvider(surface_));
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeViewGLSurfaceEGL::Destroy() {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (surface_) {
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!eglDestroySurface(GetDisplay(), surface_)) {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "eglDestroySurface failed with error "
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << GetLastEGLErrorString();
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    surface_ = NULL;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EGLConfig NativeViewGLSurfaceEGL::GetConfig() {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(USE_X11)
3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return g_config;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!config_) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get a config compatible with the window
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(window_);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XWindowAttributes win_attribs;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!XGetWindowAttributes(GetNativeDisplay(), window_, &win_attribs)) {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Try matching the window depth with an alpha channel,
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // because we're worried the destination alpha width could
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // constrain blending precision.
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kBufferSizeOffset = 1;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kAlphaSizeOffset = 3;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EGLint config_attribs[] = {
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EGL_BUFFER_SIZE, ~0,
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EGL_ALPHA_SIZE, 8,
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EGL_BLUE_SIZE, 8,
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EGL_GREEN_SIZE, 8,
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EGL_RED_SIZE, 8,
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EGL_NONE
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    config_attribs[kBufferSizeOffset] = win_attribs.depth;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EGLint num_configs;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!eglChooseConfig(g_display,
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         config_attribs,
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         &config_,
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         1,
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         &num_configs)) {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "eglChooseConfig failed with error "
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << GetLastEGLErrorString();
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (num_configs) {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EGLint config_depth;
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!eglGetConfigAttrib(g_display,
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              config_,
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              EGL_BUFFER_SIZE,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              &config_depth)) {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LOG(ERROR) << "eglGetConfigAttrib failed with error "
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   << GetLastEGLErrorString();
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return NULL;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (config_depth == win_attribs.depth) {
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return config_;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Try without an alpha channel.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    config_attribs[kAlphaSizeOffset] = 0;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!eglChooseConfig(g_display,
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         config_attribs,
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         &config_,
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         1,
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         &num_configs)) {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "eglChooseConfig failed with error "
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << GetLastEGLErrorString();
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (num_configs == 0) {
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "No suitable EGL configs found.";
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return config_;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeViewGLSurfaceEGL::IsOffscreen() {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeViewGLSurfaceEGL::SwapBuffers() {
4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TRACE_EVENT2("gpu", "NativeViewGLSurfaceEGL:RealSwapBuffers",
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "width", GetSize().width(),
4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "height", GetSize().height());
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!eglSwapBuffers(GetDisplay(), surface_)) {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "eglSwapBuffers failed with error "
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             << GetLastEGLErrorString();
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size NativeViewGLSurfaceEGL::GetSize() {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EGLint width;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EGLint height;
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!eglQuerySurface(GetDisplay(), surface_, EGL_WIDTH, &width) ||
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !eglQuerySurface(GetDisplay(), surface_, EGL_HEIGHT, &height)) {
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "eglQuerySurface failed with error "
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << GetLastEGLErrorString();
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return gfx::Size();
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size(width, height);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeViewGLSurfaceEGL::Resize(const gfx::Size& size) {
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size == GetSize())
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  size_ = size;
480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLContext* current_context = GLContext::GetCurrent();
483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool was_current =
484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      current_context && current_context->IsCurrent(this);
485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (was_current) {
486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    scoped_make_current.reset(
487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new ui::ScopedMakeCurrent(current_context, this));
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_context->ReleaseCurrent(this);
489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Destroy();
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!Initialize()) {
494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    LOG(ERROR) << "Failed to resize window.";
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool NativeViewGLSurfaceEGL::Recreate() {
502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Destroy();
503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!Initialize()) {
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    LOG(ERROR) << "Failed to create surface.";
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EGLSurface NativeViewGLSurfaceEGL::GetHandle() {
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return surface_;
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
514effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool NativeViewGLSurfaceEGL::SupportsPostSubBuffer() {
515effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return supports_post_sub_buffer_;
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeViewGLSurfaceEGL::PostSubBuffer(
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int x, int y, int width, int height) {
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(supports_post_sub_buffer_);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!eglPostSubBufferNV(GetDisplay(), surface_, x, y, width, height)) {
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "eglPostSubBufferNV failed with error "
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             << GetLastEGLErrorString();
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)VSyncProvider* NativeViewGLSurfaceEGL::GetVSyncProvider() {
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return vsync_provider_.get();
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeViewGLSurfaceEGL::~NativeViewGLSurfaceEGL() {
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Destroy();
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID)
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (window_)
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ANativeWindow_release(window_);
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)PbufferGLSurfaceEGL::PbufferGLSurfaceEGL(const gfx::Size& size)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : size_(size),
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      surface_(NULL) {
544cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Some implementations of Pbuffer do not support having a 0 size. For such
545cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // cases use a (1, 1) surface.
546cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (size_.GetArea() == 0)
547cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    size_.SetSize(1, 1);
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PbufferGLSurfaceEGL::Initialize() {
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EGLSurface old_surface = surface_;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EGLDisplay display = GetDisplay();
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!display) {
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Trying to create surface with invalid display.";
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Allocate the new pbuffer surface before freeing the old one to ensure
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // they have different addresses. If they have the same address then a
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // future call to MakeCurrent might early out because it appears the current
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // context and surface have not changed.
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EGLint pbuffer_attribs[] = {
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EGL_WIDTH, size_.width(),
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EGL_HEIGHT, size_.height(),
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EGL_NONE
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EGLSurface new_surface = eglCreatePbufferSurface(display,
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                   GetConfig(),
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                   pbuffer_attribs);
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!new_surface) {
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "eglCreatePbufferSurface failed with error "
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << GetLastEGLErrorString();
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (old_surface)
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    eglDestroySurface(display, old_surface);
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface_ = new_surface;
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PbufferGLSurfaceEGL::Destroy() {
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (surface_) {
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!eglDestroySurface(GetDisplay(), surface_)) {
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "eglDestroySurface failed with error "
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << GetLastEGLErrorString();
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    surface_ = NULL;
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EGLConfig PbufferGLSurfaceEGL::GetConfig() {
5967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return g_config;
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PbufferGLSurfaceEGL::IsOffscreen() {
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PbufferGLSurfaceEGL::SwapBuffers() {
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED() << "Attempted to call SwapBuffers on a PbufferGLSurfaceEGL.";
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size PbufferGLSurfaceEGL::GetSize() {
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return size_;
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PbufferGLSurfaceEGL::Resize(const gfx::Size& size) {
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size == size_)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLContext* current_context = GLContext::GetCurrent();
618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool was_current =
619868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      current_context && current_context->IsCurrent(this);
620868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (was_current) {
621868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    scoped_make_current.reset(
622868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new ui::ScopedMakeCurrent(current_context, this));
623868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_ = size;
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!Initialize()) {
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to resize pbuffer.";
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EGLSurface PbufferGLSurfaceEGL::GetHandle() {
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return surface_;
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* PbufferGLSurfaceEGL::GetShareHandle() {
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!gfx::g_driver_egl.ext.b_EGL_ANGLE_query_surface_pointer)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!gfx::g_driver_egl.ext.b_EGL_ANGLE_surface_d3d_texture_2d_share_handle)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* handle;
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!eglQuerySurfacePointerANGLE(g_display,
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   GetHandle(),
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   &handle)) {
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handle;
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PbufferGLSurfaceEGL::~PbufferGLSurfaceEGL() {
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Destroy();
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)SurfacelessEGL::SurfacelessEGL(const gfx::Size& size)
6670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    : size_(size) {
6680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
6690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
6700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)bool SurfacelessEGL::Initialize() {
6710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  return true;
6720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
6730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
6740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void SurfacelessEGL::Destroy() {
6750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
6760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
6770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)EGLConfig SurfacelessEGL::GetConfig() {
6780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  return g_config;
6790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
6800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
6810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)bool SurfacelessEGL::IsOffscreen() {
6820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  return true;
6830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
6840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
6850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)bool SurfacelessEGL::SwapBuffers() {
6860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  LOG(ERROR) << "Attempted to call SwapBuffers with SurfacelessEGL.";
6870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  return false;
6880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
6890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
6900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)gfx::Size SurfacelessEGL::GetSize() {
6910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  return size_;
6920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
6930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
6940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)bool SurfacelessEGL::Resize(const gfx::Size& size) {
6950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  size_ = size;
6960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  return true;
6970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
6980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
6990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)EGLSurface SurfacelessEGL::GetHandle() {
7000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  return EGL_NO_SURFACE;
7010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
7020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
7030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void* SurfacelessEGL::GetShareHandle() {
7040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  return NULL;
7050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
7060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
7070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)SurfacelessEGL::~SurfacelessEGL() {
7080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
7090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gfx
711