summaryrefslogtreecommitdiff
path: root/chromium/gpu/command_buffer/client/share_group.h
blob: 7066bb5fd7c0f9494df09f77d414056f97a944ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// Copyright (c) 2012 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.

#ifndef GPU_COMMAND_BUFFER_CLIENT_SHARE_GROUP_H_
#define GPU_COMMAND_BUFFER_CLIENT_SHARE_GROUP_H_

#include <stdint.h>

#include <memory>

#include "base/macros.h"
#include "base/synchronization/lock.h"
#include "gles2_impl_export.h"
#include "gpu/command_buffer/client/client_discardable_manager.h"
#include "gpu/command_buffer/client/ref_counted.h"
#include "gpu/command_buffer/common/gles2_cmd_format.h"

namespace gpu {
namespace gles2 {

class GLES2Implementation;
class GLES2ImplementationTest;
class ProgramInfoManager;

typedef void (GLES2Implementation::*DeleteFn)(GLsizei n, const GLuint* ids);
typedef void (GLES2Implementation::*DeleteRangeFn)(const GLuint first_id,
                                                   GLsizei range);
typedef void (GLES2Implementation::*BindFn)(GLenum target, GLuint id);
typedef void (GLES2Implementation::*BindIndexedFn)( \
    GLenum target, GLuint index, GLuint id);
typedef void (GLES2Implementation::*BindIndexedRangeFn)( \
    GLenum target, GLuint index, GLuint id, GLintptr offset, GLsizeiptr size);

using SharedIdNamespaces = id_namespaces::SharedIdNamespaces;

class ShareGroupContextData {
 public:
  struct IdHandlerData {
    IdHandlerData();
    ~IdHandlerData();

    std::vector<GLuint> freed_ids_;
    uint32_t flush_generation_;
  };

  IdHandlerData* id_handler_data(int namespace_id) {
    return &id_handler_data_[namespace_id];
  }

 private:
  IdHandlerData id_handler_data_[static_cast<int>(
      SharedIdNamespaces::kNumSharedIdNamespaces)];
};

// Base class for IdHandlers
class IdHandlerInterface {
 public:
  IdHandlerInterface() { }
  virtual ~IdHandlerInterface() { }

  // Makes some ids at or above id_offset.
  virtual void MakeIds(
      GLES2Implementation* gl_impl,
      GLuint id_offset, GLsizei n, GLuint* ids) = 0;

  // Frees some ids.
  virtual bool FreeIds(
      GLES2Implementation* gl_impl, GLsizei n, const GLuint* ids,
      DeleteFn delete_fn) = 0;

  // Marks an id as used for glBind functions. id = 0 does nothing.
  virtual bool MarkAsUsedForBind(
      GLES2Implementation* gl_impl,
      GLenum target,
      GLuint id,
      BindFn bind_fn) = 0;
  // This is for glBindBufferBase.
  virtual bool MarkAsUsedForBind(
      GLES2Implementation* gl_impl,
      GLenum target,
      GLuint index,
      GLuint id,
      BindIndexedFn bind_fn) = 0;
  // This is for glBindBufferRange.
  virtual bool MarkAsUsedForBind(
      GLES2Implementation* gl_impl,
      GLenum target,
      GLuint index,
      GLuint id,
      GLintptr offset,
      GLsizeiptr size,
      BindIndexedRangeFn bind_fn) = 0;

  // Called when a context in the share group is destructed.
  virtual void FreeContext(GLES2Implementation* gl_impl) = 0;
};

class RangeIdHandlerInterface {
 public:
  RangeIdHandlerInterface() {}
  virtual ~RangeIdHandlerInterface() {}

  // Makes a continuous range of ids. Stores the first allocated id to
  // |first_id| or 0 if allocation failed.
  virtual void MakeIdRange(GLES2Implementation* gl_impl,
                           GLsizei n,
                           GLuint* first_id) = 0;

  // Frees a continuous |range| of ids beginning at |first_id|.
  virtual void FreeIdRange(GLES2Implementation* gl_impl,
                           const GLuint first_id,
                           GLsizei range,
                           DeleteRangeFn delete_fn) = 0;

  // Called when a context in the share group is destructed.
  virtual void FreeContext(GLES2Implementation* gl_impl) = 0;
};

// ShareGroup manages shared resources for contexts that are sharing resources.
class GLES2_IMPL_EXPORT ShareGroup
    : public gpu::RefCountedThreadSafe<ShareGroup> {
 public:
  ShareGroup(bool bind_generates_resource, uint64_t tracing_guid);

  bool bind_generates_resource() const {
    return bind_generates_resource_;
  }

  IdHandlerInterface* GetIdHandler(SharedIdNamespaces namespace_id) const {
    return id_handlers_[static_cast<int>(namespace_id)].get();
  }

  RangeIdHandlerInterface* GetRangeIdHandler(int range_namespace_id) const {
    return range_id_handlers_[range_namespace_id].get();
  }

  ProgramInfoManager* program_info_manager() {
    return program_info_manager_.get();
  }

  void FreeContext(GLES2Implementation* gl_impl) {
    for (int i = 0;
         i < static_cast<int>(SharedIdNamespaces::kNumSharedIdNamespaces);
         ++i) {
      id_handlers_[i]->FreeContext(gl_impl);
    }
    for (auto& range_id_handler : range_id_handlers_) {
      range_id_handler->FreeContext(gl_impl);
    }
  }

  uint64_t TracingGUID() const { return tracing_guid_; }

  ClientDiscardableManager* discardable_manager() {
    return &discardable_manager_;
  }

  // Mark the ShareGroup as lost when an error occurs on any context in the
  // group. This is thread safe as contexts may be on different threads.
  void Lose();
  // Report if any context in the ShareGroup has reported itself lost. This is
  // thread safe as contexts may be on different threads.
  bool IsLost() const;

 private:
  friend class gpu::RefCountedThreadSafe<ShareGroup>;
  friend class gpu::gles2::GLES2ImplementationTest;
  ~ShareGroup();

  // Install a new program info manager. Used for testing only;
  void SetProgramInfoManagerForTesting(ProgramInfoManager* manager);

  std::unique_ptr<IdHandlerInterface> id_handlers_[static_cast<int>(
      SharedIdNamespaces::kNumSharedIdNamespaces)];
  std::unique_ptr<RangeIdHandlerInterface>
      range_id_handlers_[id_namespaces::kNumRangeIdNamespaces];
  std::unique_ptr<ProgramInfoManager> program_info_manager_;
  ClientDiscardableManager discardable_manager_;

  bool bind_generates_resource_;
  uint64_t tracing_guid_;

  mutable base::Lock lost_lock_;
  bool lost_ = false;

  DISALLOW_COPY_AND_ASSIGN(ShareGroup);
};

}  // namespace gles2
}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_CLIENT_SHARE_GROUP_H_