1// Copyright (c) 2012 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 GPU_COMMAND_BUFFER_SERVICE_PROGRAM_CACHE_H_
6#define GPU_COMMAND_BUFFER_SERVICE_PROGRAM_CACHE_H_
7
8#include <map>
9#include <string>
10
11#include "base/containers/hash_tables.h"
12#include "base/sha1.h"
13#include "gpu/command_buffer/common/gles2_cmd_format.h"
14#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
15#include "gpu/command_buffer/service/shader_manager.h"
16
17namespace gpu {
18namespace gles2 {
19
20class Shader;
21class ShaderTranslator;
22
23// Program cache base class for caching linked gpu programs
24class GPU_EXPORT ProgramCache {
25 public:
26  static const size_t kHashLength = base::kSHA1Length;
27
28  typedef std::map<std::string, GLint> LocationMap;
29
30  enum LinkedProgramStatus {
31    LINK_UNKNOWN,
32    LINK_SUCCEEDED
33  };
34
35  enum ProgramLoadResult {
36    PROGRAM_LOAD_FAILURE,
37    PROGRAM_LOAD_SUCCESS
38  };
39
40  ProgramCache();
41  virtual ~ProgramCache();
42
43  LinkedProgramStatus GetLinkedProgramStatus(
44      const std::string& untranslated_shader_a,
45      const ShaderTranslatorInterface* translator_a,
46      const std::string& untranslated_shader_b,
47      const ShaderTranslatorInterface* translator_b,
48      const LocationMap* bind_attrib_location_map) const;
49
50  // Loads the linked program from the cache.  If the program is not found or
51  // there was an error, PROGRAM_LOAD_FAILURE should be returned.
52  virtual ProgramLoadResult LoadLinkedProgram(
53      GLuint program,
54      Shader* shader_a,
55      const ShaderTranslatorInterface* translator_a,
56      Shader* shader_b,
57      const ShaderTranslatorInterface* translator_b,
58      const LocationMap* bind_attrib_location_map,
59      const ShaderCacheCallback& shader_callback) = 0;
60
61  // Saves the program into the cache.  If successful, the implementation should
62  // call LinkedProgramCacheSuccess.
63  virtual void SaveLinkedProgram(
64      GLuint program,
65      const Shader* shader_a,
66      const ShaderTranslatorInterface* translator_a,
67      const Shader* shader_b,
68      const ShaderTranslatorInterface* translator_b,
69      const LocationMap* bind_attrib_location_map,
70      const ShaderCacheCallback& shader_callback) = 0;
71
72  virtual void LoadProgram(const std::string& program) = 0;
73
74  // clears the cache
75  void Clear();
76
77  // Only for testing
78  void LinkedProgramCacheSuccess(const std::string& shader_a,
79                                 const ShaderTranslatorInterface* translator_a,
80                                 const std::string& shader_b,
81                                 const ShaderTranslatorInterface* translator_b,
82                                 const LocationMap* bind_attrib_location_map);
83
84 protected:
85  // called by implementing class after a shader was successfully cached
86  void LinkedProgramCacheSuccess(const std::string& program_hash);
87
88  // result is not null terminated
89  void ComputeShaderHash(const std::string& shader,
90                         const ShaderTranslatorInterface* translator,
91                         char* result) const;
92
93  // result is not null terminated.  hashed shaders are expected to be
94  // kHashLength in length
95  void ComputeProgramHash(
96      const char* hashed_shader_0,
97      const char* hashed_shader_1,
98      const LocationMap* bind_attrib_location_map,
99      char* result) const;
100
101  void Evict(const std::string& program_hash);
102
103 private:
104  typedef base::hash_map<std::string,
105                         LinkedProgramStatus> LinkStatusMap;
106
107  // called to clear the backend cache
108  virtual void ClearBackend() = 0;
109
110  LinkStatusMap link_status_;
111
112  DISALLOW_COPY_AND_ASSIGN(ProgramCache);
113};
114
115}  // namespace gles2
116}  // namespace gpu
117
118#endif  // GPU_COMMAND_BUFFER_SERVICE_PROGRAM_CACHE_H_
119