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
  194

cc / trees / layer_tree_frame_sink.h [blame]

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CC_TREES_LAYER_TREE_FRAME_SINK_H_
#define CC_TREES_LAYER_TREE_FRAME_SINK_H_

#include <deque>
#include <memory>

#include "base/memory/raw_ptr.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "cc/cc_export.h"
#include "cc/scheduler/scheduler.h"
#include "cc/trees/raster_context_provider_wrapper.h"
#include "components/viz/client/shared_bitmap_reporter.h"
#include "components/viz/common/gpu/context_lost_observer.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/gpu/raster_context_provider.h"
#include "components/viz/common/resources/returned_resource.h"
#include "gpu/ipc/client/gpu_channel_observer.h"
#include "ui/gfx/color_space.h"

namespace gpu {
class GpuMemoryBufferManager;
class ClientSharedImageInterface;
}

namespace viz {
class CompositorFrame;
class LocalSurfaceId;
struct BeginFrameAck;
}  // namespace viz

namespace cc {

class LayerContext;
class LayerTreeFrameSinkClient;
class LayerTreeHostImpl;

// An interface for submitting CompositorFrames to a display compositor
// which will compose frames from multiple clients to show on screen to the
// user.
// If a context_provider() is present, frames should be submitted with
// OpenGL resources (created with the context_provider()). If not, then
// SharedMemory resources should be used.
class CC_EXPORT LayerTreeFrameSink : public viz::SharedBitmapReporter,
                                     public viz::ContextLostObserver,
                                     public gpu::GpuChannelLostObserver {
 public:
  // Constructor for a frame sink local to the GPU process.
  LayerTreeFrameSink();

  // Constructor for GL-based and/or software resources.
  //
  // |compositor_task_runner| is used to post worker context lost callback and
  // must belong to the same thread where all calls to or from client are made.
  // Optional and won't be used unless |worker_context_provider_wrapper| is
  // present.
  //
  // |gpu_memory_buffer_manager| and |shared_bitmap_manager| must outlive the
  // LayerTreeFrameSink. |shared_bitmap_manager| is optional (won't be used) if
  // |context_provider| is present. |gpu_memory_buffer_manager| is optional
  // (won't be used) unless |context_provider| is present.
  LayerTreeFrameSink(
      scoped_refptr<viz::RasterContextProvider> context_provider,
      scoped_refptr<RasterContextProviderWrapper>
          worker_context_provider_wrapper,
      scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
      gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
      scoped_refptr<gpu::ClientSharedImageInterface> shared_image_interface);
  LayerTreeFrameSink(const LayerTreeFrameSink&) = delete;

  ~LayerTreeFrameSink() override;

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

  base::WeakPtr<LayerTreeFrameSink> GetWeakPtr();

  // Called by the compositor on the compositor thread. This is a place where
  // thread-specific data for the output surface can be initialized, since from
  // this point to when DetachFromClient() is called the output surface will
  // only be used on the compositor thread.
  // The caller should call DetachFromClient() on the same thread before
  // destroying the LayerTreeFrameSink, even if this fails. And BindToClient
  // should not be called twice for a given LayerTreeFrameSink.
  virtual bool BindToClient(LayerTreeFrameSinkClient* client);

  // Must be called from the thread where BindToClient was called if
  // BindToClient succeeded, after which the LayerTreeFrameSink may be
  // destroyed from any thread. This is a place where thread-specific data for
  // the object can be uninitialized.
  virtual void DetachFromClient();

  bool HasClient() { return !!client_; }

  void set_source_frame_number(int64_t frame_number) {
    source_frame_number_ = frame_number;
  }

  // The viz::RasterContextProviders may be null if frames should be submitted
  // with software SharedMemory resources.
  viz::RasterContextProvider* context_provider() const {
    return context_provider_.get();
  }
  RasterContextProviderWrapper* worker_context_provider_wrapper() const {
    return worker_context_provider_wrapper_.get();
  }
  viz::RasterContextProvider* worker_context_provider() const {
    return worker_context_provider_wrapper_
               ? worker_context_provider_wrapper_->GetContext().get()
               : nullptr;
  }
  gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager() const {
    return gpu_memory_buffer_manager_;
  }
  scoped_refptr<gpu::ClientSharedImageInterface> shared_image_interface() const;

  // If supported, this sets the viz::LocalSurfaceId the LayerTreeFrameSink will
  // use to submit a CompositorFrame.
  virtual void SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id) {}

  // Support for a pull-model where draws are requested by the implementation of
  // LayerTreeFrameSink. This is called by the compositor to notify that there's
  // new content. Can be called when nothing needs to be drawn if tile
  // priorities should be updated.
  virtual void Invalidate(bool needs_draw) {}

  // For successful swaps, the implementation must call
  // DidReceiveCompositorFrameAck() asynchronously when the frame has been
  // processed in order to unthrottle the next frame.
  // If |hit_test_data_changed| is false, we do an equality check
  // with the old hit-test data. If there is no change, we do not send the
  // hit-test data. False positives are allowed. The value of
  // |hit_test_data_changed| should remain constant in the caller.
  virtual void SubmitCompositorFrame(viz::CompositorFrame frame,
                                     bool hit_test_data_changed) = 0;

  // Signals that a BeginFrame issued by the viz::BeginFrameSource provided to
  // the client did not lead to a CompositorFrame submission.
  virtual void DidNotProduceFrame(const viz::BeginFrameAck& ack,
                                  FrameSkippedReason reason) = 0;

  // Creates a new LayerContext through which the client can control layers in
  // a GPU-side display tree.
  virtual std::unique_ptr<LayerContext> CreateLayerContext(
      LayerTreeHostImpl& host_impl);

  // viz::SharedBitmapReporter implementation.
  void DidAllocateSharedBitmap(base::ReadOnlySharedMemoryRegion region,
                               const viz::SharedBitmapId& id) override = 0;
  void DidDeleteSharedBitmap(const viz::SharedBitmapId& id) override = 0;

  class ContextLostForwarder;

  // viz::ContextLostObserver:
  void OnContextLost() override;

  // gpu::GpuChannelLostObserver override.
  void OnGpuChannelLost() override;

  void GpuChannelLostOnClientThread();

  // Causes gpu crash for testing.
  void CrashGpuProcessForTesting();

 protected:
  raw_ptr<LayerTreeFrameSinkClient> client_ = nullptr;

  scoped_refptr<viz::RasterContextProvider> context_provider_;
  scoped_refptr<RasterContextProviderWrapper> worker_context_provider_wrapper_;
  scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
  raw_ptr<gpu::GpuMemoryBufferManager> gpu_memory_buffer_manager_;
  scoped_refptr<gpu::ClientSharedImageInterface> shared_image_interface_;

  std::unique_ptr<ContextLostForwarder> worker_context_lost_forwarder_;

  int64_t source_frame_number_;

 private:
  // Forward the gpu channel lost task from the IO thread to the client thread.
  base::OnceCallback<void()> task_gpu_channel_lost_on_client_thread_;

  THREAD_CHECKER(thread_checker_);
  base::WeakPtrFactory<LayerTreeFrameSink> weak_ptr_factory_{this};
};

}  // namespace cc

#endif  // CC_TREES_LAYER_TREE_FRAME_SINK_H_