// Copyright 2010 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 CC_OUTPUT_GL_RENDERER_H_ #define CC_OUTPUT_GL_RENDERER_H_ #include "base/cancelable_callback.h" #include "cc/base/cc_export.h" #include "cc/base/scoped_ptr_deque.h" #include "cc/base/scoped_ptr_vector.h" #include "cc/output/direct_renderer.h" #include "cc/output/gl_renderer_draw_cache.h" #include "cc/output/program_binding.h" #include "cc/output/renderer.h" #include "cc/quads/checkerboard_draw_quad.h" #include "cc/quads/debug_border_draw_quad.h" #include "cc/quads/io_surface_draw_quad.h" #include "cc/quads/render_pass_draw_quad.h" #include "cc/quads/solid_color_draw_quad.h" #include "cc/quads/tile_draw_quad.h" #include "cc/quads/yuv_video_draw_quad.h" #include "ui/gfx/quad_f.h" class SkBitmap; namespace gpu { namespace gles2 { class GLES2Interface; } } namespace cc { class GLRendererShaderTest; class OutputSurface; class PictureDrawQuad; class ScopedResource; class StreamVideoDrawQuad; class TextureDrawQuad; class TextureMailboxDeleter; class GeometryBinding; class ScopedEnsureFramebufferAllocation; // Class that handles drawing of composited render layers using GL. class CC_EXPORT GLRenderer : public DirectRenderer { public: class ScopedUseGrContext; static scoped_ptr Create( RendererClient* client, const LayerTreeSettings* settings, OutputSurface* output_surface, ResourceProvider* resource_provider, TextureMailboxDeleter* texture_mailbox_deleter, int highp_threshold_min); virtual ~GLRenderer(); virtual const RendererCapabilitiesImpl& Capabilities() const OVERRIDE; // Waits for rendering to finish. virtual void Finish() OVERRIDE; virtual void DoNoOp() OVERRIDE; virtual void SwapBuffers(const CompositorFrameMetadata& metadata) OVERRIDE; virtual void GetFramebufferPixels(void* pixels, const gfx::Rect& rect) OVERRIDE; virtual bool IsContextLost() OVERRIDE; virtual void SendManagedMemoryStats(size_t bytes_visible, size_t bytes_visible_and_nearby, size_t bytes_allocated) OVERRIDE; static void DebugGLCall(gpu::gles2::GLES2Interface* gl, const char* command, const char* file, int line); protected: GLRenderer(RendererClient* client, const LayerTreeSettings* settings, OutputSurface* output_surface, ResourceProvider* resource_provider, TextureMailboxDeleter* texture_mailbox_deleter, int highp_threshold_min); virtual void DidChangeVisibility() OVERRIDE; bool IsBackbufferDiscarded() const { return is_backbuffer_discarded_; } void InitializeGrContext(); const gfx::QuadF& SharedGeometryQuad() const { return shared_geometry_quad_; } const GeometryBinding* SharedGeometry() const { return shared_geometry_.get(); } void GetFramebufferPixelsAsync(const gfx::Rect& rect, scoped_ptr request); void GetFramebufferTexture(unsigned texture_id, ResourceFormat texture_format, const gfx::Rect& device_rect); void ReleaseRenderPassTextures(); void SetStencilEnabled(bool enabled); bool stencil_enabled() const { return stencil_shadow_; } void SetBlendEnabled(bool enabled); bool blend_enabled() const { return blend_shadow_; } virtual void BindFramebufferToOutputSurface(DrawingFrame* frame) OVERRIDE; virtual bool BindFramebufferToTexture(DrawingFrame* frame, const ScopedResource* resource, const gfx::Rect& target_rect) OVERRIDE; virtual void SetDrawViewport(const gfx::Rect& window_space_viewport) OVERRIDE; virtual void SetScissorTestRect(const gfx::Rect& scissor_rect) OVERRIDE; virtual void DiscardPixels(bool has_external_stencil_test, bool draw_rect_covers_full_surface) OVERRIDE; virtual void ClearFramebuffer(DrawingFrame* frame, bool has_external_stencil_test) OVERRIDE; virtual void DoDrawQuad(DrawingFrame* frame, const class DrawQuad*) OVERRIDE; virtual void BeginDrawingFrame(DrawingFrame* frame) OVERRIDE; virtual void FinishDrawingFrame(DrawingFrame* frame) OVERRIDE; virtual bool FlippedFramebuffer() const OVERRIDE; virtual void EnsureScissorTestEnabled() OVERRIDE; virtual void EnsureScissorTestDisabled() OVERRIDE; virtual void CopyCurrentRenderPassToBitmap( DrawingFrame* frame, scoped_ptr request) OVERRIDE; virtual void FinishDrawingQuadList() OVERRIDE; // Check if quad needs antialiasing and if so, inflate the quad and // fill edge array for fragment shader. local_quad is set to // inflated quad if antialiasing is required, otherwise it is left // unchanged. edge array is filled with inflated quad's edge data // if antialiasing is required, otherwise it is left unchanged. // Returns true if quad requires antialiasing and false otherwise. static bool SetupQuadForAntialiasing(const gfx::Transform& device_transform, const DrawQuad* quad, gfx::QuadF* local_quad, float edge[24]); private: friend class GLRendererShaderPixelTest; friend class GLRendererShaderTest; static void ToGLMatrix(float* gl_matrix, const gfx::Transform& transform); void DrawCheckerboardQuad(const DrawingFrame* frame, const CheckerboardDrawQuad* quad); void DrawDebugBorderQuad(const DrawingFrame* frame, const DebugBorderDrawQuad* quad); scoped_ptr GetBackgroundWithFilters( DrawingFrame* frame, const RenderPassDrawQuad* quad, const gfx::Transform& contents_device_transform, const gfx::Transform& contents_device_transformInverse, bool* background_changed); void DrawRenderPassQuad(DrawingFrame* frame, const RenderPassDrawQuad* quad); void DrawSolidColorQuad(const DrawingFrame* frame, const SolidColorDrawQuad* quad); void DrawStreamVideoQuad(const DrawingFrame* frame, const StreamVideoDrawQuad* quad); void EnqueueTextureQuad(const DrawingFrame* frame, const TextureDrawQuad* quad); void FlushTextureQuadCache(); void DrawIOSurfaceQuad(const DrawingFrame* frame, const IOSurfaceDrawQuad* quad); void DrawTileQuad(const DrawingFrame* frame, const TileDrawQuad* quad); void DrawContentQuad(const DrawingFrame* frame, const ContentDrawQuadBase* quad, ResourceProvider::ResourceId resource_id); void DrawYUVVideoQuad(const DrawingFrame* frame, const YUVVideoDrawQuad* quad); void DrawPictureQuad(const DrawingFrame* frame, const PictureDrawQuad* quad); void SetShaderOpacity(float opacity, int alpha_location); void SetShaderQuadF(const gfx::QuadF& quad, int quad_location); void DrawQuadGeometry(const DrawingFrame* frame, const gfx::Transform& draw_transform, const gfx::RectF& quad_rect, int matrix_location); void SetUseProgram(unsigned program); void CopyTextureToFramebuffer(const DrawingFrame* frame, int texture_id, const gfx::Rect& rect, const gfx::Transform& draw_matrix, bool flip_vertically); bool UseScopedTexture(DrawingFrame* frame, const ScopedResource* resource, const gfx::Rect& viewport_rect); bool MakeContextCurrent(); void InitializeSharedObjects(); void CleanupSharedObjects(); typedef base::Callback copy_request, bool success)> AsyncGetFramebufferPixelsCleanupCallback; void DoGetFramebufferPixels( uint8* pixels, const gfx::Rect& window_rect, const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback); void FinishedReadback( const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback, unsigned source_buffer, unsigned query, uint8_t* dest_pixels, const gfx::Size& size); void PassOnSkBitmap(scoped_ptr bitmap, scoped_ptr lock, scoped_ptr request, bool success); void ReinitializeGLState(); void RestoreGLState(); void RestoreFramebuffer(DrawingFrame* frame); virtual void DiscardBackbuffer() OVERRIDE; virtual void EnsureBackbuffer() OVERRIDE; void EnforceMemoryPolicy(); void ScheduleOverlays(DrawingFrame* frame); typedef ScopedPtrVector OverlayResourceLockList; OverlayResourceLockList pending_overlay_resources_; OverlayResourceLockList in_use_overlay_resources_; RendererCapabilitiesImpl capabilities_; unsigned offscreen_framebuffer_id_; scoped_ptr shared_geometry_; gfx::QuadF shared_geometry_quad_; // This block of bindings defines all of the programs used by the compositor // itself. Add any new programs here to GLRendererShaderTest. // Tiled layer shaders. typedef ProgramBinding TileProgram; typedef ProgramBinding TileProgramAA; typedef ProgramBinding TileProgramSwizzleAA; typedef ProgramBinding TileProgramOpaque; typedef ProgramBinding TileProgramSwizzle; typedef ProgramBinding TileProgramSwizzleOpaque; typedef ProgramBinding TileCheckerboardProgram; // Texture shaders. typedef ProgramBinding TextureProgram; typedef ProgramBinding NonPremultipliedTextureProgram; typedef ProgramBinding TextureBackgroundProgram; typedef ProgramBinding NonPremultipliedTextureBackgroundProgram; // Render surface shaders. typedef ProgramBinding RenderPassProgram; typedef ProgramBinding RenderPassMaskProgram; typedef ProgramBinding RenderPassProgramAA; typedef ProgramBinding RenderPassMaskProgramAA; typedef ProgramBinding RenderPassColorMatrixProgram; typedef ProgramBinding RenderPassMaskColorMatrixProgramAA; typedef ProgramBinding RenderPassColorMatrixProgramAA; typedef ProgramBinding RenderPassMaskColorMatrixProgram; // Video shaders. typedef ProgramBinding VideoStreamTextureProgram; typedef ProgramBinding VideoYUVProgram; typedef ProgramBinding VideoYUVAProgram; // Special purpose / effects shaders. typedef ProgramBinding DebugBorderProgram; typedef ProgramBinding SolidColorProgram; typedef ProgramBinding SolidColorProgramAA; const TileProgram* GetTileProgram( TexCoordPrecision precision, SamplerType sampler); const TileProgramOpaque* GetTileProgramOpaque( TexCoordPrecision precision, SamplerType sampler); const TileProgramAA* GetTileProgramAA( TexCoordPrecision precision, SamplerType sampler); const TileProgramSwizzle* GetTileProgramSwizzle( TexCoordPrecision precision, SamplerType sampler); const TileProgramSwizzleOpaque* GetTileProgramSwizzleOpaque( TexCoordPrecision precision, SamplerType sampler); const TileProgramSwizzleAA* GetTileProgramSwizzleAA( TexCoordPrecision precision, SamplerType sampler); const TileCheckerboardProgram* GetTileCheckerboardProgram(); const RenderPassProgram* GetRenderPassProgram( TexCoordPrecision precision); const RenderPassProgramAA* GetRenderPassProgramAA( TexCoordPrecision precision); const RenderPassMaskProgram* GetRenderPassMaskProgram( TexCoordPrecision precision); const RenderPassMaskProgramAA* GetRenderPassMaskProgramAA( TexCoordPrecision precision); const RenderPassColorMatrixProgram* GetRenderPassColorMatrixProgram( TexCoordPrecision precision); const RenderPassColorMatrixProgramAA* GetRenderPassColorMatrixProgramAA( TexCoordPrecision precision); const RenderPassMaskColorMatrixProgram* GetRenderPassMaskColorMatrixProgram( TexCoordPrecision precision); const RenderPassMaskColorMatrixProgramAA* GetRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision); const TextureProgram* GetTextureProgram( TexCoordPrecision precision); const NonPremultipliedTextureProgram* GetNonPremultipliedTextureProgram( TexCoordPrecision precision); const TextureBackgroundProgram* GetTextureBackgroundProgram( TexCoordPrecision precision); const NonPremultipliedTextureBackgroundProgram* GetNonPremultipliedTextureBackgroundProgram(TexCoordPrecision precision); const TextureProgram* GetTextureIOSurfaceProgram( TexCoordPrecision precision); const VideoYUVProgram* GetVideoYUVProgram( TexCoordPrecision precision); const VideoYUVAProgram* GetVideoYUVAProgram( TexCoordPrecision precision); const VideoStreamTextureProgram* GetVideoStreamTextureProgram( TexCoordPrecision precision); const DebugBorderProgram* GetDebugBorderProgram(); const SolidColorProgram* GetSolidColorProgram(); const SolidColorProgramAA* GetSolidColorProgramAA(); TileProgram tile_program_[NumTexCoordPrecisions][NumSamplerTypes]; TileProgramOpaque tile_program_opaque_[NumTexCoordPrecisions][NumSamplerTypes]; TileProgramAA tile_program_aa_[NumTexCoordPrecisions][NumSamplerTypes]; TileProgramSwizzle tile_program_swizzle_[NumTexCoordPrecisions][NumSamplerTypes]; TileProgramSwizzleOpaque tile_program_swizzle_opaque_[NumTexCoordPrecisions][NumSamplerTypes]; TileProgramSwizzleAA tile_program_swizzle_aa_[NumTexCoordPrecisions][NumSamplerTypes]; TileCheckerboardProgram tile_checkerboard_program_; TextureProgram texture_program_[NumTexCoordPrecisions]; NonPremultipliedTextureProgram nonpremultiplied_texture_program_[NumTexCoordPrecisions]; TextureBackgroundProgram texture_background_program_[NumTexCoordPrecisions]; NonPremultipliedTextureBackgroundProgram nonpremultiplied_texture_background_program_[NumTexCoordPrecisions]; TextureProgram texture_io_surface_program_[NumTexCoordPrecisions]; RenderPassProgram render_pass_program_[NumTexCoordPrecisions]; RenderPassProgramAA render_pass_program_aa_[NumTexCoordPrecisions]; RenderPassMaskProgram render_pass_mask_program_[NumTexCoordPrecisions]; RenderPassMaskProgramAA render_pass_mask_program_aa_[NumTexCoordPrecisions]; RenderPassColorMatrixProgram render_pass_color_matrix_program_[NumTexCoordPrecisions]; RenderPassColorMatrixProgramAA render_pass_color_matrix_program_aa_[NumTexCoordPrecisions]; RenderPassMaskColorMatrixProgram render_pass_mask_color_matrix_program_[NumTexCoordPrecisions]; RenderPassMaskColorMatrixProgramAA render_pass_mask_color_matrix_program_aa_[NumTexCoordPrecisions]; VideoYUVProgram video_yuv_program_[NumTexCoordPrecisions]; VideoYUVAProgram video_yuva_program_[NumTexCoordPrecisions]; VideoStreamTextureProgram video_stream_texture_program_[NumTexCoordPrecisions]; DebugBorderProgram debug_border_program_; SolidColorProgram solid_color_program_; SolidColorProgramAA solid_color_program_aa_; gpu::gles2::GLES2Interface* gl_; gpu::ContextSupport* context_support_; skia::RefPtr gr_context_; skia::RefPtr sk_canvas_; TextureMailboxDeleter* texture_mailbox_deleter_; gfx::Rect swap_buffer_rect_; gfx::Rect scissor_rect_; gfx::Rect viewport_; bool is_backbuffer_discarded_; bool is_using_bind_uniform_; bool is_scissor_enabled_; bool scissor_rect_needs_reset_; bool stencil_shadow_; bool blend_shadow_; unsigned program_shadow_; TexturedQuadDrawCache draw_cache_; int highp_threshold_min_; int highp_threshold_cache_; struct PendingAsyncReadPixels; ScopedPtrVector pending_async_read_pixels_; scoped_ptr current_framebuffer_lock_; class SyncQuery; ScopedPtrDeque pending_sync_queries_; ScopedPtrDeque available_sync_queries_; scoped_ptr current_sync_query_; bool use_sync_query_; SkBitmap on_demand_tile_raster_bitmap_; ResourceProvider::ResourceId on_demand_tile_raster_resource_id_; DISALLOW_COPY_AND_ASSIGN(GLRenderer); }; // Setting DEBUG_GL_CALLS to 1 will call glGetError() after almost every GL // call made by the compositor. Useful for debugging rendering issues but // will significantly degrade performance. #define DEBUG_GL_CALLS 0 #if DEBUG_GL_CALLS && !defined(NDEBUG) #define GLC(context, x) \ (x, GLRenderer::DebugGLCall(&* context, #x, __FILE__, __LINE__)) #else #define GLC(context, x) (x) #endif } // namespace cc #endif // CC_OUTPUT_GL_RENDERER_H_