<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file implements the ViewGLContext and PbufferGLContext classes.

#include "app/gfx/gl/gl_context.h"

#include <GL/osmesa.h>

#include "app/gfx/gl/gl_bindings.h"
#include "app/gfx/gl/gl_context_egl.h"
#include "app/gfx/gl/gl_context_osmesa.h"
#include "app/gfx/gl/gl_context_stub.h"
#include "app/gfx/gl/gl_implementation.h"
#include "app/x11_util.h"
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/scoped_ptr.h"

namespace gfx {

typedef GLXContext GLContextHandle;
typedef GLXPbuffer PbufferHandle;

// This class is a wrapper around a GL context that renders directly to a
// window.
class ViewGLContext : public GLContext {
 public:
  explicit ViewGLContext(gfx::PluginWindowHandle window)
      : window_(window),
        context_(NULL) {
    DCHECK(window);
  }

  // Initializes the GL context.
  bool Initialize(bool multisampled);

  virtual void Destroy();
  virtual bool MakeCurrent();
  virtual bool IsCurrent();
  virtual bool IsOffscreen();
  virtual bool SwapBuffers();
  virtual gfx::Size GetSize();
  virtual void* GetHandle();

 private:
  gfx::PluginWindowHandle window_;
  GLContextHandle context_;

  DISALLOW_COPY_AND_ASSIGN(ViewGLContext);
};

// This class is a wrapper around a GL context that uses OSMesa to render
// to an offscreen buffer and then blits it to a window.
class OSMesaViewGLContext : public GLContext {
 public:
  explicit OSMesaViewGLContext(gfx::PluginWindowHandle window)
      : window_graphics_context_(0),
        window_(window),
        pixmap_graphics_context_(0),
        pixmap_(0) {
    DCHECK(window);
  }

  // Initializes the GL context.
  bool Initialize();

  virtual void Destroy();
  virtual bool MakeCurrent();
  virtual bool IsCurrent();
  virtual bool IsOffscreen();
  virtual bool SwapBuffers();
  virtual gfx::Size GetSize();
  virtual void* GetHandle();

 private:
  bool UpdateSize();

  GC window_graphics_context_;
  gfx::PluginWindowHandle window_;
  GC pixmap_graphics_context_;
  Pixmap pixmap_;
  OSMesaGLContext osmesa_context_;

  DISALLOW_COPY_AND_ASSIGN(OSMesaViewGLContext);
};

// This class is a wrapper around a GL context used for offscreen rendering.
// It is initially backed by a 1x1 pbuffer. Use it to create an FBO to do useful
// rendering.
class PbufferGLContext : public GLContext {
 public:
  explicit PbufferGLContext()
      : context_(NULL),
        pbuffer_(0) {
  }

  // Initializes the GL context.
  bool Initialize(GLContext* shared_context);

  virtual void Destroy();
  virtual bool MakeCurrent();
  virtual bool IsCurrent();
  virtual bool IsOffscreen();
  virtual bool SwapBuffers();
  virtual gfx::Size GetSize();
  virtual void* GetHandle();

 private:
  GLContextHandle context_;
  PbufferHandle pbuffer_;

  DISALLOW_COPY_AND_ASSIGN(PbufferGLContext);
};

// Backup context if Pbuffers (GLX 1.3) aren't supported. May run slower...
class PixmapGLContext : public GLContext {
 public:
  explicit PixmapGLContext()
      : context_(NULL),
        pixmap_(0),
        glx_pixmap_(0) {
  }

  // Initializes the GL context.
  bool Initialize(GLContext* shared_context);

  virtual void Destroy();
  virtual bool MakeCurrent();
  virtual bool IsCurrent();
  virtual bool IsOffscreen();
  virtual bool SwapBuffers();
  virtual gfx::Size GetSize();
  virtual void* GetHandle();

 private:
  GLContextHandle context_;
  Pixmap pixmap_;
  GLXPixmap glx_pixmap_;

  DISALLOW_COPY_AND_ASSIGN(PixmapGLContext);
};

// scoped_ptr functor for XFree(). Use as follows:
//   scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> foo(...);
// where "XVisualInfo" is any X type that is freed with XFree.
class ScopedPtrXFree {
 public:
  void operator()(void* x) const {
    ::XFree(x);
  }
};

bool GLContext::InitializeOneOff() {
  static bool initialized = false;
  if (initialized)
    return true;

  static const GLImplementation kAllowedGLImplementations[] = {
    kGLImplementationEGLGLES2,
    kGLImplementationDesktopGL,
    kGLImplementationOSMesaGL
  };

  if (!InitializeBestGLBindings(
           kAllowedGLImplementations,
           kAllowedGLImplementations + arraysize(kAllowedGLImplementations))) {
    LOG(ERROR) << "InitializeBestGLBindings failed.";
    return false;
  }

  // Only check the GLX version if we are in fact using GLX. We might actually
  // be using the mock GL implementation.
  if (GetGLImplementation() == kGLImplementationDesktopGL) {
    Display* display = x11_util::GetXDisplay();
    int major, minor;
    if (!glXQueryVersion(display, &major, &minor)) {
      LOG(ERROR) << "glxQueryVersion failed";
      return false;
    }

    if (major == 1 && minor < 3) {
      LOG(WARNING) << "GLX 1.3 or later is recommended.";
    }
  }

  initialized = true;
  return true;
}

bool ViewGLContext::Initialize(bool multisampled) {
  if (multisampled) {
    LOG(WARNING) << "Multisampling not implemented.";
  }

  Display* display = x11_util::GetXDisplay();
  XWindowAttributes attributes;
  XGetWindowAttributes(display, window_, &attributes);
  XVisualInfo visual_info_template;
  visual_info_template.visualid = XVisualIDFromVisual(attributes.visual);
  int visual_info_count = 0;
  scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> visual_info_list(
      XGetVisualInfo(display, VisualIDMask,
                     &visual_info_template,
                     &visual_info_count));
  DCHECK(visual_info_list.get());
  DCHECK_GT(visual_info_count, 0);
  context_ = NULL;
  for (int i = 0; i < visual_info_count; ++i) {
    context_ = glXCreateContext(display, visual_info_list.get() + i, 0, True);
    if (context_)
      break;
  }
  if (!context_) {
    LOG(ERROR) << "Couldn't create GL context.";<commit_msg>GPU process does one-off EGL initialization on linux.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file implements the ViewGLContext and PbufferGLContext classes.

#include "app/gfx/gl/gl_context.h"

#include <GL/osmesa.h>

#include "app/gfx/gl/gl_bindings.h"
#include "app/gfx/gl/gl_context_egl.h"
#include "app/gfx/gl/gl_context_osmesa.h"
#include "app/gfx/gl/gl_context_stub.h"
#include "app/gfx/gl/gl_implementation.h"
#include "app/x11_util.h"
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/scoped_ptr.h"

namespace gfx {

typedef GLXContext GLContextHandle;
typedef GLXPbuffer PbufferHandle;

// This class is a wrapper around a GL context that renders directly to a
// window.
class ViewGLContext : public GLContext {
 public:
  explicit ViewGLContext(gfx::PluginWindowHandle window)
      : window_(window),
        context_(NULL) {
    DCHECK(window);
  }

  // Initializes the GL context.
  bool Initialize(bool multisampled);

  virtual void Destroy();
  virtual bool MakeCurrent();
  virtual bool IsCurrent();
  virtual bool IsOffscreen();
  virtual bool SwapBuffers();
  virtual gfx::Size GetSize();
  virtual void* GetHandle();

 private:
  gfx::PluginWindowHandle window_;
  GLContextHandle context_;

  DISALLOW_COPY_AND_ASSIGN(ViewGLContext);
};

// This class is a wrapper around a GL context that uses OSMesa to render
// to an offscreen buffer and then blits it to a window.
class OSMesaViewGLContext : public GLContext {
 public:
  explicit OSMesaViewGLContext(gfx::PluginWindowHandle window)
      : window_graphics_context_(0),
        window_(window),
        pixmap_graphics_context_(0),
        pixmap_(0) {
    DCHECK(window);
  }

  // Initializes the GL context.
  bool Initialize();

  virtual void Destroy();
  virtual bool MakeCurrent();
  virtual bool IsCurrent();
  virtual bool IsOffscreen();
  virtual bool SwapBuffers();
  virtual gfx::Size GetSize();
  virtual void* GetHandle();

 private:
  bool UpdateSize();

  GC window_graphics_context_;
  gfx::PluginWindowHandle window_;
  GC pixmap_graphics_context_;
  Pixmap pixmap_;
  OSMesaGLContext osmesa_context_;

  DISALLOW_COPY_AND_ASSIGN(OSMesaViewGLContext);
};

// This class is a wrapper around a GL context used for offscreen rendering.
// It is initially backed by a 1x1 pbuffer. Use it to create an FBO to do useful
// rendering.
class PbufferGLContext : public GLContext {
 public:
  explicit PbufferGLContext()
      : context_(NULL),
        pbuffer_(0) {
  }

  // Initializes the GL context.
  bool Initialize(GLContext* shared_context);

  virtual void Destroy();
  virtual bool MakeCurrent();
  virtual bool IsCurrent();
  virtual bool IsOffscreen();
  virtual bool SwapBuffers();
  virtual gfx::Size GetSize();
  virtual void* GetHandle();

 private:
  GLContextHandle context_;
  PbufferHandle pbuffer_;

  DISALLOW_COPY_AND_ASSIGN(PbufferGLContext);
};

// Backup context if Pbuffers (GLX 1.3) aren't supported. May run slower...
class PixmapGLContext : public GLContext {
 public:
  explicit PixmapGLContext()
      : context_(NULL),
        pixmap_(0),
        glx_pixmap_(0) {
  }

  // Initializes the GL context.
  bool Initialize(GLContext* shared_context);

  virtual void Destroy();
  virtual bool MakeCurrent();
  virtual bool IsCurrent();
  virtual bool IsOffscreen();
  virtual bool SwapBuffers();
  virtual gfx::Size GetSize();
  virtual void* GetHandle();

 private:
  GLContextHandle context_;
  Pixmap pixmap_;
  GLXPixmap glx_pixmap_;

  DISALLOW_COPY_AND_ASSIGN(PixmapGLContext);
};

// scoped_ptr functor for XFree(). Use as follows:
//   scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> foo(...);
// where "XVisualInfo" is any X type that is freed with XFree.
class ScopedPtrXFree {
 public:
  void operator()(void* x) const {
    ::XFree(x);
  }
};

bool GLContext::InitializeOneOff() {
  static bool initialized = false;
  if (initialized)
    return true;

  static const GLImplementation kAllowedGLImplementations[] = {
    kGLImplementationEGLGLES2,
    kGLImplementationDesktopGL,
    kGLImplementationOSMesaGL
  };

  if (!InitializeBestGLBindings(
           kAllowedGLImplementations,
           kAllowedGLImplementations + arraysize(kAllowedGLImplementations))) {
    LOG(ERROR) << "InitializeBestGLBindings failed.";
    return false;
  }

  switch (GetGLImplementation()) {
    case kGLImplementationDesktopGL: {
      // Only check the GLX version if we are in fact using GLX. We might
      // actually be using the mock GL implementation.
      Display* display = x11_util::GetXDisplay();
      int major, minor;
      if (!glXQueryVersion(display, &major, &minor)) {
        LOG(ERROR) << "glxQueryVersion failed";
        return false;
      }

      if (major == 1 && minor < 3) {
        LOG(WARNING) << "GLX 1.3 or later is recommended.";
      }

      break;
    }
    case kGLImplementationEGLGLES2:
      if (!BaseEGLContext::InitializeOneOff()) {
        LOG(ERROR) << "BaseEGLContext::InitializeOneOff failed.";
        return false;
      }
      break;
    default:
      break;
  }

  initialized = true;
  return true;
}

bool ViewGLContext::Initialize(bool multisampled) {
  if (multisampled) {
    LOG(WARNING) << "Multisampling not implemented.";
  }

  Display* display = x11_util::GetXDisplay();
  XWindowAttributes attributes;
  XGetWindowAttributes(display, window_, &attributes);
  XVisualInfo visual_info_template;
  visual_info_template.visualid = XVisualIDFromVisual(attributes.visual);
  int visual_info_count = 0;
  scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> visual_info_list(
      XGetVisualInfo(display, VisualIDMask,
                     &visual_info_template,
                     &visual_info_count));
  DCHECK(visual_info_list.get());
  DCHECK_GT(visual_info_count, 0);
  context_ = NULL;
  for (int i = 0; i < visual_info_count; ++i) {
    context_ = glXCreateContext(display, visual_info_list.get() + i, 0, True);
    if (context_)
      break;
  }
  if (!context_) {
    LOG(ERROR) << "Couldn't create GL context.";
{'fraction_non_alphanumeric': 0.10140704354341853, 'fraction_numerical': 0.004912163849804346, 'mean_word_length': 3.8357487922705316, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7563770', 'n_tokens_mistral': 3842, 'n_tokens_neox': 3745, 'n_words': 1034}