| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CONTENT_COMMON_GPU_IMAGE_TRANSPORT_SURFACE_CALAYER_MAC_H_ |
| #define CONTENT_COMMON_GPU_IMAGE_TRANSPORT_SURFACE_CALAYER_MAC_H_ |
| |
| #include "base/mac/scoped_nsobject.h" |
| #include "content/common/gpu/image_transport_surface_fbo_mac.h" |
| #include "ui/base/cocoa/remote_layer_api.h" |
| #include "ui/gl/gpu_switching_observer.h" |
| #include "ui/gl/scoped_cgl.h" |
| |
| @class ImageTransportCAOpenGLLayer; |
| @class ImageTransportIOSurface; |
| |
| namespace content { |
| |
| // Allocate CAOpenGLLayer-backed storage for an FBO image transport surface. |
| class CALayerStorageProvider |
| : public ImageTransportSurfaceFBO::StorageProvider, |
| public ui::GpuSwitchingObserver { |
| public: |
| CALayerStorageProvider(ImageTransportSurfaceFBO* transport_surface); |
| ~CALayerStorageProvider() override; |
| |
| // ImageTransportSurfaceFBO::StorageProvider implementation: |
| gfx::Size GetRoundedSize(gfx::Size size) override; |
| bool AllocateColorBufferStorage( |
| CGLContextObj context, const base::Closure& context_dirtied_callback, |
| GLuint texture, gfx::Size pixel_size, float scale_factor) override; |
| void FreeColorBufferStorage() override; |
| void FrameSizeChanged( |
| const gfx::Size& pixel_size, float scale_factor) override; |
| void SwapBuffers(const gfx::Rect& dirty_rect) override; |
| void WillWriteToBackbuffer() override; |
| void DiscardBackbuffer() override; |
| void SwapBuffersAckedByBrowser(bool disable_throttling) override; |
| |
| // Interface to the CALayer. |
| CGLContextObj LayerShareGroupContext(); |
| base::Closure LayerShareGroupContextDirtiedCallback(); |
| bool LayerHasPendingDraw() const; |
| void LayerDoDraw(const gfx::Rect& dirty_rect, bool flipped); |
| void LayerUnblockBrowserIfNeeded(); |
| CAContext* LayerCAContext() { return context_.get(); } |
| |
| // ui::GpuSwitchingObserver implementation. |
| void OnGpuSwitched() override; |
| |
| private: |
| void CreateLayerAndRequestDraw(bool should_draw_immediately, |
| const gfx::Rect& dirty_rect); |
| void DrawImmediatelyAndUnblockBrowser(); |
| |
| // The browser will be blocked while there is a frame that was sent to it but |
| // hasn't drawn yet. This call will un-block the browser. |
| void UnblockBrowserIfNeeded(); |
| |
| // Inform the layer that it is no longer being used, and reset the layer. |
| void ResetLayer(); |
| |
| ImageTransportSurfaceFBO* transport_surface_; |
| |
| // Used to determine if we should use setNeedsDisplay or setAsynchronous to |
| // animate. If vsync is disabled, an immediate setNeedsDisplay and |
| // displayIfNeeded are called. |
| const bool gpu_vsync_disabled_; |
| |
| // Used also to determine if we should wait for CoreAnimation to call our |
| // drawInCGLContext, or if we should force it with displayIfNeeded. |
| bool throttling_disabled_; |
| |
| // Set when a new swap occurs, and un-set when the frame is acked to the |
| // browser. This is when the CAOpenGLLayer draws or when then IOSurface |
| // is committed. |
| bool has_pending_ack_; |
| |
| // The texture with the pixels to draw, and the share group it is allocated |
| // in. |
| base::ScopedTypeRef<CGLContextObj> share_group_context_; |
| base::Closure share_group_context_dirtied_callback_; |
| GLuint fbo_texture_; |
| gfx::Size fbo_pixel_size_; |
| float fbo_scale_factor_; |
| |
| // State for the Core Profile code path. |
| GLuint program_; |
| GLuint vertex_shader_; |
| GLuint fragment_shader_; |
| GLuint position_location_; |
| GLuint tex_location_; |
| GLuint vertex_buffer_; |
| GLuint vertex_array_; |
| |
| // The CALayer that the current frame is being drawn into. |
| base::scoped_nsobject<CAContext> context_; |
| base::scoped_nsobject<ImageTransportCAOpenGLLayer> ca_opengl_layer_; |
| |
| // When a CAContext is destroyed in the GPU process, it will become a blank |
| // CALayer in the browser process. Put retains on these contexts in this queue |
| // when they are discarded, and remove one item from the queue as each frame |
| // is acked. |
| std::list<base::scoped_nsobject<CAContext>> previously_discarded_contexts_; |
| |
| // Indicates that the CALayer should be recreated at the next swap. This is |
| // to ensure that the CGLContext created for the CALayer be on the right GPU. |
| bool recreate_layer_after_gpu_switch_; |
| |
| // Weak factory against which a timeout task for forcing a draw is created. |
| base::WeakPtrFactory<CALayerStorageProvider> pending_draw_weak_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CALayerStorageProvider); |
| }; |
| |
| } // namespace content |
| |
| #endif // CONTENT_COMMON_GPU_IMAGE_TRANSPORT_SURFACE_CALAYER_MAC_H_ |