1// Copyright 2014 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_MAILBOX_SYNCHRONIZER_H_
6#define GPU_COMMAND_BUFFER_SERVICE_MAILBOX_SYNCHRONIZER_H_
7
8#include "gpu/command_buffer/common/mailbox.h"
9
10#include <map>
11#include <queue>
12#include <set>
13
14#include "base/memory/linked_ptr.h"
15#include "base/synchronization/lock.h"
16#include "gpu/command_buffer/service/texture_definition.h"
17#include "gpu/gpu_export.h"
18
19namespace gfx {
20class GLFence;
21}
22
23namespace gpu {
24namespace gles2 {
25
26class MailboxManager;
27class Texture;
28
29// A thread-safe proxy that can be used to emulate texture sharing across
30// share-groups.
31class MailboxSynchronizer {
32 public:
33  ~MailboxSynchronizer();
34
35  GPU_EXPORT static bool Initialize();
36  GPU_EXPORT static void Terminate();
37  static MailboxSynchronizer* GetInstance();
38
39  // Create a texture from a globally visible mailbox.
40  Texture* CreateTextureFromMailbox(unsigned target, const Mailbox& mailbox);
41
42  void PushTextureUpdates(MailboxManager* manager, uint32 sync_point);
43  void PullTextureUpdates(MailboxManager* manager, uint32 sync_point);
44
45  void TextureDeleted(Texture* texture);
46
47 private:
48  MailboxSynchronizer();
49
50  struct TargetName {
51    TargetName(unsigned target, const Mailbox& mailbox);
52    bool operator<(const TargetName& rhs) const {
53      return memcmp(this, &rhs, sizeof(rhs)) < 0;
54    }
55    bool operator!=(const TargetName& rhs) const {
56      return memcmp(this, &rhs, sizeof(rhs)) != 0;
57    }
58    bool operator==(const TargetName& rhs) const {
59      return !operator!=(rhs);
60    }
61    unsigned target;
62    Mailbox mailbox;
63  };
64
65  base::Lock lock_;
66
67  struct TextureGroup {
68    explicit TextureGroup(const TextureDefinition& definition);
69    ~TextureGroup();
70
71    TextureDefinition definition;
72    std::set<TargetName> mailboxes;
73   private:
74    DISALLOW_COPY_AND_ASSIGN(TextureGroup);
75  };
76
77  struct TextureVersion {
78    explicit TextureVersion(linked_ptr<TextureGroup> group);
79    ~TextureVersion();
80
81    unsigned int version;
82    linked_ptr<TextureGroup> group;
83  };
84  typedef std::map<Texture*, TextureVersion> TextureMap;
85  TextureMap textures_;
86
87  linked_ptr<TextureGroup> GetGroupForMailboxLocked(
88      const TargetName& target_name);
89  void ReassociateMailboxLocked(
90      const TargetName& target_name,
91      TextureGroup* group);
92  void UpdateTextureLocked(Texture* texture, TextureVersion& texture_version);
93  void CreateFenceLocked(uint32 sync_point);
94  void AcquireFenceLocked(uint32 sync_point);
95
96  typedef std::map<uint32, linked_ptr<gfx::GLFence> > SyncPointToFenceMap;
97  SyncPointToFenceMap sync_point_to_fence_;
98  std::queue<SyncPointToFenceMap::iterator> sync_points_;
99
100  DISALLOW_COPY_AND_ASSIGN(MailboxSynchronizer);
101};
102
103}  // namespage gles2
104}  // namespace gpu
105
106#endif  // GPU_COMMAND_BUFFER_SERVICE_MAILBOX_SYNCHRONIZER_H_
107
108