1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "cc/test/test_in_process_context_provider.h"
6
7#include "base/lazy_instance.h"
8#include "gpu/GLES2/gl2extchromium.h"
9#include "gpu/command_buffer/client/gl_in_process_context.h"
10#include "gpu/command_buffer/client/gles2_implementation.h"
11#include "gpu/command_buffer/client/gles2_lib.h"
12#include "gpu/command_buffer/common/gles2_cmd_utils.h"
13#include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h"
14#include "third_party/khronos/GLES2/gl2.h"
15#include "third_party/khronos/GLES2/gl2ext.h"
16#include "third_party/skia/include/gpu/GrContext.h"
17#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
18#include "ui/gfx/native_widget_types.h"
19
20namespace cc {
21
22// static
23scoped_ptr<gpu::GLInProcessContext> CreateTestInProcessContext() {
24  const bool is_offscreen = true;
25  const bool share_resources = true;
26  gpu::gles2::ContextCreationAttribHelper attribs;
27  attribs.alpha_size = 8;
28  attribs.blue_size = 8;
29  attribs.green_size = 8;
30  attribs.red_size = 8;
31  attribs.depth_size = 24;
32  attribs.stencil_size = 8;
33  attribs.samples = 0;
34  attribs.sample_buffers = 0;
35  attribs.fail_if_major_perf_caveat = false;
36  attribs.bind_generates_resource = false;
37  gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
38
39  scoped_ptr<gpu::GLInProcessContext> context =
40      make_scoped_ptr(gpu::GLInProcessContext::Create(
41          NULL,
42          NULL,
43          is_offscreen,
44          gfx::kNullAcceleratedWidget,
45          gfx::Size(1, 1),
46          NULL,
47          share_resources,
48          attribs,
49          gpu_preference,
50          gpu::GLInProcessContextSharedMemoryLimits()));
51
52  DCHECK(context);
53  return context.Pass();
54}
55
56TestInProcessContextProvider::TestInProcessContextProvider()
57    : context_(CreateTestInProcessContext()) {}
58
59TestInProcessContextProvider::~TestInProcessContextProvider() {
60}
61
62bool TestInProcessContextProvider::BindToCurrentThread() { return true; }
63
64gpu::gles2::GLES2Interface* TestInProcessContextProvider::ContextGL() {
65  return context_->GetImplementation();
66}
67
68gpu::ContextSupport* TestInProcessContextProvider::ContextSupport() {
69  return context_->GetImplementation();
70}
71
72namespace {
73
74// Singleton used to initialize and terminate the gles2 library.
75class GLES2Initializer {
76 public:
77  GLES2Initializer() { ::gles2::Initialize(); }
78
79  ~GLES2Initializer() { ::gles2::Terminate(); }
80
81 private:
82  DISALLOW_COPY_AND_ASSIGN(GLES2Initializer);
83};
84
85static base::LazyInstance<GLES2Initializer> g_gles2_initializer =
86    LAZY_INSTANCE_INITIALIZER;
87
88}  // namespace
89
90static void BindGrContextCallback(const GrGLInterface* interface) {
91  TestInProcessContextProvider* context_provider =
92      reinterpret_cast<TestInProcessContextProvider*>(interface->fCallbackData);
93
94  gles2::SetGLContext(context_provider->ContextGL());
95}
96
97class GrContext* TestInProcessContextProvider::GrContext() {
98  if (gr_context_)
99    return gr_context_.get();
100
101  // The GrGLInterface factory will make GL calls using the C GLES2 interface.
102  // Make sure the gles2 library is initialized first on exactly one thread.
103  g_gles2_initializer.Get();
104  gles2::SetGLContext(ContextGL());
105
106  skia::RefPtr<GrGLInterface> interface =
107      skia::AdoptRef(skia_bindings::CreateCommandBufferSkiaGLBinding());
108  interface->fCallback = BindGrContextCallback;
109  interface->fCallbackData = reinterpret_cast<GrGLInterfaceCallbackData>(this);
110
111  gr_context_ = skia::AdoptRef(GrContext::Create(
112      kOpenGL_GrBackend, reinterpret_cast<GrBackendContext>(interface.get())));
113
114  return gr_context_.get();
115}
116
117ContextProvider::Capabilities
118TestInProcessContextProvider::ContextCapabilities() {
119  return ContextProvider::Capabilities();
120}
121
122bool TestInProcessContextProvider::IsContextLost() { return false; }
123
124void TestInProcessContextProvider::VerifyContexts() {}
125
126void TestInProcessContextProvider::DeleteCachedResources() {
127  if (gr_context_)
128    gr_context_->freeGpuResources();
129}
130
131bool TestInProcessContextProvider::DestroyedOnMainThread() { return false; }
132
133void TestInProcessContextProvider::SetLostContextCallback(
134    const LostContextCallback& lost_context_callback) {}
135
136void TestInProcessContextProvider::SetMemoryPolicyChangedCallback(
137    const MemoryPolicyChangedCallback& memory_policy_changed_callback) {}
138
139}  // namespace cc
140