// 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 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 context_; base::scoped_nsobject 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> 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 pending_draw_weak_factory_; DISALLOW_COPY_AND_ASSIGN(CALayerStorageProvider); }; } // namespace content #endif // CONTENT_COMMON_GPU_IMAGE_TRANSPORT_SURFACE_CALAYER_MAC_H_