12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2011 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CC_OUTPUT_PROGRAM_BINDING_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CC_OUTPUT_PROGRAM_BINDING_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "cc/output/context_provider.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/output/shader.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace gpu {
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace gles2 {
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class GLES2Interface;
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ProgramBindingBase {
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProgramBindingBase();
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~ProgramBindingBase();
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool Init(gpu::gles2::GLES2Interface* context,
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            const std::string& vertex_shader,
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            const std::string& fragment_shader);
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool Link(gpu::gles2::GLES2Interface* context);
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void Cleanup(gpu::gles2::GLES2Interface* context);
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned program() const { return program_; }
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool initialized() const { return initialized_; }
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  unsigned LoadShader(gpu::gles2::GLES2Interface* context,
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      unsigned type,
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      const std::string& shader_source);
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  unsigned CreateShaderProgram(gpu::gles2::GLES2Interface* context,
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               unsigned vertex_shader,
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               unsigned fragment_shader);
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void CleanupShaders(gpu::gles2::GLES2Interface* context);
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned program_;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned vertex_shader_id_;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned fragment_shader_id_;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool initialized_;
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ProgramBindingBase);
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <class VertexShader, class FragmentShader>
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ProgramBinding : public ProgramBindingBase {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ProgramBinding() {}
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Initialize(ContextProvider* context_provider,
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  TexCoordPrecision precision,
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  SamplerType sampler) {
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(context_provider);
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!initialized_);
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (context_provider->IsContextLost())
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!ProgramBindingBase::Init(
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            context_provider->ContextGL(),
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            vertex_shader_.GetShaderString(),
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            fragment_shader_.GetShaderString(precision, sampler))) {
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DCHECK(context_provider->IsContextLost());
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return;
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int base_uniform_index = 0;
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    vertex_shader_.Init(context_provider->ContextGL(),
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        program_, &base_uniform_index);
79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    fragment_shader_.Init(context_provider->ContextGL(),
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          program_, &base_uniform_index);
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Link after binding uniforms
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!Link(context_provider->ContextGL())) {
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DCHECK(context_provider->IsContextLost());
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return;
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    initialized_ = true;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const VertexShader& vertex_shader() const { return vertex_shader_; }
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const FragmentShader& fragment_shader() const { return fragment_shader_; }
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VertexShader vertex_shader_;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FragmentShader fragment_shader_;
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ProgramBinding);
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // CC_OUTPUT_PROGRAM_BINDING_H_
104