// 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 "cc/base/cc_export.h" #include "cc/output/direct_renderer.h" #include "cc/output/gl_renderer_draw_cache.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 "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsMemoryAllocation.h" #include "ui/gfx/quad_f.h" namespace cc { class GLRendererShaderTest; class OutputSurface; class ScopedResource; class StreamVideoDrawQuad; class TextureDrawQuad; class GeometryBinding; class ScopedEnsureFramebufferAllocation; // Class that handles drawing of composited render layers using GL. class CC_EXPORT GLRenderer : public DirectRenderer, public NON_EXPORTED_BASE( WebKit::WebGraphicsContext3D:: WebGraphicsSwapBuffersCompleteCallbackCHROMIUM), public NON_EXPORTED_BASE( WebKit::WebGraphicsContext3D:: WebGraphicsMemoryAllocationChangedCallbackCHROMIUM), public NON_EXPORTED_BASE( WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback) { public: static scoped_ptr Create(RendererClient* client, OutputSurface* output_surface, ResourceProvider* resource_provider); virtual ~GLRenderer(); virtual const RendererCapabilities& Capabilities() const OVERRIDE; WebKit::WebGraphicsContext3D* Context(); virtual void ViewportChanged() OVERRIDE; virtual void ReceiveCompositorFrameAck(const CompositorFrameAck& ack) OVERRIDE; // Waits for rendering to finish. virtual void Finish() OVERRIDE; virtual void DoNoOp() OVERRIDE; // Puts backbuffer onscreen. virtual bool SwapBuffers() OVERRIDE; virtual void GetFramebufferPixels(void* pixels, gfx::Rect rect) OVERRIDE; virtual bool IsContextLost() OVERRIDE; virtual void SetVisible(bool visible) OVERRIDE; virtual void SendManagedMemoryStats(size_t bytes_visible, size_t bytes_visible_and_nearby, size_t bytes_allocated) OVERRIDE; static void DebugGLCall(WebKit::WebGraphicsContext3D* context, const char* command, const char* file, int line); protected: GLRenderer(RendererClient* client, OutputSurface* output_surface, ResourceProvider* resource_provider); bool IsBackbufferDiscarded() const { return is_backbuffer_discarded_; } bool Initialize(); const gfx::QuadF& SharedGeometryQuad() const { return shared_geometry_quad_; } const GeometryBinding* SharedGeometry() const { return shared_geometry_.get(); } bool GetFramebufferTexture(ScopedResource* resource, gfx::Rect device_rect); void ReleaseRenderPassTextures(); virtual void BindFramebufferToOutputSurface(DrawingFrame& frame) OVERRIDE; virtual bool BindFramebufferToTexture(DrawingFrame& frame, const ScopedResource* resource, gfx::Rect framebuffer_rect) OVERRIDE; virtual void SetDrawViewportSize(gfx::Size viewport_size) OVERRIDE; virtual void SetScissorTestRect(gfx::Rect scissor_rect) OVERRIDE; virtual void ClearFramebuffer(DrawingFrame& frame) 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 FinishDrawingQuadList() OVERRIDE; private: friend class GLRendererShaderTest; static void ToGLMatrix(float* gl_matrix, const gfx::Transform& transform); static ManagedMemoryPolicy::PriorityCutoff PriorityCutoff( WebKit::WebGraphicsMemoryAllocation::PriorityCutoff priority_cutoff); void DrawCheckerboardQuad(const DrawingFrame& frame, const CheckerboardDrawQuad* quad); void DrawDebugBorderQuad(const DrawingFrame& frame, const DebugBorderDrawQuad* quad); scoped_ptr DrawBackgroundFilters( DrawingFrame& frame, const RenderPassDrawQuad* quad, const gfx::Transform& contents_device_transform, const gfx::Transform& contents_device_transformInverse); void DrawRenderPassQuad(DrawingFrame& frame, const RenderPassDrawQuad* quad); void DrawSolidColorQuad(const DrawingFrame& frame, const SolidColorDrawQuad* quad); void DrawStreamVideoQuad(const DrawingFrame& frame, const StreamVideoDrawQuad* quad); void DrawTextureQuad(const DrawingFrame& frame, const TextureDrawQuad* 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 DrawYUVVideoQuad(const DrawingFrame& frame, const YUVVideoDrawQuad* 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 SetBlendEnabled(bool enabled); void SetUseProgram(unsigned program); void CopyTextureToFramebuffer(const DrawingFrame& frame, int texture_id, gfx::Rect rect, const gfx::Transform& draw_matrix); // Check if quad needs antialiasing and if so, inflate the quad and // fill edge array for fragment shader. localQuad 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. bool SetupQuadForAntialiasing(const gfx::Transform& device_transform, const DrawQuad* quad, gfx::QuadF* local_quad, float edge[24]) const; bool UseScopedTexture(DrawingFrame& frame, const ScopedResource* resource, gfx::Rect viewport_rect); bool MakeContextCurrent(); bool InitializeSharedObjects(); void CleanupSharedObjects(); // WebKit:: // WebGraphicsContext3D::WebGraphicsSwapBuffersCompleteCallbackCHROMIUM // implementation. virtual void onSwapBuffersComplete() OVERRIDE; // WebKit:: // WebGraphicsContext3D::WebGraphicsMemoryAllocationChangedCallbackCHROMIUM // implementation. virtual void onMemoryAllocationChanged( WebKit::WebGraphicsMemoryAllocation allocation) OVERRIDE; void DiscardBackbuffer(); void EnsureBackbuffer(); void EnforceMemoryPolicy(); // WebGraphicsContext3D::WebGraphicsContextLostCallback implementation. virtual void onContextLost() OVERRIDE; RendererCapabilities 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; // Render surface shaders. typedef ProgramBinding RenderPassProgram; typedef ProgramBinding RenderPassMaskProgram; typedef ProgramBinding RenderPassProgramAA; typedef ProgramBinding RenderPassMaskProgramAA; // Texture shaders. typedef ProgramBinding TextureProgram; typedef ProgramBinding TextureProgramFlip; typedef ProgramBinding TextureIOSurfaceProgram; // Video shaders. typedef ProgramBinding VideoStreamTextureProgram; typedef ProgramBinding VideoYUVProgram; // Special purpose / effects shaders. typedef ProgramBinding DebugBorderProgram; typedef ProgramBinding SolidColorProgram; typedef ProgramBinding SolidColorProgramAA; const TileProgram* GetTileProgram(); const TileProgramOpaque* GetTileProgramOpaque(); const TileProgramAA* GetTileProgramAA(); const TileProgramSwizzle* GetTileProgramSwizzle(); const TileProgramSwizzleOpaque* GetTileProgramSwizzleOpaque(); const TileProgramSwizzleAA* GetTileProgramSwizzleAA(); const TileCheckerboardProgram* GetTileCheckerboardProgram(); const RenderPassProgram* GetRenderPassProgram(); const RenderPassProgramAA* GetRenderPassProgramAA(); const RenderPassMaskProgram* GetRenderPassMaskProgram(); const RenderPassMaskProgramAA* GetRenderPassMaskProgramAA(); const TextureProgram* GetTextureProgram(); const TextureProgramFlip* GetTextureProgramFlip(); const TextureIOSurfaceProgram* GetTextureIOSurfaceProgram(); const VideoYUVProgram* GetVideoYUVProgram(); const VideoStreamTextureProgram* GetVideoStreamTextureProgram(); const DebugBorderProgram* GetDebugBorderProgram(); const SolidColorProgram* GetSolidColorProgram(); const SolidColorProgramAA* GetSolidColorProgramAA(); scoped_ptr tile_program_; scoped_ptr tile_program_opaque_; scoped_ptr tile_program_aa_; scoped_ptr tile_program_swizzle_; scoped_ptr tile_program_swizzle_opaque_; scoped_ptr tile_program_swizzle_aa_; scoped_ptr tile_checkerboard_program_; scoped_ptr render_pass_program_; scoped_ptr render_pass_program_aa_; scoped_ptr render_pass_mask_program_; scoped_ptr render_pass_mask_program_aa_; scoped_ptr texture_program_; scoped_ptr texture_program_flip_; scoped_ptr texture_io_surface_program_; scoped_ptr video_yuv_program_; scoped_ptr video_stream_texture_program_; scoped_ptr debug_border_program_; scoped_ptr solid_color_program_; scoped_ptr solid_color_program_aa_; OutputSurface* output_surface_; WebKit::WebGraphicsContext3D* context_; gfx::Rect swap_buffer_rect_; gfx::Rect scissor_rect_; bool is_viewport_changed_; bool is_backbuffer_discarded_; bool discard_backbuffer_when_not_visible_; bool is_using_bind_uniform_; bool visible_; bool is_scissor_enabled_; bool blend_shadow_; unsigned program_shadow_; TexturedQuadDrawCache draw_cache_; scoped_ptr current_framebuffer_lock_; scoped_refptr last_swap_fence_; 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 } #endif // CC_OUTPUT_GL_RENDERER_H_