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 CONTENT_COMMON_GPU_IMAGE_TRANSPORT_SURFACE_FBO_MAC_H_
6#define CONTENT_COMMON_GPU_IMAGE_TRANSPORT_SURFACE_FBO_MAC_H_
7
8#include "base/mac/scoped_cftyperef.h"
9#include "base/memory/scoped_ptr.h"
10#include "content/common/gpu/gpu_command_buffer_stub.h"
11#include "content/common/gpu/image_transport_surface.h"
12#include "ui/gl/gl_bindings.h"
13
14namespace content {
15
16// We are backed by an offscreen surface for the purposes of creating
17// a context, but use FBOs to render to texture. The texture may be backed by
18// an IOSurface, or it may be presented to the screen via a CALayer, depending
19// on the StorageProvider class specified.
20class ImageTransportSurfaceFBO
21    : public gfx::GLSurface,
22      public ImageTransportSurface,
23      public GpuCommandBufferStub::DestructionObserver {
24 public:
25  // The interface through which storage for the color buffer of the FBO is
26  // allocated.
27  class StorageProvider {
28   public:
29    virtual ~StorageProvider() {}
30    // IOSurfaces cause too much address space fragmentation if they are
31    // allocated on every resize. This gets a rounded size for allocation.
32    virtual gfx::Size GetRoundedSize(gfx::Size size) = 0;
33
34    // Allocate the storage for the color buffer. The specified context is
35    // current, and there is a texture bound to GL_TEXTURE_RECTANGLE_ARB.
36    virtual bool AllocateColorBufferStorage(
37        CGLContextObj context, GLuint texture,
38        gfx::Size size, float scale_factor) = 0;
39
40    // Free the storage allocated in the AllocateColorBufferStorage call. The
41    // GL texture that was bound has already been deleted by the caller.
42    virtual void FreeColorBufferStorage() = 0;
43
44    // Swap buffers and return the handle for the surface to send to the browser
45    // process to display.
46    virtual void SwapBuffers(const gfx::Size& size, float scale_factor) = 0;
47
48    // Indicate that the backbuffer will be written to.
49    virtual void WillWriteToBackbuffer() = 0;
50
51    // Indicate that the backbuffer has been discarded and should not be seen
52    // again.
53    virtual void DiscardBackbuffer() = 0;
54
55    // Called once for every SwapBuffers call when the IPC for the present has
56    // been processed by the browser.
57    virtual void SwapBuffersAckedByBrowser() = 0;
58  };
59
60  ImageTransportSurfaceFBO(GpuChannelManager* manager,
61                           GpuCommandBufferStub* stub,
62                           gfx::PluginWindowHandle handle);
63
64  // GLSurface implementation
65  virtual bool Initialize() OVERRIDE;
66  virtual void Destroy() OVERRIDE;
67  virtual bool DeferDraws() OVERRIDE;
68  virtual bool IsOffscreen() OVERRIDE;
69  virtual bool SwapBuffers() OVERRIDE;
70  virtual bool PostSubBuffer(int x, int y, int width, int height) OVERRIDE;
71  virtual bool SupportsPostSubBuffer() OVERRIDE;
72  virtual gfx::Size GetSize() OVERRIDE;
73  virtual void* GetHandle() OVERRIDE;
74  virtual void* GetDisplay() OVERRIDE;
75  virtual bool OnMakeCurrent(gfx::GLContext* context) OVERRIDE;
76  virtual unsigned int GetBackingFrameBufferObject() OVERRIDE;
77  virtual bool SetBackbufferAllocation(bool allocated) OVERRIDE;
78  virtual void SetFrontbufferAllocation(bool allocated) OVERRIDE;
79
80  // Called when the context may continue to make forward progress after a swap.
81  void SendSwapBuffers(uint64 surface_handle,
82                       const gfx::Size pixel_size,
83                       float scale_factor);
84
85 protected:
86  // ImageTransportSurface implementation
87  virtual void OnBufferPresented(
88      const AcceleratedSurfaceMsg_BufferPresented_Params& params) OVERRIDE;
89  virtual void OnResize(gfx::Size pixel_size, float scale_factor) OVERRIDE;
90  virtual void SetLatencyInfo(
91      const std::vector<ui::LatencyInfo>&) OVERRIDE;
92  virtual void WakeUpGpu() OVERRIDE;
93
94  // GpuCommandBufferStub::DestructionObserver implementation.
95  virtual void OnWillDestroyStub() OVERRIDE;
96
97 private:
98  virtual ~ImageTransportSurfaceFBO() OVERRIDE;
99
100  void AdjustBufferAllocation();
101  void DestroyFramebuffer();
102  void AllocateOrResizeFramebuffer(
103      const gfx::Size& pixel_size, float scale_factor);
104
105  scoped_ptr<StorageProvider> storage_provider_;
106
107  // Tracks the current buffer allocation state.
108  bool backbuffer_suggested_allocation_;
109  bool frontbuffer_suggested_allocation_;
110
111  uint32 fbo_id_;
112  GLuint texture_id_;
113  GLuint depth_stencil_renderbuffer_id_;
114  bool has_complete_framebuffer_;
115
116  // Weak pointer to the context that this was last made current to.
117  gfx::GLContext* context_;
118
119  gfx::Size pixel_size_;
120  gfx::Size rounded_pixel_size_;
121  float scale_factor_;
122
123  // Whether or not we've successfully made the surface current once.
124  bool made_current_;
125
126  // Whether a SwapBuffers IPC needs to be sent to the browser.
127  bool is_swap_buffers_send_pending_;
128  std::vector<ui::LatencyInfo> latency_info_;
129
130  scoped_ptr<ImageTransportHelper> helper_;
131
132  DISALLOW_COPY_AND_ASSIGN(ImageTransportSurfaceFBO);
133};
134
135}  // namespace content
136
137#endif  //  CONTENT_COMMON_GPU_IMAGE_TRANSPORT_SURFACE_MAC_H_
138