1// Copyright 2011 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#ifndef CC_OUTPUT_PROGRAM_BINDING_H_
6#define CC_OUTPUT_PROGRAM_BINDING_H_
7
8#include <string>
9
10#include "base/logging.h"
11#include "cc/output/context_provider.h"
12#include "cc/output/shader.h"
13
14namespace gpu {
15namespace gles2 {
16class GLES2Interface;
17}
18}
19
20namespace cc {
21
22class ProgramBindingBase {
23 public:
24  ProgramBindingBase();
25  ~ProgramBindingBase();
26
27  bool Init(gpu::gles2::GLES2Interface* context,
28            const std::string& vertex_shader,
29            const std::string& fragment_shader);
30  bool Link(gpu::gles2::GLES2Interface* context);
31  void Cleanup(gpu::gles2::GLES2Interface* context);
32
33  unsigned program() const { return program_; }
34  bool initialized() const { return initialized_; }
35
36 protected:
37  unsigned LoadShader(gpu::gles2::GLES2Interface* context,
38                      unsigned type,
39                      const std::string& shader_source);
40  unsigned CreateShaderProgram(gpu::gles2::GLES2Interface* context,
41                               unsigned vertex_shader,
42                               unsigned fragment_shader);
43  void CleanupShaders(gpu::gles2::GLES2Interface* context);
44
45  unsigned program_;
46  unsigned vertex_shader_id_;
47  unsigned fragment_shader_id_;
48  bool initialized_;
49
50 private:
51  DISALLOW_COPY_AND_ASSIGN(ProgramBindingBase);
52};
53
54template <class VertexShader, class FragmentShader>
55class ProgramBinding : public ProgramBindingBase {
56 public:
57  ProgramBinding() {}
58
59  void Initialize(ContextProvider* context_provider,
60                  TexCoordPrecision precision,
61                  SamplerType sampler) {
62    DCHECK(context_provider);
63    DCHECK(!initialized_);
64
65    if (context_provider->IsContextLost())
66      return;
67
68    if (!ProgramBindingBase::Init(
69            context_provider->ContextGL(),
70            vertex_shader_.GetShaderString(),
71            fragment_shader_.GetShaderString(precision, sampler))) {
72      DCHECK(context_provider->IsContextLost());
73      return;
74    }
75
76    int base_uniform_index = 0;
77    vertex_shader_.Init(context_provider->ContextGL(),
78                        program_, &base_uniform_index);
79    fragment_shader_.Init(context_provider->ContextGL(),
80                          program_, &base_uniform_index);
81
82    // Link after binding uniforms
83    if (!Link(context_provider->ContextGL())) {
84      DCHECK(context_provider->IsContextLost());
85      return;
86    }
87
88    initialized_ = true;
89  }
90
91  const VertexShader& vertex_shader() const { return vertex_shader_; }
92  const FragmentShader& fragment_shader() const { return fragment_shader_; }
93
94 private:
95  VertexShader vertex_shader_;
96  FragmentShader fragment_shader_;
97
98  DISALLOW_COPY_AND_ASSIGN(ProgramBinding);
99};
100
101}  // namespace cc
102
103#endif  // CC_OUTPUT_PROGRAM_BINDING_H_
104