• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 #ifndef TENSORFLOW_LITE_DELEGATES_GPU_GL_GL_SYNC_H_
17 #define TENSORFLOW_LITE_DELEGATES_GPU_GL_GL_SYNC_H_
18 
19 #include "tensorflow/lite/delegates/gpu/common/status.h"
20 #include "tensorflow/lite/delegates/gpu/gl/gl_buffer.h"
21 #include "tensorflow/lite/delegates/gpu/gl/gl_call.h"
22 #include "tensorflow/lite/delegates/gpu/gl/gl_program.h"
23 #include "tensorflow/lite/delegates/gpu/gl/portable_gl31.h"
24 
25 namespace tflite {
26 namespace gpu {
27 namespace gl {
28 
29 // RAII wrapper for OpenGL GLsync object.
30 // See https://www.khronos.org/opengl/wiki/Sync_Object for more information.
31 //
32 // GlSync is moveable but not copyable.
33 class GlSync {
34  public:
NewSync(GlSync * gl_sync)35   static Status NewSync(GlSync* gl_sync) {
36     GLsync sync;
37     RETURN_IF_ERROR(TFLITE_GPU_CALL_GL(glFenceSync, &sync,
38                                        GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
39     *gl_sync = GlSync(sync);
40     return OkStatus();
41   }
42 
43   // Creates invalid object.
GlSync()44   GlSync() : GlSync(nullptr) {}
45 
46   // Move-only
GlSync(GlSync && sync)47   GlSync(GlSync&& sync) : sync_(sync.sync_) { sync.sync_ = nullptr; }
48 
49   GlSync& operator=(GlSync&& sync) {
50     if (this != &sync) {
51       Invalidate();
52       std::swap(sync_, sync.sync_);
53     }
54     return *this;
55   }
56 
57   GlSync(const GlSync&) = delete;
58   GlSync& operator=(const GlSync&) = delete;
59 
~GlSync()60   ~GlSync() { Invalidate(); }
61 
sync()62   const GLsync sync() const { return sync_; }
63 
64  private:
GlSync(GLsync sync)65   explicit GlSync(GLsync sync) : sync_(sync) {}
66 
Invalidate()67   void Invalidate() {
68     if (sync_) {
69       glDeleteSync(sync_);
70       sync_ = nullptr;
71     }
72   }
73 
74   GLsync sync_;
75 };
76 
77 // Waits until GPU is done with processing.
78 Status GlSyncWait();
79 
80 // Waits until all comands are flushed and then performs active waiting by
81 // spinning a thread and checking sync status. It leads to shorter wait time
82 // (up to tens of ms) but consumes more CPU.
83 Status GlActiveSyncWait();
84 
85 // CPU checks the value in the buffer that is going to be written by GPU. The
86 // persistent buffer is used for the simultaneous access to the buffer by GPU
87 // and CPU. The instance remains invalid if persistent buffer OpenGL extension
88 // is not supported by the device.
89 class GlShaderSync {
90  public:
91   static Status NewSync(GlShaderSync* gl_sync);
GlShaderSync()92   GlShaderSync() {}
93   Status Wait();
94 
95  private:
96   GlProgram flag_program_;
97   GlPersistentBuffer flag_buffer_;
98 };
99 
100 }  // namespace gl
101 }  // namespace gpu
102 }  // namespace tflite
103 
104 #endif  // TENSORFLOW_LITE_DELEGATES_GPU_GL_GL_SYNC_H_
105