File: gl_surface_presentation_helper.h

package info (click to toggle)
chromium 120.0.6099.224-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,112,112 kB
  • sloc: cpp: 32,907,025; ansic: 8,148,123; javascript: 3,679,536; python: 2,031,248; asm: 959,718; java: 804,675; xml: 617,256; sh: 111,417; objc: 100,835; perl: 88,443; cs: 53,032; makefile: 29,579; fortran: 24,137; php: 21,162; tcl: 21,147; sql: 20,809; ruby: 17,735; pascal: 12,864; yacc: 8,045; lisp: 3,388; lex: 1,323; ada: 727; awk: 329; jsp: 267; csh: 117; exp: 43; sed: 37
file content (125 lines) | stat: -rw-r--r-- 4,281 bytes parent folder | download | duplicates (5)
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
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_GL_GL_SURFACE_PRESENTATION_HELPER_H_
#define UI_GL_GL_SURFACE_PRESENTATION_HELPER_H_

#include "base/containers/circular_deque.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "ui/gfx/swap_result.h"
#include "ui/gl/gl_export.h"
#include "ui/gl/gl_surface.h"

namespace gfx {
class VSyncProvider;
}

namespace gl {

class GLContext;
class GLFence;
class GPUTimingClient;
class GPUTimer;

// Helper class for managering and invoke presentation callbacks for GLSurface
// implementations.
class GL_EXPORT GLSurfacePresentationHelper {
 public:
  class GL_EXPORT ScopedSwapBuffers {
   public:
    ScopedSwapBuffers(GLSurfacePresentationHelper* helper,
                      GLSurface::PresentationCallback callback);
    ScopedSwapBuffers(GLSurfacePresentationHelper* helper,
                      GLSurface::PresentationCallback callback,
                      int frame_id);

    ScopedSwapBuffers(const ScopedSwapBuffers&) = delete;
    ScopedSwapBuffers& operator=(const ScopedSwapBuffers&) = delete;

    ~ScopedSwapBuffers();

    void set_result(gfx::SwapResult result) { result_ = result; }
    gfx::SwapResult result() const { return result_; }

   private:
    const raw_ptr<GLSurfacePresentationHelper> helper_;
    gfx::SwapResult result_ = gfx::SwapResult::SWAP_ACK;
  };

  explicit GLSurfacePresentationHelper(gfx::VSyncProvider* vsync_provider);

  // For using fixed VSync provider.
  GLSurfacePresentationHelper(const base::TimeTicks timebase,
                              const base::TimeDelta interval);

  GLSurfacePresentationHelper(const GLSurfacePresentationHelper&) = delete;
  GLSurfacePresentationHelper& operator=(const GLSurfacePresentationHelper&) =
      delete;

  ~GLSurfacePresentationHelper();

  void OnMakeCurrent(GLContext* context, GLSurface* surface);
  void PreSwapBuffers(GLSurface::PresentationCallback callback, int frame_id);
  void PostSwapBuffers(gfx::SwapResult result);

 private:
  struct Frame {
    Frame(Frame&& other);
    Frame(int frame_id, GLSurface::PresentationCallback callback);
    Frame(std::unique_ptr<GPUTimer>&& timer,
          GLSurface::PresentationCallback callback);
    Frame(std::unique_ptr<GLFence>&& fence,
          GLSurface::PresentationCallback callback);
    explicit Frame(GLSurface::PresentationCallback callback);
    ~Frame();
    Frame& operator=(Frame&& other);

    void Destroy(bool has_context = false);

    std::unique_ptr<GPUTimer> timer;
    // GLFence is used only if gpu timers are not available.
    std::unique_ptr<GLFence> fence;
    int frame_id = -1;
    GLSurface::PresentationCallback callback;
    gfx::SwapResult result = gfx::SwapResult::SWAP_ACK;
  };

  bool GetFrameTimestampInfoIfAvailable(const Frame& frame,
                                        base::TimeTicks* timestamp,
                                        base::TimeDelta* interval,
                                        base::TimeTicks* writes_done,
                                        uint32_t* flags);

  // Check |pending_frames_| and run presentation callbacks.
  void CheckPendingFrames();

  // Callback used by PostDelayedTask for running CheckPendingFrames().
  void CheckPendingFramesCallback();

  void UpdateVSyncCallback(bool should_check_pending_frames,
                           const base::TimeTicks timebase,
                           const base::TimeDelta interval);

  void ScheduleCheckPendingFrames(bool align_with_next_vsync);

  const raw_ptr<gfx::VSyncProvider> vsync_provider_;
  scoped_refptr<GLContext> gl_context_;
  raw_ptr<GLSurface> surface_ = nullptr;
  scoped_refptr<GPUTimingClient> gpu_timing_client_;
  base::circular_deque<Frame> pending_frames_;
  base::TimeTicks vsync_timebase_;
  base::TimeDelta vsync_interval_;
  bool check_pending_frame_scheduled_ = false;
  bool gl_fence_supported_ = false;
  raw_ptr<EGLTimestampClient> egl_timestamp_client_ = nullptr;
  bool update_vsync_pending_ = false;

  base::WeakPtrFactory<GLSurfacePresentationHelper> weak_ptr_factory_{this};
};

}  // namespace gl

#endif  // UI_GL_GL_SURFACE_PRESENTATION_HELPER_H_