diff options
author | brianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-01 23:03:11 +0000 |
---|---|---|
committer | brianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-01 23:03:11 +0000 |
commit | 075d8aae89b630b505f97f437e665cf1968eb4c0 (patch) | |
tree | eb66ede0e1cb085f42500924e9e9fc8c564ffca5 /cc | |
parent | 58430f338d50e9df8ca7066652b347b1ef7ff52d (diff) | |
download | chromium_src-075d8aae89b630b505f97f437e665cf1968eb4c0.zip chromium_src-075d8aae89b630b505f97f437e665cf1968eb4c0.tar.gz chromium_src-075d8aae89b630b505f97f437e665cf1968eb4c0.tar.bz2 |
cc: Use highp precision for texture coords if available and needed
This fixes an earlier version of this patch that had a bug in
FragmentShaderRGBATexAlphaMask.
High precision is only used when the source is greater than N
pixels in any direction to prevent performance regressions. N is
determined based on the actual precision of mediump reported by
the driver.
BUG=183581
BUG=173747
Review URL: https://chromiumcodereview.appspot.com/12665005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@191692 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
28 files changed, 770 insertions, 373 deletions
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp index a32483e..7c6ee9c 100644 --- a/cc/cc_tests.gyp +++ b/cc/cc_tests.gyp @@ -18,6 +18,7 @@ 'scheduler/frame_rate_controller_unittest.cc', 'output/gl_renderer_unittest.cc', 'output/gl_renderer_pixeltest.cc', + 'output/shader_unittest.cc', 'base/hash_pair_unittest.cc', 'layers/heads_up_display_unittest.cc', 'animation/keyframed_animation_curve_unittest.cc', diff --git a/cc/debug/fake_web_graphics_context_3d.cc b/cc/debug/fake_web_graphics_context_3d.cc index c626eb1..d3ab18a 100644 --- a/cc/debug/fake_web_graphics_context_3d.cc +++ b/cc/debug/fake_web_graphics_context_3d.cc @@ -4,6 +4,7 @@ #include "cc/debug/fake_web_graphics_context_3d.h" +#include "base/logging.h" #include "third_party/khronos/GLES2/gl2.h" using WebKit::WGC3Dboolean; @@ -152,6 +153,49 @@ WebKit::WebString FakeWebGraphicsContext3D::getShaderInfoLog( return WebKit::WebString(); } +void FakeWebGraphicsContext3D::getShaderPrecisionFormat( + WebKit::WGC3Denum shadertype, + WebKit::WGC3Denum precisiontype, + WebKit::WGC3Dint* range, + WebKit::WGC3Dint* precision) { + // Return the minimum precision requirements of the GLES specificatin. + switch (precisiontype) { + case GL_LOW_INT: + range[0] = 8; + range[1] = 8; + *precision = 0; + break; + case GL_MEDIUM_INT: + range[0] = 10; + range[1] = 10; + *precision = 0; + break; + case GL_HIGH_INT: + range[0] = 16; + range[1] = 16; + *precision = 0; + break; + case GL_LOW_FLOAT: + range[0] = 8; + range[1] = 8; + *precision = 8; + break; + case GL_MEDIUM_FLOAT: + range[0] = 14; + range[1] = 14; + *precision = 10; + break; + case GL_HIGH_FLOAT: + range[0] = 62; + range[1] = 62; + *precision = 16; + break; + default: + NOTREACHED(); + break; + } +} + WebKit::WebString FakeWebGraphicsContext3D::getShaderSource( WebGLId shader) { return WebKit::WebString(); diff --git a/cc/debug/fake_web_graphics_context_3d.h b/cc/debug/fake_web_graphics_context_3d.h index 0fe10b8..f1c8525 100644 --- a/cc/debug/fake_web_graphics_context_3d.h +++ b/cc/debug/fake_web_graphics_context_3d.h @@ -289,7 +289,7 @@ class CC_EXPORT FakeWebGraphicsContext3D WebKit::WGC3Denum shadertype, WebKit::WGC3Denum precisiontype, WebKit::WGC3Dint* range, - WebKit::WGC3Dint* precision) {} + WebKit::WGC3Dint* precision); virtual WebKit::WebString getShaderSource(WebKit::WebGLId shader); virtual WebKit::WebString getString(WebKit::WGC3Denum name); virtual void getTexParameterfv( diff --git a/cc/layers/nine_patch_layer_unittest.cc b/cc/layers/nine_patch_layer_unittest.cc index 2f792a7..f120e51 100644 --- a/cc/layers/nine_patch_layer_unittest.cc +++ b/cc/layers/nine_patch_layer_unittest.cc @@ -100,7 +100,7 @@ TEST_F(NinePatchLayerTest, TriggerFullUploadOnceWhenChangingBitmap) { DebugScopedSetImplThread impl_thread(Proxy()); DebugScopedSetMainThreadBlocked main_thread_blocked(Proxy()); output_surface = CreateFakeOutputSurface(); - resource_provider = ResourceProvider::Create(output_surface.get()); + resource_provider = ResourceProvider::Create(output_surface.get(), 0); params.texture->AcquireBackingTexture(resource_provider.get()); ASSERT_TRUE(params.texture->have_backing_texture()); } diff --git a/cc/layers/tiled_layer_unittest.cc b/cc/layers/tiled_layer_unittest.cc index 6a8c5b7..0f64d3c 100644 --- a/cc/layers/tiled_layer_unittest.cc +++ b/cc/layers/tiled_layer_unittest.cc @@ -65,7 +65,7 @@ class TiledLayerTest : public testing::Test { DebugScopedSetImplThreadAndMainThreadBlocked impl_thread_and_main_thread_blocked(proxy_); - resource_provider_ = ResourceProvider::Create(output_surface_.get()); + resource_provider_ = ResourceProvider::Create(output_surface_.get(), 0); host_impl_ = make_scoped_ptr(new FakeLayerTreeHostImpl(proxy_)); } diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index 9f4c6f9..eaeb31d 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -85,9 +85,10 @@ bool NeedsIOSurfaceReadbackWorkaround() { scoped_ptr<GLRenderer> GLRenderer::Create(RendererClient* client, OutputSurface* output_surface, - ResourceProvider* resource_provider) { - scoped_ptr<GLRenderer> renderer( - new GLRenderer(client, output_surface, resource_provider)); + ResourceProvider* resource_provider, + int highp_threshold_min) { + scoped_ptr<GLRenderer> renderer(new GLRenderer( + client, output_surface, resource_provider, highp_threshold_min)); if (!renderer->Initialize()) return scoped_ptr<GLRenderer>(); @@ -96,7 +97,8 @@ scoped_ptr<GLRenderer> GLRenderer::Create(RendererClient* client, GLRenderer::GLRenderer(RendererClient* client, OutputSurface* output_surface, - ResourceProvider* resource_provider) + ResourceProvider* resource_provider, + int highp_threshold_min) : DirectRenderer(client, resource_provider), offscreen_framebuffer_id_(0), shared_geometry_quad_(gfx::RectF(-0.5f, -0.5f, 1.0f, 1.0f)), @@ -108,6 +110,7 @@ GLRenderer::GLRenderer(RendererClient* client, is_using_bind_uniform_(false), visible_(true), is_scissor_enabled_(false), + highp_threshold_min_(highp_threshold_min), on_demand_tile_raster_resource_id_(0) { DCHECK(context_); } @@ -747,6 +750,10 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, GL_LINEAR)); } + TexCoordPrecision texCoordPrecision = TexCoordPrecisionRequired( + context_, highp_threshold_min_, + quad->shared_quad_state->visible_content_rect.bottom_right()); + int shader_quad_location = -1; int shader_edge_location = -1; int shader_mask_sampler_location = -1; @@ -760,7 +767,8 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, int shader_tex_scale_location = -1; if (use_aa && mask_texture_id && !use_color_matrix) { - const RenderPassMaskProgramAA* program = GetRenderPassMaskProgramAA(); + const RenderPassMaskProgramAA* program = + GetRenderPassMaskProgramAA(texCoordPrecision); SetUseProgram(program->program()); GLC(Context(), Context()->uniform1i(program->fragment_shader().sampler_location(), 0)); @@ -777,7 +785,8 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, shader_alpha_location = program->fragment_shader().alpha_location(); shader_tex_scale_location = program->vertex_shader().tex_scale_location(); } else if (!use_aa && mask_texture_id && !use_color_matrix) { - const RenderPassMaskProgram* program = GetRenderPassMaskProgram(); + const RenderPassMaskProgram* program = + GetRenderPassMaskProgram(texCoordPrecision); SetUseProgram(program->program()); GLC(Context(), Context()->uniform1i(program->fragment_shader().sampler_location(), 0)); @@ -793,7 +802,8 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, shader_tex_transform_location = program->vertex_shader().tex_transform_location(); } else if (use_aa && !mask_texture_id && !use_color_matrix) { - const RenderPassProgramAA* program = GetRenderPassProgramAA(); + const RenderPassProgramAA* program = + GetRenderPassProgramAA(texCoordPrecision); SetUseProgram(program->program()); GLC(Context(), Context()->uniform1i(program->fragment_shader().sampler_location(), 0)); @@ -805,7 +815,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, shader_tex_scale_location = program->vertex_shader().tex_scale_location(); } else if (use_aa && mask_texture_id && use_color_matrix) { const RenderPassMaskColorMatrixProgramAA* program = - GetRenderPassMaskColorMatrixProgramAA(); + GetRenderPassMaskColorMatrixProgramAA(texCoordPrecision); SetUseProgram(program->program()); GLC(Context(), Context()->uniform1i(program->fragment_shader().sampler_location(), 0)); @@ -827,7 +837,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, program->fragment_shader().color_offset_location(); } else if (use_aa && !mask_texture_id && use_color_matrix) { const RenderPassColorMatrixProgramAA* program = - GetRenderPassColorMatrixProgramAA(); + GetRenderPassColorMatrixProgramAA(texCoordPrecision); SetUseProgram(program->program()); GLC(Context(), Context()->uniform1i(program->fragment_shader().sampler_location(), 0)); @@ -843,7 +853,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, program->fragment_shader().color_offset_location(); } else if (!use_aa && mask_texture_id && use_color_matrix) { const RenderPassMaskColorMatrixProgram* program = - GetRenderPassMaskColorMatrixProgram(); + GetRenderPassMaskColorMatrixProgram(texCoordPrecision); SetUseProgram(program->program()); GLC(Context(), Context()->uniform1i(program->fragment_shader().sampler_location(), 0)); @@ -864,7 +874,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, program->fragment_shader().color_offset_location(); } else if (!use_aa && !mask_texture_id && use_color_matrix) { const RenderPassColorMatrixProgram* program = - GetRenderPassColorMatrixProgram(); + GetRenderPassColorMatrixProgram(texCoordPrecision); SetUseProgram(program->program()); GLC(Context(), Context()->uniform1i(program->fragment_shader().sampler_location(), 0)); @@ -878,7 +888,8 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, shader_color_offset_location = program->fragment_shader().color_offset_location(); } else { - const RenderPassProgram* program = GetRenderPassProgram(); + const RenderPassProgram* program = + GetRenderPassProgram(texCoordPrecision); SetUseProgram(program->program()); GLC(Context(), Context()->uniform1i(program->fragment_shader().sampler_location(), 0)); @@ -1211,6 +1222,11 @@ void GLRenderer::DrawContentQuad(const DrawingFrame* frame, float vertex_tex_scale_x = tile_rect.width() / clamp_geom_rect.width(); float vertex_tex_scale_y = tile_rect.height() / clamp_geom_rect.height(); + // We assume we do not need highp texture coordinates for tiles. + // Make sure that assumption is correct here. + DCHECK_EQ(TexCoordPrecisionMedium, TexCoordPrecisionRequired( + context_, highp_threshold_min_, quad->texture_size)); + // Map to normalized texture coordinates. gfx::Size texture_size = quad->texture_size; float fragment_tex_translate_x = clamp_tex_rect.x() / texture_size.width(); @@ -1319,7 +1335,11 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame, const YUVVideoDrawQuad* quad) { SetBlendEnabled(quad->ShouldDrawWithBlending()); - const VideoYUVProgram* program = GetVideoYUVProgram(); + TexCoordPrecision texCoordPrecision = TexCoordPrecisionRequired( + context_, highp_threshold_min_, + quad->shared_quad_state->visible_content_rect.bottom_right()); + + const VideoYUVProgram* program = GetVideoYUVProgram(texCoordPrecision); DCHECK(program && (program->initialized() || IsContextLost())); const VideoLayerImpl::FramePlane& y_plane = quad->y_plane; @@ -1391,7 +1411,12 @@ void GLRenderer::DrawStreamVideoQuad(const DrawingFrame* frame, DCHECK(capabilities_.using_egl_image); - const VideoStreamTextureProgram* program = GetVideoStreamTextureProgram(); + TexCoordPrecision texCoordPrecision = TexCoordPrecisionRequired( + context_, highp_threshold_min_, + quad->shared_quad_state->visible_content_rect.bottom_right()); + + const VideoStreamTextureProgram* program = + GetVideoStreamTextureProgram(texCoordPrecision); SetUseProgram(program->program()); ToGLMatrix(&gl_matrix[0], quad->matrix); @@ -1557,12 +1582,16 @@ void GLRenderer::FlushTextureQuadCache() { void GLRenderer::EnqueueTextureQuad(const DrawingFrame* frame, const TextureDrawQuad* quad) { + TexCoordPrecision texCoordPrecision = TexCoordPrecisionRequired( + context_, highp_threshold_min_, + quad->shared_quad_state->visible_content_rect.bottom_right()); + // Choose the correct texture program binding TexTransformTextureProgramBinding binding; if (quad->flipped) - binding.Set(GetTextureProgramFlip(), Context()); + binding.Set(GetTextureProgramFlip(texCoordPrecision), Context()); else - binding.Set(GetTextureProgram(), Context()); + binding.Set(GetTextureProgram(texCoordPrecision), Context()); int resource_id = quad->resource_id; @@ -1608,11 +1637,15 @@ void GLRenderer::EnqueueTextureQuad(const DrawingFrame* frame, void GLRenderer::DrawTextureQuad(const DrawingFrame* frame, const TextureDrawQuad* quad) { + TexCoordPrecision texCoordPrecision = TexCoordPrecisionRequired( + context_, highp_threshold_min_, + quad->shared_quad_state->visible_content_rect.bottom_right()); + TexTransformTextureProgramBinding binding; if (quad->flipped) - binding.Set(GetTextureProgramFlip(), Context()); + binding.Set(GetTextureProgramFlip(texCoordPrecision), Context()); else - binding.Set(GetTextureProgram(), Context()); + binding.Set(GetTextureProgram(texCoordPrecision), Context()); SetUseProgram(binding.program_id); GLC(Context(), Context()->uniform1i(binding.sampler_location, 0)); gfx::PointF uv0 = quad->uv_top_left; @@ -1658,8 +1691,12 @@ void GLRenderer::DrawIOSurfaceQuad(const DrawingFrame* frame, const IOSurfaceDrawQuad* quad) { SetBlendEnabled(quad->ShouldDrawWithBlending()); + TexCoordPrecision texCoordPrecision = TexCoordPrecisionRequired( + context_, highp_threshold_min_, + quad->shared_quad_state->visible_content_rect.bottom_right()); + TexTransformTextureProgramBinding binding; - binding.Set(GetTextureIOSurfaceProgram(), Context()); + binding.Set(GetTextureIOSurfaceProgram(texCoordPrecision), Context()); SetUseProgram(binding.program_id); GLC(Context(), Context()->uniform1i(binding.sampler_location, 0)); @@ -1792,7 +1829,9 @@ void GLRenderer::CopyTextureToFramebuffer(const DrawingFrame* frame, int texture_id, gfx::Rect rect, const gfx::Transform& draw_matrix) { - const RenderPassProgram* program = GetRenderPassProgram(); + TexCoordPrecision texCoordPrecision = TexCoordPrecisionRequired( + context_, highp_threshold_min_, rect.bottom_right()); + const RenderPassProgram* program = GetRenderPassProgram(texCoordPrecision); GLC(Context(), Context()->bindTexture(GL_TEXTURE_2D, texture_id)); @@ -2129,11 +2168,16 @@ bool GLRenderer::InitializeSharedObjects() { // We will always need these programs to render, so create the programs // eagerly so that the shader compilation can start while we do other work. // Other programs are created lazily on first access. - shared_geometry_ = - make_scoped_ptr(new GeometryBinding(context_, QuadVertexRect())); - render_pass_program_ = make_scoped_ptr(new RenderPassProgram(context_)); - tile_program_ = make_scoped_ptr(new TileProgram(context_)); - tile_program_opaque_ = make_scoped_ptr(new TileProgramOpaque(context_)); + shared_geometry_ = make_scoped_ptr( + new GeometryBinding(context_, QuadVertexRect())); + render_pass_program_ = make_scoped_ptr( + new RenderPassProgram(context_, TexCoordPrecisionMedium)); + render_pass_program_highp_ = make_scoped_ptr( + new RenderPassProgram(context_, TexCoordPrecisionHigh)); + tile_program_ = make_scoped_ptr( + new TileProgram(context_, TexCoordPrecisionMedium)); + tile_program_opaque_ = make_scoped_ptr( + new TileProgramOpaque(context_, TexCoordPrecisionMedium)); GLC(context_, context_->flush()); @@ -2142,10 +2186,9 @@ bool GLRenderer::InitializeSharedObjects() { const GLRenderer::TileCheckerboardProgram* GLRenderer::GetTileCheckerboardProgram() { - if (!tile_checkerboard_program_) { - tile_checkerboard_program_ = - make_scoped_ptr(new TileCheckerboardProgram(context_)); - } + if (!tile_checkerboard_program_) + tile_checkerboard_program_ = make_scoped_ptr( + new TileCheckerboardProgram(context_, TexCoordPrecisionNA)); if (!tile_checkerboard_program_->initialized()) { TRACE_EVENT0("cc", "GLRenderer::checkerboardProgram::initalize"); tile_checkerboard_program_->Initialize(context_, is_using_bind_uniform_); @@ -2155,7 +2198,8 @@ GLRenderer::GetTileCheckerboardProgram() { const GLRenderer::DebugBorderProgram* GLRenderer::GetDebugBorderProgram() { if (!debug_border_program_) - debug_border_program_ = make_scoped_ptr(new DebugBorderProgram(context_)); + debug_border_program_ = make_scoped_ptr( + new DebugBorderProgram(context_, TexCoordPrecisionNA)); if (!debug_border_program_->initialized()) { TRACE_EVENT0("cc", "GLRenderer::debugBorderProgram::initialize"); debug_border_program_->Initialize(context_, is_using_bind_uniform_); @@ -2165,7 +2209,8 @@ const GLRenderer::DebugBorderProgram* GLRenderer::GetDebugBorderProgram() { const GLRenderer::SolidColorProgram* GLRenderer::GetSolidColorProgram() { if (!solid_color_program_) - solid_color_program_ = make_scoped_ptr(new SolidColorProgram(context_)); + solid_color_program_ = make_scoped_ptr( + new SolidColorProgram(context_, TexCoordPrecisionNA)); if (!solid_color_program_->initialized()) { TRACE_EVENT0("cc", "GLRenderer::solidColorProgram::initialize"); solid_color_program_->Initialize(context_, is_using_bind_uniform_); @@ -2176,7 +2221,7 @@ const GLRenderer::SolidColorProgram* GLRenderer::GetSolidColorProgram() { const GLRenderer::SolidColorProgramAA* GLRenderer::GetSolidColorProgramAA() { if (!solid_color_program_aa_) { solid_color_program_aa_ = - make_scoped_ptr(new SolidColorProgramAA(context_)); + make_scoped_ptr(new SolidColorProgramAA(context_, TexCoordPrecisionNA)); } if (!solid_color_program_aa_->initialized()) { TRACE_EVENT0("cc", "GLRenderer::solidColorProgramAA::initialize"); @@ -2185,103 +2230,128 @@ const GLRenderer::SolidColorProgramAA* GLRenderer::GetSolidColorProgramAA() { return solid_color_program_aa_.get(); } -const GLRenderer::RenderPassProgram* GLRenderer::GetRenderPassProgram() { - DCHECK(render_pass_program_); - if (!render_pass_program_->initialized()) { +const GLRenderer::RenderPassProgram* GLRenderer::GetRenderPassProgram( + TexCoordPrecision precision) { + scoped_ptr<RenderPassProgram> &program = + (precision == TexCoordPrecisionHigh) ? render_pass_program_highp_ + : render_pass_program_; + DCHECK(program); + if (!program->initialized()) { TRACE_EVENT0("cc", "GLRenderer::renderPassProgram::initialize"); - render_pass_program_->Initialize(context_, is_using_bind_uniform_); + program->Initialize(context_, is_using_bind_uniform_); } - return render_pass_program_.get(); -} - -const GLRenderer::RenderPassProgramAA* GLRenderer::GetRenderPassProgramAA() { - if (!render_pass_program_aa_) - render_pass_program_aa_ = - make_scoped_ptr(new RenderPassProgramAA(context_)); - if (!render_pass_program_aa_->initialized()) { + return program.get(); +} + +const GLRenderer::RenderPassProgramAA* GLRenderer::GetRenderPassProgramAA( + TexCoordPrecision precision) { + scoped_ptr<RenderPassProgramAA> &program = + (precision == TexCoordPrecisionHigh) ? render_pass_program_aa_highp_ + : render_pass_program_aa_; + if (!program) + program = + make_scoped_ptr(new RenderPassProgramAA(context_, precision)); + if (!program->initialized()) { TRACE_EVENT0("cc", "GLRenderer::renderPassProgramAA::initialize"); - render_pass_program_aa_->Initialize(context_, is_using_bind_uniform_); + program->Initialize(context_, is_using_bind_uniform_); } - return render_pass_program_aa_.get(); + return program.get(); } const GLRenderer::RenderPassMaskProgram* -GLRenderer::GetRenderPassMaskProgram() { - if (!render_pass_mask_program_) - render_pass_mask_program_ = - make_scoped_ptr(new RenderPassMaskProgram(context_)); - if (!render_pass_mask_program_->initialized()) { +GLRenderer::GetRenderPassMaskProgram(TexCoordPrecision precision) { + scoped_ptr<RenderPassMaskProgram> &program = + (precision == TexCoordPrecisionHigh) ? render_pass_mask_program_highp_ + : render_pass_mask_program_; + if (!program) + program = make_scoped_ptr(new RenderPassMaskProgram(context_, precision)); + if (!program->initialized()) { TRACE_EVENT0("cc", "GLRenderer::renderPassMaskProgram::initialize"); - render_pass_mask_program_->Initialize(context_, is_using_bind_uniform_); + program->Initialize(context_, is_using_bind_uniform_); } - return render_pass_mask_program_.get(); + return program.get(); } const GLRenderer::RenderPassMaskProgramAA* -GLRenderer::GetRenderPassMaskProgramAA() { - if (!render_pass_mask_program_aa_) - render_pass_mask_program_aa_ = - make_scoped_ptr(new RenderPassMaskProgramAA(context_)); - if (!render_pass_mask_program_aa_->initialized()) { +GLRenderer::GetRenderPassMaskProgramAA(TexCoordPrecision precision) { + scoped_ptr<RenderPassMaskProgramAA> &program = + (precision == TexCoordPrecisionHigh) ? render_pass_mask_program_aa_highp_ + : render_pass_mask_program_aa_; + if (!program) + program = + make_scoped_ptr(new RenderPassMaskProgramAA(context_, precision)); + if (!program->initialized()) { TRACE_EVENT0("cc", "GLRenderer::renderPassMaskProgramAA::initialize"); - render_pass_mask_program_aa_->Initialize(context_, is_using_bind_uniform_); + program->Initialize(context_, is_using_bind_uniform_); } - return render_pass_mask_program_aa_.get(); + return program.get(); } const GLRenderer::RenderPassColorMatrixProgram* -GLRenderer::GetRenderPassColorMatrixProgram() { - if (!render_pass_color_matrix_program_) - render_pass_color_matrix_program_ = - make_scoped_ptr(new RenderPassColorMatrixProgram(context_)); - if (!render_pass_color_matrix_program_->initialized()) { +GLRenderer::GetRenderPassColorMatrixProgram(TexCoordPrecision precision) { + scoped_ptr<RenderPassColorMatrixProgram> &program = + (precision == TexCoordPrecisionHigh) ? + render_pass_color_matrix_program_highp_ : + render_pass_color_matrix_program_; + if (!program) + program = make_scoped_ptr( + new RenderPassColorMatrixProgram(context_, precision)); + if (!program->initialized()) { TRACE_EVENT0("cc", "GLRenderer::renderPassColorMatrixProgram::initialize"); - render_pass_color_matrix_program_->Initialize(context_, - is_using_bind_uniform_); + program->Initialize(context_, is_using_bind_uniform_); } - return render_pass_color_matrix_program_.get(); + return program.get(); } const GLRenderer::RenderPassColorMatrixProgramAA* -GLRenderer::GetRenderPassColorMatrixProgramAA() { - if (!render_pass_color_matrix_program_aa_) - render_pass_color_matrix_program_aa_ = - make_scoped_ptr(new RenderPassColorMatrixProgramAA(context_)); - if (!render_pass_color_matrix_program_aa_->initialized()) { +GLRenderer::GetRenderPassColorMatrixProgramAA(TexCoordPrecision precision) { + scoped_ptr<RenderPassColorMatrixProgramAA> &program = + (precision == TexCoordPrecisionHigh) ? + render_pass_color_matrix_program_aa_highp_ : + render_pass_color_matrix_program_aa_; + if (!program) + program = make_scoped_ptr( + new RenderPassColorMatrixProgramAA(context_, precision)); + if (!program->initialized()) { TRACE_EVENT0("cc", "GLRenderer::renderPassColorMatrixProgramAA::initialize"); - render_pass_color_matrix_program_aa_->Initialize(context_, - is_using_bind_uniform_); + program->Initialize(context_, is_using_bind_uniform_); } - return render_pass_color_matrix_program_aa_.get(); + return program.get(); } const GLRenderer::RenderPassMaskColorMatrixProgram* -GLRenderer::GetRenderPassMaskColorMatrixProgram() { - if (!render_pass_mask_color_matrix_program_) - render_pass_mask_color_matrix_program_ = - make_scoped_ptr(new RenderPassMaskColorMatrixProgram(context_)); - if (!render_pass_mask_color_matrix_program_->initialized()) { +GLRenderer::GetRenderPassMaskColorMatrixProgram(TexCoordPrecision precision) { + scoped_ptr<RenderPassMaskColorMatrixProgram> &program = + (precision == TexCoordPrecisionHigh) ? + render_pass_mask_color_matrix_program_highp_ : + render_pass_mask_color_matrix_program_; + if (!program) + program = make_scoped_ptr( + new RenderPassMaskColorMatrixProgram(context_, precision)); + if (!program->initialized()) { TRACE_EVENT0("cc", "GLRenderer::renderPassMaskColorMatrixProgram::initialize"); - render_pass_mask_color_matrix_program_->Initialize(context_, - is_using_bind_uniform_); + program->Initialize(context_, is_using_bind_uniform_); } - return render_pass_mask_color_matrix_program_.get(); + return program.get(); } const GLRenderer::RenderPassMaskColorMatrixProgramAA* -GLRenderer::GetRenderPassMaskColorMatrixProgramAA() { - if (!render_pass_mask_color_matrix_program_aa_) - render_pass_mask_color_matrix_program_aa_ = - make_scoped_ptr(new RenderPassMaskColorMatrixProgramAA(context_)); - if (!render_pass_mask_color_matrix_program_aa_->initialized()) { +GLRenderer::GetRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision) { + scoped_ptr<RenderPassMaskColorMatrixProgramAA> &program = + (precision == TexCoordPrecisionHigh) ? + render_pass_mask_color_matrix_program_aa_highp_ : + render_pass_mask_color_matrix_program_aa_; + if (!program) + program = make_scoped_ptr( + new RenderPassMaskColorMatrixProgramAA(context_, precision)); + if (!program->initialized()) { TRACE_EVENT0("cc", "GLRenderer::renderPassMaskColorMatrixProgramAA::initialize"); - render_pass_mask_color_matrix_program_aa_->Initialize( - context_, is_using_bind_uniform_); + program->Initialize(context_, is_using_bind_uniform_); } - return render_pass_mask_color_matrix_program_aa_.get(); + return program.get(); } const GLRenderer::TileProgram* GLRenderer::GetTileProgram() { @@ -2304,7 +2374,8 @@ const GLRenderer::TileProgramOpaque* GLRenderer::GetTileProgramOpaque() { const GLRenderer::TileProgramAA* GLRenderer::GetTileProgramAA() { if (!tile_program_aa_) - tile_program_aa_ = make_scoped_ptr(new TileProgramAA(context_)); + tile_program_aa_ = make_scoped_ptr( + new TileProgramAA(context_, TexCoordPrecisionMedium)); if (!tile_program_aa_->initialized()) { TRACE_EVENT0("cc", "GLRenderer::tileProgramAA::initialize"); tile_program_aa_->Initialize(context_, is_using_bind_uniform_); @@ -2314,7 +2385,8 @@ const GLRenderer::TileProgramAA* GLRenderer::GetTileProgramAA() { const GLRenderer::TileProgramSwizzle* GLRenderer::GetTileProgramSwizzle() { if (!tile_program_swizzle_) - tile_program_swizzle_ = make_scoped_ptr(new TileProgramSwizzle(context_)); + tile_program_swizzle_ = make_scoped_ptr( + new TileProgramSwizzle(context_, TexCoordPrecisionMedium)); if (!tile_program_swizzle_->initialized()) { TRACE_EVENT0("cc", "GLRenderer::tileProgramSwizzle::initialize"); tile_program_swizzle_->Initialize(context_, is_using_bind_uniform_); @@ -2325,8 +2397,8 @@ const GLRenderer::TileProgramSwizzle* GLRenderer::GetTileProgramSwizzle() { const GLRenderer::TileProgramSwizzleOpaque* GLRenderer::GetTileProgramSwizzleOpaque() { if (!tile_program_swizzle_opaque_) - tile_program_swizzle_opaque_ = - make_scoped_ptr(new TileProgramSwizzleOpaque(context_)); + tile_program_swizzle_opaque_ = make_scoped_ptr( + new TileProgramSwizzleOpaque(context_, TexCoordPrecisionMedium)); if (!tile_program_swizzle_opaque_->initialized()) { TRACE_EVENT0("cc", "GLRenderer::tileProgramSwizzleOpaque::initialize"); tile_program_swizzle_opaque_->Initialize(context_, is_using_bind_uniform_); @@ -2336,8 +2408,8 @@ GLRenderer::GetTileProgramSwizzleOpaque() { const GLRenderer::TileProgramSwizzleAA* GLRenderer::GetTileProgramSwizzleAA() { if (!tile_program_swizzle_aa_) - tile_program_swizzle_aa_ = - make_scoped_ptr(new TileProgramSwizzleAA(context_)); + tile_program_swizzle_aa_ = make_scoped_ptr( + new TileProgramSwizzleAA(context_, TexCoordPrecisionMedium)); if (!tile_program_swizzle_aa_->initialized()) { TRACE_EVENT0("cc", "GLRenderer::tileProgramSwizzleAA::initialize"); tile_program_swizzle_aa_->Initialize(context_, is_using_bind_uniform_); @@ -2345,60 +2417,78 @@ const GLRenderer::TileProgramSwizzleAA* GLRenderer::GetTileProgramSwizzleAA() { return tile_program_swizzle_aa_.get(); } -const GLRenderer::TextureProgram* GLRenderer::GetTextureProgram() { - if (!texture_program_) - texture_program_ = make_scoped_ptr(new TextureProgram(context_)); - if (!texture_program_->initialized()) { +const GLRenderer::TextureProgram* GLRenderer::GetTextureProgram( + TexCoordPrecision precision) { + scoped_ptr<TextureProgram> &program = + (precision == TexCoordPrecisionHigh) ? texture_program_highp_ + : texture_program_; + if (!program) + program = make_scoped_ptr(new TextureProgram(context_, precision)); + if (!program->initialized()) { TRACE_EVENT0("cc", "GLRenderer::textureProgram::initialize"); - texture_program_->Initialize(context_, is_using_bind_uniform_); + program->Initialize(context_, is_using_bind_uniform_); } - return texture_program_.get(); + return program.get(); } -const GLRenderer::TextureProgramFlip* GLRenderer::GetTextureProgramFlip() { - if (!texture_program_flip_) - texture_program_flip_ = make_scoped_ptr(new TextureProgramFlip(context_)); - if (!texture_program_flip_->initialized()) { +const GLRenderer::TextureProgramFlip* GLRenderer::GetTextureProgramFlip( + TexCoordPrecision precision) { + scoped_ptr<TextureProgramFlip> &program = + (precision == TexCoordPrecisionHigh) ? texture_program_flip_highp_ + : texture_program_flip_; + if (!program) + program = make_scoped_ptr(new TextureProgramFlip(context_, precision)); + if (!program->initialized()) { TRACE_EVENT0("cc", "GLRenderer::textureProgramFlip::initialize"); - texture_program_flip_->Initialize(context_, is_using_bind_uniform_); + program->Initialize(context_, is_using_bind_uniform_); } - return texture_program_flip_.get(); + return program.get(); } const GLRenderer::TextureIOSurfaceProgram* -GLRenderer::GetTextureIOSurfaceProgram() { - if (!texture_io_surface_program_) - texture_io_surface_program_ = - make_scoped_ptr(new TextureIOSurfaceProgram(context_)); - if (!texture_io_surface_program_->initialized()) { +GLRenderer::GetTextureIOSurfaceProgram(TexCoordPrecision precision) { + scoped_ptr<TextureIOSurfaceProgram> &program = + (precision == TexCoordPrecisionHigh) ? texture_io_surface_program_highp_ + : texture_io_surface_program_; + if (!program) + program = + make_scoped_ptr(new TextureIOSurfaceProgram(context_, precision)); + if (!program->initialized()) { TRACE_EVENT0("cc", "GLRenderer::textureIOSurfaceProgram::initialize"); - texture_io_surface_program_->Initialize(context_, is_using_bind_uniform_); + program->Initialize(context_, is_using_bind_uniform_); } - return texture_io_surface_program_.get(); + return program.get(); } -const GLRenderer::VideoYUVProgram* GLRenderer::GetVideoYUVProgram() { - if (!video_yuv_program_) - video_yuv_program_ = make_scoped_ptr(new VideoYUVProgram(context_)); - if (!video_yuv_program_->initialized()) { +const GLRenderer::VideoYUVProgram* GLRenderer::GetVideoYUVProgram( + TexCoordPrecision precision) { + scoped_ptr<VideoYUVProgram> &program = + (precision == TexCoordPrecisionHigh) ? video_yuv_program_highp_ + : video_yuv_program_; + if (!program) + program = make_scoped_ptr(new VideoYUVProgram(context_, precision)); + if (!program->initialized()) { TRACE_EVENT0("cc", "GLRenderer::videoYUVProgram::initialize"); - video_yuv_program_->Initialize(context_, is_using_bind_uniform_); + program->Initialize(context_, is_using_bind_uniform_); } - return video_yuv_program_.get(); + return program.get(); } const GLRenderer::VideoStreamTextureProgram* -GLRenderer::GetVideoStreamTextureProgram() { +GLRenderer::GetVideoStreamTextureProgram(TexCoordPrecision precision) { if (!Capabilities().using_egl_image) return NULL; - if (!video_stream_texture_program_) - video_stream_texture_program_ = - make_scoped_ptr(new VideoStreamTextureProgram(context_)); - if (!video_stream_texture_program_->initialized()) { + scoped_ptr<VideoStreamTextureProgram> &program = + (precision == TexCoordPrecisionHigh) ? video_stream_texture_program_highp_ + : video_stream_texture_program_; + if (!program) + program = + make_scoped_ptr(new VideoStreamTextureProgram(context_, precision)); + if (!program->initialized()) { TRACE_EVENT0("cc", "GLRenderer::streamTextureProgram::initialize"); - video_stream_texture_program_->Initialize(context_, is_using_bind_uniform_); + program->Initialize(context_, is_using_bind_uniform_); } - return video_stream_texture_program_.get(); + return program.get(); } void GLRenderer::CleanupSharedObjects() { @@ -2438,6 +2528,23 @@ void GLRenderer::CleanupSharedObjects() { if (render_pass_mask_color_matrix_program_) render_pass_mask_color_matrix_program_->Cleanup(context_); + if (render_pass_mask_program_highp_) + render_pass_mask_program_highp_->Cleanup(context_); + if (render_pass_program_highp_) + render_pass_program_highp_->Cleanup(context_); + if (render_pass_mask_program_aa_highp_) + render_pass_mask_program_aa_highp_->Cleanup(context_); + if (render_pass_program_aa_highp_) + render_pass_program_aa_highp_->Cleanup(context_); + if (render_pass_color_matrix_program_highp_) + render_pass_color_matrix_program_highp_->Cleanup(context_); + if (render_pass_mask_color_matrix_program_aa_highp_) + render_pass_mask_color_matrix_program_aa_highp_->Cleanup(context_); + if (render_pass_color_matrix_program_aa_highp_) + render_pass_color_matrix_program_aa_highp_->Cleanup(context_); + if (render_pass_mask_color_matrix_program_highp_) + render_pass_mask_color_matrix_program_highp_->Cleanup(context_); + if (texture_program_) texture_program_->Cleanup(context_); if (texture_program_flip_) @@ -2445,11 +2552,23 @@ void GLRenderer::CleanupSharedObjects() { if (texture_io_surface_program_) texture_io_surface_program_->Cleanup(context_); + if (texture_program_highp_) + texture_program_highp_->Cleanup(context_); + if (texture_program_flip_highp_) + texture_program_flip_highp_->Cleanup(context_); + if (texture_io_surface_program_highp_) + texture_io_surface_program_highp_->Cleanup(context_); + if (video_yuv_program_) video_yuv_program_->Cleanup(context_); if (video_stream_texture_program_) video_stream_texture_program_->Cleanup(context_); + if (video_yuv_program_highp_) + video_yuv_program_highp_->Cleanup(context_); + if (video_stream_texture_program_highp_) + video_stream_texture_program_highp_->Cleanup(context_); + if (debug_border_program_) debug_border_program_->Cleanup(context_); if (solid_color_program_) diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h index fee6db0..b5f8a46 100644 --- a/cc/output/gl_renderer.h +++ b/cc/output/gl_renderer.h @@ -45,7 +45,8 @@ class CC_EXPORT GLRenderer public: static scoped_ptr<GLRenderer> Create(RendererClient* client, OutputSurface* output_surface, - ResourceProvider* resource_provider); + ResourceProvider* resource_provider, + int highp_threshold_min); virtual ~GLRenderer(); @@ -83,7 +84,8 @@ class CC_EXPORT GLRenderer protected: GLRenderer(RendererClient* client, OutputSurface* output_surface, - ResourceProvider* resource_provider); + ResourceProvider* resource_provider, + int highp_threshold_min); bool IsBackbufferDiscarded() const { return is_backbuffer_discarded_; } bool Initialize(); @@ -281,22 +283,34 @@ class CC_EXPORT GLRenderer const TileProgramSwizzleAA* GetTileProgramSwizzleAA(); const TileCheckerboardProgram* GetTileCheckerboardProgram(); - const RenderPassProgram* GetRenderPassProgram(); - const RenderPassProgramAA* GetRenderPassProgramAA(); - const RenderPassMaskProgram* GetRenderPassMaskProgram(); - const RenderPassMaskProgramAA* GetRenderPassMaskProgramAA(); - const RenderPassColorMatrixProgram* GetRenderPassColorMatrixProgram(); - const RenderPassColorMatrixProgramAA* GetRenderPassColorMatrixProgramAA(); - const RenderPassMaskColorMatrixProgram* GetRenderPassMaskColorMatrixProgram(); + 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(); + GetRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision); - const TextureProgram* GetTextureProgram(); - const TextureProgramFlip* GetTextureProgramFlip(); - const TextureIOSurfaceProgram* GetTextureIOSurfaceProgram(); + const TextureProgram* GetTextureProgram( + TexCoordPrecision precision); + const TextureProgramFlip* GetTextureProgramFlip( + TexCoordPrecision precision); + const TextureIOSurfaceProgram* GetTextureIOSurfaceProgram( + TexCoordPrecision precision); - const VideoYUVProgram* GetVideoYUVProgram(); - const VideoStreamTextureProgram* GetVideoStreamTextureProgram(); + const VideoYUVProgram* GetVideoYUVProgram( + TexCoordPrecision precision); + const VideoStreamTextureProgram* GetVideoStreamTextureProgram( + TexCoordPrecision precision); const DebugBorderProgram* GetDebugBorderProgram(); const SolidColorProgram* GetSolidColorProgram(); @@ -314,6 +328,10 @@ class CC_EXPORT GLRenderer scoped_ptr<TextureProgramFlip> texture_program_flip_; scoped_ptr<TextureIOSurfaceProgram> texture_io_surface_program_; + scoped_ptr<TextureProgram> texture_program_highp_; + scoped_ptr<TextureProgramFlip> texture_program_flip_highp_; + scoped_ptr<TextureIOSurfaceProgram> texture_io_surface_program_highp_; + scoped_ptr<RenderPassProgram> render_pass_program_; scoped_ptr<RenderPassProgramAA> render_pass_program_aa_; scoped_ptr<RenderPassMaskProgram> render_pass_mask_program_; @@ -326,9 +344,25 @@ class CC_EXPORT GLRenderer scoped_ptr<RenderPassMaskColorMatrixProgramAA> render_pass_mask_color_matrix_program_aa_; + scoped_ptr<RenderPassProgram> render_pass_program_highp_; + scoped_ptr<RenderPassProgramAA> render_pass_program_aa_highp_; + scoped_ptr<RenderPassMaskProgram> render_pass_mask_program_highp_; + scoped_ptr<RenderPassMaskProgramAA> render_pass_mask_program_aa_highp_; + scoped_ptr<RenderPassColorMatrixProgram> + render_pass_color_matrix_program_highp_; + scoped_ptr<RenderPassColorMatrixProgramAA> + render_pass_color_matrix_program_aa_highp_; + scoped_ptr<RenderPassMaskColorMatrixProgram> + render_pass_mask_color_matrix_program_highp_; + scoped_ptr<RenderPassMaskColorMatrixProgramAA> + render_pass_mask_color_matrix_program_aa_highp_; + scoped_ptr<VideoYUVProgram> video_yuv_program_; scoped_ptr<VideoStreamTextureProgram> video_stream_texture_program_; + scoped_ptr<VideoYUVProgram> video_yuv_program_highp_; + scoped_ptr<VideoStreamTextureProgram> video_stream_texture_program_highp_; + scoped_ptr<DebugBorderProgram> debug_border_program_; scoped_ptr<SolidColorProgram> solid_color_program_; scoped_ptr<SolidColorProgramAA> solid_color_program_aa_; @@ -347,6 +381,7 @@ class CC_EXPORT GLRenderer bool blend_shadow_; unsigned program_shadow_; TexturedQuadDrawCache draw_cache_; + int highp_threshold_min_; scoped_ptr<ResourceProvider::ScopedWriteLockGL> current_framebuffer_lock_; diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc index 9bbed71..30ba585 100644 --- a/cc/output/gl_renderer_unittest.cc +++ b/cc/output/gl_renderer_unittest.cc @@ -66,28 +66,37 @@ class GLRendererShaderPixelTest : public PixelTest { EXPECT_PROGRAM_VALID(renderer_->GetTileProgramSwizzleOpaque()); EXPECT_PROGRAM_VALID(renderer_->GetTileProgramSwizzleAA()); EXPECT_PROGRAM_VALID(renderer_->GetTileCheckerboardProgram()); - EXPECT_PROGRAM_VALID(renderer_->GetRenderPassProgram()); - EXPECT_PROGRAM_VALID(renderer_->GetRenderPassProgramAA()); - EXPECT_PROGRAM_VALID(renderer_->GetRenderPassMaskProgram()); - EXPECT_PROGRAM_VALID(renderer_->GetRenderPassMaskProgramAA()); - EXPECT_PROGRAM_VALID(renderer_->GetRenderPassColorMatrixProgram()); - EXPECT_PROGRAM_VALID(renderer_->GetRenderPassMaskColorMatrixProgramAA()); - EXPECT_PROGRAM_VALID(renderer_->GetRenderPassColorMatrixProgramAA()); - EXPECT_PROGRAM_VALID(renderer_->GetRenderPassMaskColorMatrixProgram()); - EXPECT_PROGRAM_VALID(renderer_->GetTextureProgram()); - EXPECT_PROGRAM_VALID(renderer_->GetTextureProgramFlip()); - EXPECT_PROGRAM_VALID(renderer_->GetTextureIOSurfaceProgram()); - EXPECT_PROGRAM_VALID(renderer_->GetVideoYUVProgram()); - // This is unlikely to be ever true in tests due to usage of osmesa. - if (renderer_->Capabilities().using_egl_image) - EXPECT_PROGRAM_VALID(renderer_->GetVideoStreamTextureProgram()); - else - EXPECT_FALSE(renderer_->GetVideoStreamTextureProgram()); EXPECT_PROGRAM_VALID(renderer_->GetDebugBorderProgram()); EXPECT_PROGRAM_VALID(renderer_->GetSolidColorProgram()); EXPECT_PROGRAM_VALID(renderer_->GetSolidColorProgramAA()); + //TestShadersWithTexCoordPrecision(TexCoordPrecisionMedium); + TestShadersWithTexCoordPrecision(TexCoordPrecisionHigh); ASSERT_FALSE(renderer_->IsContextLost()); } + + void TestShadersWithTexCoordPrecision(TexCoordPrecision precision) { + EXPECT_PROGRAM_VALID(renderer_->GetRenderPassProgram(precision)); + EXPECT_PROGRAM_VALID(renderer_->GetRenderPassProgramAA(precision)); + EXPECT_PROGRAM_VALID(renderer_->GetRenderPassMaskProgram(precision)); + EXPECT_PROGRAM_VALID(renderer_->GetRenderPassMaskProgramAA(precision)); + EXPECT_PROGRAM_VALID( + renderer_->GetRenderPassColorMatrixProgram(precision)); + EXPECT_PROGRAM_VALID( + renderer_->GetRenderPassMaskColorMatrixProgramAA(precision)); + EXPECT_PROGRAM_VALID( + renderer_->GetRenderPassColorMatrixProgramAA(precision)); + EXPECT_PROGRAM_VALID( + renderer_->GetRenderPassMaskColorMatrixProgram(precision)); + EXPECT_PROGRAM_VALID(renderer_->GetTextureProgram(precision)); + EXPECT_PROGRAM_VALID(renderer_->GetTextureProgramFlip(precision)); + EXPECT_PROGRAM_VALID(renderer_->GetTextureIOSurfaceProgram(precision)); + EXPECT_PROGRAM_VALID(renderer_->GetVideoYUVProgram(precision)); + // This is unlikely to be ever true in tests due to usage of osmesa. + if (renderer_->Capabilities().using_egl_image) + EXPECT_PROGRAM_VALID(renderer_->GetVideoStreamTextureProgram(precision)); + else + EXPECT_FALSE(renderer_->GetVideoStreamTextureProgram(precision)); + } }; namespace { @@ -209,7 +218,7 @@ class FakeRendererGL : public GLRenderer { FakeRendererGL(RendererClient* client, OutputSurface* output_surface, ResourceProvider* resource_provider) - : GLRenderer(client, output_surface, resource_provider) {} + : GLRenderer(client, output_surface, resource_provider, 0) {} // GLRenderer methods. @@ -229,7 +238,7 @@ class GLRendererTest : public testing::Test { output_surface_(FakeOutputSurface::Create3d( scoped_ptr<WebKit::WebGraphicsContext3D>( new FrameCountingMemoryAllocationSettingContext()))), - resource_provider_(ResourceProvider::Create(output_surface_.get())), + resource_provider_(ResourceProvider::Create(output_surface_.get(), 0)), renderer_(&mock_client_, output_surface_.get(), resource_provider_.get()) {} @@ -261,9 +270,9 @@ class GLRendererShaderTest : public testing::Test { protected: GLRendererShaderTest() : output_surface_(FakeOutputSurface::Create3d()), - resource_provider_(ResourceProvider::Create(output_surface_.get())), + resource_provider_(ResourceProvider::Create(output_surface_.get(), 0)), renderer_(GLRenderer::Create(&mock_client_, output_surface_.get(), - resource_provider_.get())) { + resource_provider_.get(), 0)) { } void TestRenderPassProgram() { @@ -561,7 +570,7 @@ TEST(GLRendererTest2, InitializationDoesNotMakeSynchronousCalls) { FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( new ForbidSynchronousCallContext))); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get())); + ResourceProvider::Create(output_surface.get(), 0)); FakeRendererGL renderer( &mock_client, output_surface.get(), resource_provider.get()); @@ -600,7 +609,7 @@ TEST(GLRendererTest2, InitializationWithQuicklyLostContextDoesNotAssert) { FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( new LoseContextOnFirstGetContext))); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get())); + ResourceProvider::Create(output_surface.get(), 0)); FakeRendererGL renderer( &mock_client, output_surface.get(), resource_provider.get()); @@ -629,7 +638,7 @@ TEST( FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( new ContextThatDoesNotSupportMemoryManagmentExtensions))); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get())); + ResourceProvider::Create(output_surface.get(), 0)); FakeRendererGL renderer( &mock_client, output_surface.get(), resource_provider.get()); @@ -657,7 +666,7 @@ TEST(GLRendererTest2, OpaqueBackground) { ClearCountingContext* context = static_cast<ClearCountingContext*>(output_surface->context3d()); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get())); + ResourceProvider::Create(output_surface.get(), 0)); FakeRendererGL renderer( &mock_client, output_surface.get(), resource_provider.get()); @@ -683,7 +692,7 @@ TEST(GLRendererTest2, TransparentBackground) { ClearCountingContext* context = static_cast<ClearCountingContext*>(output_surface->context3d()); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get())); + ResourceProvider::Create(output_surface.get(), 0)); FakeRendererGL renderer( &mock_client, output_surface.get(), resource_provider.get()); @@ -754,7 +763,7 @@ TEST(GLRendererTest2, VisibilityChangeIsLastCall) { static_cast<VisibilityChangeIsLastCallTrackingContext*>( output_surface->context3d()); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get())); + ResourceProvider::Create(output_surface.get(), 0)); FakeRendererGL renderer( &mock_client, output_surface.get(), resource_provider.get()); @@ -813,7 +822,7 @@ TEST(GLRendererTest2, ActiveTextureState) { TextureStateTrackingContext* context = static_cast<TextureStateTrackingContext*>(output_surface->context3d()); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get())); + ResourceProvider::Create(output_surface.get(), 0)); FakeRendererGL renderer( &fake_client, output_surface.get(), resource_provider.get()); @@ -898,7 +907,7 @@ TEST(GLRendererTest2, ShouldClearRootRenderPass) { static_cast<NoClearRootRenderPassMockContext*>( output_surface->context3d()); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get())); + ResourceProvider::Create(output_surface.get(), 0)); FakeRendererGL renderer( &mock_client, output_surface.get(), resource_provider.get()); EXPECT_TRUE(renderer.Initialize()); @@ -968,7 +977,7 @@ TEST(GLRendererTest2, ScissorTestWhenClearing) { FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( new ScissorTestOnClearCheckingContext))); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get())); + ResourceProvider::Create(output_surface.get(), 0)); FakeRendererGL renderer( &mock_client, output_surface.get(), resource_provider.get()); EXPECT_TRUE(renderer.Initialize()); @@ -1283,7 +1292,7 @@ class MockOutputSurface : public OutputSurface { class MockOutputSurfaceTest : public testing::Test, public FakeRendererClient { protected: MockOutputSurfaceTest() - : resource_provider_(ResourceProvider::Create(&output_surface_)), + : resource_provider_(ResourceProvider::Create(&output_surface_, 0)), renderer_(this, &output_surface_, resource_provider_.get()) {} virtual void SetUp() { EXPECT_TRUE(renderer_.Initialize()); } diff --git a/cc/output/program_binding.h b/cc/output/program_binding.h index 0e5aa9e..ee9d284 100644 --- a/cc/output/program_binding.h +++ b/cc/output/program_binding.h @@ -8,6 +8,7 @@ #include <string> #include "base/logging.h" +#include "cc/output/shader.h" namespace WebKit { class WebGraphicsContext3D; } @@ -49,10 +50,12 @@ class ProgramBindingBase { template <class VertexShader, class FragmentShader> class ProgramBinding : public ProgramBindingBase { public: - explicit ProgramBinding(WebKit::WebGraphicsContext3D* context) { - ProgramBindingBase::Init(context, - vertex_shader_.GetShaderString(), - fragment_shader_.GetShaderString()); + explicit ProgramBinding(WebKit::WebGraphicsContext3D* context, + TexCoordPrecision precision) { + ProgramBindingBase::Init( + context, + vertex_shader_.GetShaderString(), + fragment_shader_.GetShaderString(precision)); } void Initialize(WebKit::WebGraphicsContext3D* context, diff --git a/cc/output/shader.cc b/cc/output/shader.cc index 988f6e1..7afa8a3 100644 --- a/cc/output/shader.cc +++ b/cc/output/shader.cc @@ -8,10 +8,13 @@ #include "base/basictypes.h" #include "base/logging.h" +#include "cc/output/gl_renderer.h" // For the GLC() macro. #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h" +#include "third_party/khronos/GLES2/gl2.h" #define SHADER0(Src) #Src -#define SHADER(Src) SHADER0(Src) +#define VERTEX_SHADER(Src) setVertexTexCoordPrecision(SHADER0(Src)) +#define FRAGMENT_SHADER(Src) setFragTexCoordPrecision(precision, SHADER0(Src)) using WebKit::WebGraphicsContext3D; @@ -42,7 +45,72 @@ static void GetProgramUniformLocations(WebGraphicsContext3D* context, } } -} // namespace +static std::string setFragTexCoordPrecision( + TexCoordPrecision requestedPrecision, std::string shaderString) +{ + switch (requestedPrecision) { + case TexCoordPrecisionHigh: + DCHECK_NE(shaderString.find("TexCoordPrecision"), std::string::npos); + return "#ifdef GL_FRAGMENT_PRECISION_HIGH\n" + " #define TexCoordPrecision highp\n" + "#else\n" + " #define TexCoordPrecision mediump\n" + "#endif\n" + + shaderString; + case TexCoordPrecisionMedium: + DCHECK_NE(shaderString.find("TexCoordPrecision"), std::string::npos); + return "#define TexCoordPrecision mediump\n" + + shaderString; + case TexCoordPrecisionNA: + DCHECK_EQ(shaderString.find("TexCoordPrecision"), std::string::npos); + DCHECK_EQ(shaderString.find("texture2D"), std::string::npos); + return shaderString; + } + return shaderString; +} + +static std::string setVertexTexCoordPrecision(const char* shaderString) +{ + // We unconditionally use highp in the vertex shader since + // we are unlikely to be vertex shader bound when drawing large quads. + // Also, some vertex shaders mutate the texture coordinate in such a + // way that the effective precision might be lower than expected. + return "#define TexCoordPrecision highp\n" + + std::string(shaderString); +} + +TexCoordPrecision TexCoordPrecisionRequired(WebGraphicsContext3D* context, + int highp_threshold_min, + int x, int y) { + // Initialize range and precision with minimum spec values for when + // getShaderPrecisionFormat is a test stub. + // TODO: Implement better stubs of getShaderPrecisionFormat everywhere. + GLint range[2] = { 14, 14 }; + GLint precision = 10; + GLC(context, context->getShaderPrecisionFormat(GL_FRAGMENT_SHADER, + GL_MEDIUM_FLOAT, + range, &precision)); + int highp_threshold = std::max(1 << precision, highp_threshold_min); + if (x > highp_threshold || y > highp_threshold) + return TexCoordPrecisionHigh; + return TexCoordPrecisionMedium; +} + +} // namespace + +TexCoordPrecision TexCoordPrecisionRequired(WebGraphicsContext3D* context, + int highp_threshold_min, + const gfx::Point& max_coordinate) { + return TexCoordPrecisionRequired(context, highp_threshold_min, + max_coordinate.x(), max_coordinate.y()); +} + +TexCoordPrecision TexCoordPrecisionRequired(WebGraphicsContext3D* context, + int highp_threshold_min, + const gfx::Size& max_size) { + return TexCoordPrecisionRequired(context, highp_threshold_min, + max_size.width(), max_size.height()); +} VertexShaderPosTex::VertexShaderPosTex() : matrix_location_(-1) {} @@ -70,11 +138,11 @@ void VertexShaderPosTex::Init(WebGraphicsContext3D* context, } std::string VertexShaderPosTex::GetShaderString() const { - return SHADER( + return VERTEX_SHADER( attribute vec4 a_position; - attribute vec2 a_texCoord; + attribute TexCoordPrecision vec2 a_texCoord; uniform mat4 matrix; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; void main() { gl_Position = matrix * a_position; v_texCoord = a_texCoord; @@ -111,13 +179,13 @@ void VertexShaderPosTexYUVStretch::Init(WebGraphicsContext3D* context, } std::string VertexShaderPosTexYUVStretch::GetShaderString() const { - return SHADER( + return VERTEX_SHADER( precision mediump float; attribute vec4 a_position; - attribute vec2 a_texCoord; + attribute TexCoordPrecision vec2 a_texCoord; uniform mat4 matrix; - varying vec2 v_texCoord; - uniform vec2 texScale; + varying TexCoordPrecision vec2 v_texCoord; + uniform TexCoordPrecision vec2 texScale; void main() { gl_Position = matrix * a_position; v_texCoord = a_texCoord * texScale; @@ -151,7 +219,7 @@ void VertexShaderPos::Init(WebGraphicsContext3D* context, } std::string VertexShaderPos::GetShaderString() const { - return SHADER( + return VERTEX_SHADER( attribute vec4 a_position; uniform mat4 matrix; void main() { @@ -193,18 +261,19 @@ void VertexShaderPosTexTransform::Init(WebGraphicsContext3D* context, } std::string VertexShaderPosTexTransform::GetShaderString() const { - return SHADER( + return VERTEX_SHADER( attribute vec4 a_position; - attribute vec2 a_texCoord; + attribute TexCoordPrecision vec2 a_texCoord; attribute float a_index; uniform mat4 matrix[8]; - uniform vec4 texTransform[8]; + uniform TexCoordPrecision vec4 texTransform[8]; uniform float opacity[32]; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; varying float v_alpha; void main() { gl_Position = matrix[int(a_index * 0.25)] * a_position; // NOLINT - vec4 texTrans = texTransform[int(a_index * 0.25)]; // NOLINT + TexCoordPrecision vec4 texTrans = + texTransform[int(a_index * 0.25)]; // NOLINT v_texCoord = a_texCoord * texTrans.zw + texTrans.xy; v_alpha = opacity[int(a_index)]; // NOLINT } @@ -212,18 +281,19 @@ std::string VertexShaderPosTexTransform::GetShaderString() const { } std::string VertexShaderPosTexTransformFlip::GetShaderString() const { - return SHADER( + return VERTEX_SHADER( attribute vec4 a_position; - attribute vec2 a_texCoord; + attribute TexCoordPrecision vec2 a_texCoord; attribute float a_index; uniform mat4 matrix[8]; - uniform vec4 texTransform[8]; + uniform TexCoordPrecision vec4 texTransform[8]; uniform float opacity[32]; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; varying float v_alpha; void main() { gl_Position = matrix[int(a_index * 0.25)] * a_position; // NOLINT - vec4 texTrans = texTransform[int(a_index * 0.25)]; // NOLINT + TexCoordPrecision vec4 texTrans = + texTransform[int(a_index * 0.25)]; // NOLINT v_texCoord = a_texCoord * texTrans.zw + texTrans.xy; v_texCoord.y = 1.0 - v_texCoord.y; v_alpha = opacity[int(a_index)]; // NOLINT @@ -232,9 +302,9 @@ std::string VertexShaderPosTexTransformFlip::GetShaderString() const { } std::string VertexShaderPosTexIdentity::GetShaderString() const { - return SHADER( + return VERTEX_SHADER( attribute vec4 a_position; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; void main() { gl_Position = a_position; v_texCoord = (a_position.xy + vec2(1.0)) * 0.5; @@ -276,16 +346,16 @@ void VertexShaderQuad::Init(WebGraphicsContext3D* context, } std::string VertexShaderQuad::GetShaderString() const { - return SHADER( - attribute vec4 a_position; - attribute vec2 a_texCoord; + return VERTEX_SHADER( + attribute TexCoordPrecision vec4 a_position; + attribute TexCoordPrecision vec2 a_texCoord; uniform mat4 matrix; - uniform vec2 point[4]; - uniform vec2 texScale; - varying vec2 v_texCoord; + uniform TexCoordPrecision vec2 point[4]; + uniform TexCoordPrecision vec2 texScale; + varying TexCoordPrecision vec2 v_texCoord; void main() { - vec2 complement = abs(a_texCoord - 1.0); - vec4 pos = vec4(0.0, 0.0, a_position.z, a_position.w); + TexCoordPrecision vec2 complement = abs(a_texCoord - 1.0); + TexCoordPrecision vec4 pos = vec4(0.0, 0.0, a_position.z, a_position.w); pos.xy += (complement.x * complement.y) * point[0]; pos.xy += (a_texCoord.x * complement.y) * point[1]; pos.xy += (a_texCoord.x * a_texCoord.y) * point[2]; @@ -329,16 +399,16 @@ void VertexShaderTile::Init(WebGraphicsContext3D* context, } std::string VertexShaderTile::GetShaderString() const { - return SHADER( - attribute vec4 a_position; - attribute vec2 a_texCoord; + return VERTEX_SHADER( + attribute TexCoordPrecision vec4 a_position; + attribute TexCoordPrecision vec2 a_texCoord; uniform mat4 matrix; - uniform vec2 point[4]; - uniform vec4 vertexTexTransform; - varying vec2 v_texCoord; + uniform TexCoordPrecision vec2 point[4]; + uniform TexCoordPrecision vec4 vertexTexTransform; + varying TexCoordPrecision vec2 v_texCoord; void main() { - vec2 complement = abs(a_texCoord - 1.0); - vec4 pos = vec4(0.0, 0.0, a_position.z, a_position.w); + TexCoordPrecision vec2 complement = abs(a_texCoord - 1.0); + TexCoordPrecision vec4 pos = vec4(0.0, 0.0, a_position.z, a_position.w); pos.xy += (complement.x * complement.y) * point[0]; pos.xy += (a_texCoord.x * complement.y) * point[1]; pos.xy += (a_texCoord.x * a_texCoord.y) * point[2]; @@ -378,12 +448,12 @@ bool VertexShaderVideoTransform::Init(WebGraphicsContext3D* context, } std::string VertexShaderVideoTransform::GetShaderString() const { - return SHADER( + return VERTEX_SHADER( attribute vec4 a_position; - attribute vec2 a_texCoord; + attribute TexCoordPrecision vec2 a_texCoord; uniform mat4 matrix; - uniform mat4 texMatrix; - varying vec2 v_texCoord; + uniform TexCoordPrecision mat4 texMatrix; + varying TexCoordPrecision vec2 v_texCoord; void main() { gl_Position = matrix * a_position; v_texCoord = @@ -505,12 +575,13 @@ bool FragmentShaderOESImageExternal::Init(WebGraphicsContext3D* context, return sampler_location_ != -1; } -std::string FragmentShaderOESImageExternal::GetShaderString() const { +std::string FragmentShaderOESImageExternal::GetShaderString( + TexCoordPrecision precision) const { // Cannot use the SHADER() macro because of the '#' char - return "#extension GL_OES_EGL_image_external : require\n" - SHADER( + return "#extension GL_OES_EGL_image_external : require\n" + + FRAGMENT_SHADER( precision mediump float; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; uniform samplerExternalOES s_texture; void main() { vec4 texColor = texture2D(s_texture, v_texCoord); @@ -519,10 +590,11 @@ std::string FragmentShaderOESImageExternal::GetShaderString() const { ); // NOLINT(whitespace/parens) } -std::string FragmentShaderRGBATexAlpha::GetShaderString() const { - return SHADER( +std::string FragmentShaderRGBATexAlpha::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; uniform sampler2D s_texture; uniform float alpha; void main() { @@ -532,10 +604,11 @@ std::string FragmentShaderRGBATexAlpha::GetShaderString() const { ); // NOLINT(whitespace/parens) } -std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderString() const { - return SHADER( +std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; uniform sampler2D s_texture; uniform float alpha; uniform mat4 colorMatrix; @@ -552,10 +625,11 @@ std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderString() const { ); // NOLINT(whitespace/parens) } -std::string FragmentShaderRGBATexVaryingAlpha::GetShaderString() const { - return SHADER( +std::string FragmentShaderRGBATexVaryingAlpha::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; varying float v_alpha; uniform sampler2D s_texture; void main() { @@ -565,11 +639,12 @@ std::string FragmentShaderRGBATexVaryingAlpha::GetShaderString() const { ); // NOLINT(whitespace/parens) } -std::string FragmentShaderRGBATexRectVaryingAlpha::GetShaderString() const { - return "#extension GL_ARB_texture_rectangle : require\n" - SHADER( +std::string FragmentShaderRGBATexRectVaryingAlpha::GetShaderString( + TexCoordPrecision precision) const { + return "#extension GL_ARB_texture_rectangle : require\n" + + FRAGMENT_SHADER( precision mediump float; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; varying float v_alpha; uniform sampler2DRect s_texture; void main() { @@ -579,10 +654,11 @@ std::string FragmentShaderRGBATexRectVaryingAlpha::GetShaderString() const { ); // NOLINT(whitespace/parens) } -std::string FragmentShaderRGBATexOpaque::GetShaderString() const { - return SHADER( +std::string FragmentShaderRGBATexOpaque::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; uniform sampler2D s_texture; void main() { vec4 texColor = texture2D(s_texture, v_texCoord); @@ -591,10 +667,11 @@ std::string FragmentShaderRGBATexOpaque::GetShaderString() const { ); // NOLINT(whitespace/parens) } -std::string FragmentShaderRGBATex::GetShaderString() const { - return SHADER( +std::string FragmentShaderRGBATex::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; uniform sampler2D s_texture; void main() { gl_FragColor = texture2D(s_texture, v_texCoord); @@ -602,10 +679,11 @@ std::string FragmentShaderRGBATex::GetShaderString() const { ); // NOLINT(whitespace/parens) } -std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderString() const { - return SHADER( +std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; uniform sampler2D s_texture; uniform float alpha; void main() { @@ -616,10 +694,11 @@ std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderString() const { ); // NOLINT(whitespace/parens) } -std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderString() const { - return SHADER( +std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; uniform sampler2D s_texture; void main() { vec4 texColor = texture2D(s_texture, v_texCoord); @@ -660,10 +739,11 @@ void FragmentShaderRGBATexAlphaAA::Init(WebGraphicsContext3D* context, edge_location_ != -1); } -std::string FragmentShaderRGBATexAlphaAA::GetShaderString() const { - return SHADER( +std::string FragmentShaderRGBATexAlphaAA::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; uniform sampler2D s_texture; uniform float alpha; uniform vec3 edge[8]; @@ -719,16 +799,18 @@ void FragmentTexClampAlphaAABinding::Init(WebGraphicsContext3D* context, fragment_tex_transform_location_ != -1 && edge_location_ != -1); } -std::string FragmentShaderRGBATexClampAlphaAA::GetShaderString() const { - return SHADER( +std::string FragmentShaderRGBATexClampAlphaAA::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; uniform sampler2D s_texture; uniform float alpha; - uniform vec4 fragmentTexTransform; + uniform TexCoordPrecision vec4 fragmentTexTransform; uniform vec3 edge[8]; void main() { - vec2 texCoord = clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw + + TexCoordPrecision vec2 texCoord = + clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw + fragmentTexTransform.xy; vec4 texColor = texture2D(s_texture, texCoord); vec3 pos = vec3(gl_FragCoord.xy, 1); @@ -746,16 +828,18 @@ std::string FragmentShaderRGBATexClampAlphaAA::GetShaderString() const { ); // NOLINT(whitespace/parens) } -std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderString() const { - return SHADER( +std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; uniform sampler2D s_texture; uniform float alpha; - uniform vec4 fragmentTexTransform; + uniform TexCoordPrecision vec4 fragmentTexTransform; uniform vec3 edge[8]; void main() { - vec2 texCoord = clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw + + TexCoordPrecision vec2 texCoord = + clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw + fragmentTexTransform.xy; vec4 texColor = texture2D(s_texture, texCoord); vec3 pos = vec3(gl_FragCoord.xy, 1); @@ -810,21 +894,21 @@ void FragmentShaderRGBATexAlphaMask::Init(WebGraphicsContext3D* context, alpha_location_ != -1); } -std::string FragmentShaderRGBATexAlphaMask::GetShaderString() const { - return SHADER( +std::string FragmentShaderRGBATexAlphaMask::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; uniform sampler2D s_texture; uniform sampler2D s_mask; - uniform vec2 maskTexCoordScale; - uniform vec2 maskTexCoordOffset; + uniform TexCoordPrecision vec2 maskTexCoordScale; + uniform TexCoordPrecision vec2 maskTexCoordOffset; uniform float alpha; void main() { vec4 texColor = texture2D(s_texture, v_texCoord); - vec2 maskTexCoord = vec2(maskTexCoordOffset.x + v_texCoord.x * - maskTexCoordScale.x, - maskTexCoordOffset.y + v_texCoord.y * - maskTexCoordScale.y); + TexCoordPrecision vec2 maskTexCoord = + vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x, + maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y); vec4 maskColor = texture2D(s_mask, maskTexCoord); gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha * maskColor.w; @@ -872,22 +956,22 @@ void FragmentShaderRGBATexAlphaMaskAA::Init(WebGraphicsContext3D* context, alpha_location_ != -1 && edge_location_ != -1); } -std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderString() const { - return SHADER( +std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; uniform sampler2D s_texture; uniform sampler2D s_mask; - uniform vec2 maskTexCoordScale; - uniform vec2 maskTexCoordOffset; + uniform TexCoordPrecision vec2 maskTexCoordScale; + uniform TexCoordPrecision vec2 maskTexCoordOffset; uniform float alpha; uniform vec3 edge[8]; void main() { vec4 texColor = texture2D(s_texture, v_texCoord); - vec2 maskTexCoord = vec2(maskTexCoordOffset.x + v_texCoord.x * - maskTexCoordScale.x, - maskTexCoordOffset.y + v_texCoord.y * - maskTexCoordScale.y); + TexCoordPrecision vec2 maskTexCoord = + vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x, + maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y); vec4 maskColor = texture2D(s_mask, maskTexCoord); vec3 pos = vec3(gl_FragCoord.xy, 1); float a0 = clamp(dot(edge[0], pos), 0.0, 1.0); @@ -954,11 +1038,11 @@ void FragmentShaderRGBATexAlphaMaskColorMatrixAA::Init( color_matrix_location_ != -1 && color_offset_location_ != -1); } -std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderString() - const { - return SHADER( +std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; uniform sampler2D s_texture; uniform sampler2D s_mask; uniform vec2 maskTexCoordScale; @@ -974,7 +1058,7 @@ std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderString() texColor = colorMatrix * texColor + colorOffset; texColor.rgb *= texColor.a; texColor = clamp(texColor, 0.0, 1.0); - vec2 maskTexCoord = + TexCoordPrecision vec2 maskTexCoord = vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x, maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y); vec4 maskColor = texture2D(s_mask, maskTexCoord); @@ -1034,10 +1118,11 @@ void FragmentShaderRGBATexAlphaColorMatrixAA::Init( color_offset_location_ != -1); } -std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderString() const { - return SHADER( +std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; uniform sampler2D s_texture; uniform float alpha; uniform mat4 colorMatrix; @@ -1107,10 +1192,11 @@ void FragmentShaderRGBATexAlphaMaskColorMatrix::Init( color_offset_location_ != -1); } -std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderString() const { - return SHADER( +std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; uniform sampler2D s_texture; uniform sampler2D s_mask; uniform vec2 maskTexCoordScale; @@ -1125,7 +1211,7 @@ std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderString() const { texColor = colorMatrix * texColor + colorOffset; texColor.rgb *= texColor.a; texColor = clamp(texColor, 0.0, 1.0); - vec2 maskTexCoord = + TexCoordPrecision vec2 maskTexCoord = vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x, maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y); vec4 maskColor = texture2D(s_mask, maskTexCoord); @@ -1178,11 +1264,12 @@ void FragmentShaderYUVVideo::Init(WebGraphicsContext3D* context, yuv_matrix_location_ != -1 && yuv_adj_location_ != -1); } -std::string FragmentShaderYUVVideo::GetShaderString() const { - return SHADER( +std::string FragmentShaderYUVVideo::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; precision mediump int; - varying vec2 v_texCoord; + varying TexCoordPrecision vec2 v_texCoord; uniform sampler2D y_texture; uniform sampler2D u_texture; uniform sampler2D v_texture; @@ -1225,8 +1312,9 @@ void FragmentShaderColor::Init(WebGraphicsContext3D* context, DCHECK_NE(color_location_, -1); } -std::string FragmentShaderColor::GetShaderString() const { - return SHADER( +std::string FragmentShaderColor::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; uniform vec4 color; void main() { @@ -1263,8 +1351,9 @@ void FragmentShaderColorAA::Init(WebGraphicsContext3D* context, DCHECK(edge_location_ != -1 && color_location_ != -1); } -std::string FragmentShaderColorAA::GetShaderString() const { - return SHADER( +std::string FragmentShaderColorAA::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( precision mediump float; uniform vec4 color; uniform vec3 edge[8]; @@ -1318,10 +1407,11 @@ void FragmentShaderCheckerboard::Init(WebGraphicsContext3D* context, frequency_location_ != -1 && color_location_ != -1); } -std::string FragmentShaderCheckerboard::GetShaderString() const { +std::string FragmentShaderCheckerboard::GetShaderString( + TexCoordPrecision precision) const { // Shader based on Example 13-17 of "OpenGL ES 2.0 Programming Guide" // by Munshi, Ginsburg, Shreiner. - return SHADER( + return FRAGMENT_SHADER( precision mediump float; precision mediump int; varying vec2 v_texCoord; @@ -1332,8 +1422,8 @@ std::string FragmentShaderCheckerboard::GetShaderString() const { void main() { vec4 color1 = vec4(1.0, 1.0, 1.0, 1.0); vec4 color2 = color; - vec2 texCoord = clamp(v_texCoord, 0.0, 1.0) * texTransform.zw + - texTransform.xy; + vec2 texCoord = + clamp(v_texCoord, 0.0, 1.0) * texTransform.zw + texTransform.xy; vec2 coord = mod(floor(texCoord * frequency * 2.0), 2.0); float picker = abs(coord.x - coord.y); gl_FragColor = mix(color1, color2, picker) * alpha; diff --git a/cc/output/shader.h b/cc/output/shader.h index 228fc6d..5832e8f 100644 --- a/cc/output/shader.h +++ b/cc/output/shader.h @@ -8,14 +8,36 @@ #include <string> #include "base/basictypes.h" +#include "cc/base/cc_export.h" #include "third_party/skia/include/core/SkColorPriv.h" +namespace gfx { +class Point; +class Size; +} + namespace WebKit { class WebGraphicsContext3D; } namespace cc { +enum TexCoordPrecision { + TexCoordPrecisionNA, + TexCoordPrecisionMedium, + TexCoordPrecisionHigh, +}; + +CC_EXPORT TexCoordPrecision TexCoordPrecisionRequired( + WebKit::WebGraphicsContext3D* context, + int highp_threshold_min, + const gfx::Point& max_coordinate); + +CC_EXPORT TexCoordPrecision TexCoordPrecisionRequired( + WebKit::WebGraphicsContext3D* context, + int highp_threshold_min, + const gfx::Size& max_size); + class VertexShaderPosTex { public: VertexShaderPosTex(); @@ -237,45 +259,45 @@ class FragmentTexOpaqueBinding { class FragmentShaderRGBATexVaryingAlpha : public FragmentTexOpaqueBinding { public: - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; }; class FragmentShaderRGBATexAlpha : public FragmentTexAlphaBinding { public: - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; }; class FragmentShaderRGBATexColorMatrixAlpha : public FragmentTexColorMatrixAlphaBinding { public: - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; }; class FragmentShaderRGBATexRectVaryingAlpha : public FragmentTexAlphaBinding { public: - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; }; class FragmentShaderRGBATexOpaque : public FragmentTexOpaqueBinding { public: - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; }; class FragmentShaderRGBATex : public FragmentTexOpaqueBinding { public: - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; }; // Swizzles the red and blue component of sampled texel with alpha. class FragmentShaderRGBATexSwizzleAlpha : public FragmentTexAlphaBinding { public: - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; }; // Swizzles the red and blue component of sampled texel without alpha. class FragmentShaderRGBATexSwizzleOpaque : public FragmentTexOpaqueBinding { public: - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; }; // Fragment shader for external textures. @@ -283,7 +305,7 @@ class FragmentShaderOESImageExternal : public FragmentTexAlphaBinding { public: FragmentShaderOESImageExternal(); - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; bool Init(WebKit::WebGraphicsContext3D*, unsigned program, bool using_bind_uniform, @@ -302,7 +324,7 @@ class FragmentShaderRGBATexAlphaAA { unsigned program, bool using_bind_uniform, int* base_uniform_index); - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; int alpha_location() const { return alpha_location_; } int sampler_location() const { return sampler_location_; } @@ -343,20 +365,20 @@ class FragmentTexClampAlphaAABinding { class FragmentShaderRGBATexClampAlphaAA : public FragmentTexClampAlphaAABinding { public: - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; }; // Swizzles the red and blue component of sampled texel. class FragmentShaderRGBATexClampSwizzleAlphaAA : public FragmentTexClampAlphaAABinding { public: - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; }; class FragmentShaderRGBATexAlphaMask { public: FragmentShaderRGBATexAlphaMask(); - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; void Init(WebKit::WebGraphicsContext3D*, unsigned program, @@ -385,7 +407,7 @@ class FragmentShaderRGBATexAlphaMask { class FragmentShaderRGBATexAlphaMaskAA { public: FragmentShaderRGBATexAlphaMaskAA(); - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; void Init(WebKit::WebGraphicsContext3D*, unsigned program, @@ -416,7 +438,7 @@ class FragmentShaderRGBATexAlphaMaskAA { class FragmentShaderRGBATexAlphaMaskColorMatrixAA { public: FragmentShaderRGBATexAlphaMaskColorMatrixAA(); - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; void Init(WebKit::WebGraphicsContext3D*, unsigned program, @@ -449,7 +471,7 @@ class FragmentShaderRGBATexAlphaMaskColorMatrixAA { class FragmentShaderRGBATexAlphaColorMatrixAA { public: FragmentShaderRGBATexAlphaColorMatrixAA(); - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; void Init(WebKit::WebGraphicsContext3D*, unsigned program, @@ -472,7 +494,7 @@ class FragmentShaderRGBATexAlphaColorMatrixAA { class FragmentShaderRGBATexAlphaMaskColorMatrix { public: FragmentShaderRGBATexAlphaMaskColorMatrix(); - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; void Init(WebKit::WebGraphicsContext3D*, unsigned program, @@ -503,7 +525,7 @@ class FragmentShaderRGBATexAlphaMaskColorMatrix { class FragmentShaderYUVVideo { public: FragmentShaderYUVVideo(); - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; void Init(WebKit::WebGraphicsContext3D*, unsigned program, @@ -530,7 +552,7 @@ class FragmentShaderYUVVideo { class FragmentShaderColor { public: FragmentShaderColor(); - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; void Init(WebKit::WebGraphicsContext3D*, unsigned program, @@ -548,7 +570,7 @@ class FragmentShaderColor { class FragmentShaderColorAA { public: FragmentShaderColorAA(); - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; void Init(WebKit::WebGraphicsContext3D*, unsigned program, @@ -567,7 +589,7 @@ class FragmentShaderColorAA { class FragmentShaderCheckerboard { public: FragmentShaderCheckerboard(); - std::string GetShaderString() const; + std::string GetShaderString(TexCoordPrecision precision) const; void Init(WebKit::WebGraphicsContext3D*, unsigned program, diff --git a/cc/output/shader_unittest.cc b/cc/output/shader_unittest.cc new file mode 100644 index 0000000..adbe887 --- /dev/null +++ b/cc/output/shader_unittest.cc @@ -0,0 +1,46 @@ +// Copyright 2013 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. + +#include "cc/output/shader.h" + +#include "cc/debug/fake_web_graphics_context_3d.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/point.h" +#include "ui/gfx/size.h" + +namespace cc { + +TEST(ShaderTest, HighpThresholds) { + // The FakeWebGraphicsContext3D always uses a mediump precision of 10 bits + // which corresponds to a native highp threshold of 2^10 = 1024 + FakeWebGraphicsContext3D context; + + int threshold_min; + gfx::Point closePoint(512, 512); + gfx::Size smallSize(512, 512); + gfx::Point farPoint(2560, 2560); + gfx::Size bigSize(2560, 2560); + + threshold_min = 0; + EXPECT_EQ(TexCoordPrecisionMedium, + TexCoordPrecisionRequired(&context, threshold_min, closePoint)); + EXPECT_EQ(TexCoordPrecisionMedium, + TexCoordPrecisionRequired(&context, threshold_min, smallSize)); + EXPECT_EQ(TexCoordPrecisionHigh, + TexCoordPrecisionRequired(&context, threshold_min, farPoint)); + EXPECT_EQ(TexCoordPrecisionHigh, + TexCoordPrecisionRequired(&context, threshold_min, bigSize)); + + threshold_min = 3000; + EXPECT_EQ(TexCoordPrecisionMedium, + TexCoordPrecisionRequired(&context, threshold_min, closePoint)); + EXPECT_EQ(TexCoordPrecisionMedium, + TexCoordPrecisionRequired(&context, threshold_min, smallSize)); + EXPECT_EQ(TexCoordPrecisionMedium, + TexCoordPrecisionRequired(&context, threshold_min, farPoint)); + EXPECT_EQ(TexCoordPrecisionMedium, + TexCoordPrecisionRequired(&context, threshold_min, bigSize)); +} + +} diff --git a/cc/output/software_renderer_unittest.cc b/cc/output/software_renderer_unittest.cc index ade2b90..fc5ba6d 100644 --- a/cc/output/software_renderer_unittest.cc +++ b/cc/output/software_renderer_unittest.cc @@ -29,7 +29,7 @@ class SoftwareRendererTest : public testing::Test, public RendererClient { void InitializeRenderer() { output_surface_ = FakeOutputSurface::CreateSoftware( make_scoped_ptr(new SoftwareOutputDevice)); - resource_provider_ = ResourceProvider::Create(output_surface_.get()); + resource_provider_ = ResourceProvider::Create(output_surface_.get(), 0); renderer_ = SoftwareRenderer::Create( this, output_surface_.get(), resource_provider()); } diff --git a/cc/output/texture_copier.cc b/cc/output/texture_copier.cc index a32fb65..1ad0ef0 100644 --- a/cc/output/texture_copier.cc +++ b/cc/output/texture_copier.cc @@ -14,8 +14,11 @@ namespace cc { AcceleratedTextureCopier::AcceleratedTextureCopier( WebKit::WebGraphicsContext3D* context, - bool using_bind_uniforms) - : context_(context), using_bind_uniforms_(using_bind_uniforms) { + bool using_bind_uniforms, + int highp_threshold_min) + : context_(context) + , using_bind_uniforms_(using_bind_uniforms) + , highp_threshold_min_(highp_threshold_min) { DCHECK(context_); GLC(context_, fbo_ = context_->createFramebuffer()); GLC(context_, position_buffer_ = context_->createBuffer()); @@ -29,12 +32,15 @@ AcceleratedTextureCopier::AcceleratedTextureCopier( GL_ARRAY_BUFFER, sizeof(kPositions), kPositions, GL_STATIC_DRAW)); GLC(context_, context_->bindBuffer(GL_ARRAY_BUFFER, 0)); - blit_program_.reset(new BlitProgram(context_)); + blit_program_.reset(new BlitProgram(context_, TexCoordPrecisionMedium)); + blit_program_highp_.reset(new BlitProgram(context_, TexCoordPrecisionHigh)); } AcceleratedTextureCopier::~AcceleratedTextureCopier() { if (blit_program_) blit_program_->Cleanup(context_); + if (blit_program_highp_) + blit_program_highp_->Cleanup(context_); if (position_buffer_) GLC(context_, context_->deleteBuffer(position_buffer_)); if (fbo_) @@ -72,11 +78,21 @@ void AcceleratedTextureCopier::CopyTexture(Parameters parameters) { context_->texParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - if (!blit_program_->initialized()) - blit_program_->Initialize(context_, using_bind_uniforms_); - - // TODO(danakj): Use EXT_framebuffer_blit if available. - GLC(context_, context_->useProgram(blit_program_->program())); + TexCoordPrecision texCoordPrecision = TexCoordPrecisionRequired( + context_, highp_threshold_min_, parameters.size); + if (texCoordPrecision == TexCoordPrecisionHigh) { + if (!blit_program_highp_->initialized()) + blit_program_highp_->Initialize(context_, using_bind_uniforms_); + + // TODO(danakj): Use EXT_framebuffer_blit if available. + GLC(context_, context_->useProgram(blit_program_highp_->program())); + } else { + if (!blit_program_->initialized()) + blit_program_->Initialize(context_, using_bind_uniforms_); + + // TODO(danakj: Use EXT_framebuffer_blit if available. + GLC(context_, context_->useProgram(blit_program_->program())); + } const int kPositionAttribute = 0; GLC(context_, context_->bindBuffer(GL_ARRAY_BUFFER, position_buffer_)); diff --git a/cc/output/texture_copier.h b/cc/output/texture_copier.h index ad037ba..9b958bce 100644 --- a/cc/output/texture_copier.h +++ b/cc/output/texture_copier.h @@ -38,9 +38,11 @@ class CC_EXPORT AcceleratedTextureCopier : public TextureCopier { public: static scoped_ptr<AcceleratedTextureCopier> Create( WebKit::WebGraphicsContext3D* context, - bool using_bind_uniforms) { + bool using_bind_uniforms, + int highp_threshold_min) { return make_scoped_ptr( - new AcceleratedTextureCopier(context, using_bind_uniforms)); + new AcceleratedTextureCopier( + context, using_bind_uniforms, highp_threshold_min)); } virtual ~AcceleratedTextureCopier(); @@ -49,7 +51,8 @@ class CC_EXPORT AcceleratedTextureCopier : public TextureCopier { protected: AcceleratedTextureCopier(WebKit::WebGraphicsContext3D* context, - bool using_bind_uniforms); + bool using_bind_uniforms, + int highp_threshold_min); private: typedef ProgramBinding<VertexShaderPosTexIdentity, FragmentShaderRGBATex> @@ -59,7 +62,9 @@ class CC_EXPORT AcceleratedTextureCopier : public TextureCopier { GLuint fbo_; GLuint position_buffer_; scoped_ptr<BlitProgram> blit_program_; + scoped_ptr<BlitProgram> blit_program_highp_; bool using_bind_uniforms_; + int highp_threshold_min_; DISALLOW_COPY_AND_ASSIGN(AcceleratedTextureCopier); }; diff --git a/cc/output/texture_copier_unittest.cc b/cc/output/texture_copier_unittest.cc index 671821e..dcd2a98 100644 --- a/cc/output/texture_copier_unittest.cc +++ b/cc/output/texture_copier_unittest.cc @@ -69,7 +69,7 @@ TEST(TextureCopierTest, TestDrawArraysCopy) { int dest_texture_id = mock_context->createTexture(); gfx::Size size(256, 128); scoped_ptr<AcceleratedTextureCopier> copier( - AcceleratedTextureCopier::Create(mock_context.get(), false)); + AcceleratedTextureCopier::Create(mock_context.get(), false, 0)); TextureCopier::Parameters copy = { source_texture_id, dest_texture_id, size }; copier->CopyTexture(copy); } diff --git a/cc/resources/picture_layer_tiling_set_unittest.cc b/cc/resources/picture_layer_tiling_set_unittest.cc index ce4a40a..d2af09a 100644 --- a/cc/resources/picture_layer_tiling_set_unittest.cc +++ b/cc/resources/picture_layer_tiling_set_unittest.cc @@ -63,7 +63,7 @@ class PictureLayerTilingSetTestWithResources : public testing::Test { scoped_ptr<FakeOutputSurface> output_surface = FakeOutputSurface::Create3d(); scoped_ptr<ResourceProvider> resource_provider = - ResourceProvider::Create(output_surface.get()); + ResourceProvider::Create(output_surface.get(), 0); FakePictureLayerTilingClient client; client.SetTileSize(gfx::Size(256, 256)); diff --git a/cc/resources/prioritized_resource_unittest.cc b/cc/resources/prioritized_resource_unittest.cc index b820933..7dd5444 100644 --- a/cc/resources/prioritized_resource_unittest.cc +++ b/cc/resources/prioritized_resource_unittest.cc @@ -22,7 +22,7 @@ class PrioritizedResourceTest : public testing::Test { texture_format_(GL_RGBA), output_surface_(CreateFakeOutputSurface()) { DebugScopedSetImplThread impl_thread(&proxy_); - resource_provider_ = cc::ResourceProvider::Create(output_surface_.get()); + resource_provider_ = cc::ResourceProvider::Create(output_surface_.get(), 0); } virtual ~PrioritizedResourceTest() { @@ -73,6 +73,7 @@ class PrioritizedResourceTest : public testing::Test { void ResourceManagerAssertInvariants( PrioritizedResourceManager* resource_manager) { + #ifndef NDEBUG DebugScopedSetImplThreadAndMainThreadBlocked impl_thread_and_main_thread_blocked(&proxy_); diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index e2b01e4..b58f8e7 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc @@ -133,10 +133,11 @@ ResourceProvider::Child::Child() {} ResourceProvider::Child::~Child() {} scoped_ptr<ResourceProvider> ResourceProvider::Create( - OutputSurface* output_surface) { + OutputSurface* output_surface, + int highp_threshold_min) { scoped_ptr<ResourceProvider> resource_provider( new ResourceProvider(output_surface)); - if (!resource_provider->Initialize()) + if (!resource_provider->Initialize(highp_threshold_min)) return scoped_ptr<ResourceProvider>(); return resource_provider.Pass(); } @@ -598,7 +599,7 @@ ResourceProvider::ResourceProvider(OutputSurface* output_surface) max_texture_size_(0), best_texture_format_(0) {} -bool ResourceProvider::Initialize() { +bool ResourceProvider::Initialize(int highp_threshold_min) { DCHECK(thread_checker_.CalledOnValidThread()); WebGraphicsContext3D* context3d = output_surface_->context3d(); if (!context3d) { @@ -631,8 +632,8 @@ bool ResourceProvider::Initialize() { use_bgra = true; } - texture_copier_ = - AcceleratedTextureCopier::Create(context3d, use_bind_uniform); + texture_copier_ = AcceleratedTextureCopier::Create( + context3d, use_bind_uniform, highp_threshold_min); texture_uploader_ = TextureUploader::Create(context3d, use_map_sub, use_shallow_flush_); diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h index e5001a0..56daa3e 100644 --- a/cc/resources/resource_provider.h +++ b/cc/resources/resource_provider.h @@ -55,7 +55,8 @@ class CC_EXPORT ResourceProvider { Bitmap, }; - static scoped_ptr<ResourceProvider> Create(OutputSurface* output_surface); + static scoped_ptr<ResourceProvider> Create(OutputSurface* output_surface, + int highp_threshold_min); virtual ~ResourceProvider(); @@ -356,7 +357,7 @@ class CC_EXPORT ResourceProvider { } explicit ResourceProvider(OutputSurface* output_surface); - bool Initialize(); + bool Initialize(int highp_threshold_min); const Resource* LockForRead(ResourceId id); void UnlockForRead(ResourceId id); diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc index 7e3d15c..68a6261 100644 --- a/cc/resources/resource_provider_unittest.cc +++ b/cc/resources/resource_provider_unittest.cc @@ -337,7 +337,7 @@ class ResourceProviderTest output_surface_(FakeOutputSurface::Create3d( ResourceProviderContext::Create(shared_data_.get()) .PassAs<WebKit::WebGraphicsContext3D>())), - resource_provider_(ResourceProvider::Create(output_surface_.get())) { + resource_provider_(ResourceProvider::Create(output_surface_.get(), 0)) { resource_provider_->set_default_resource_type(GetParam()); } @@ -487,7 +487,7 @@ TEST_P(ResourceProviderTest, TransferResources) { ResourceProviderContext::Create(shared_data_.get()) .PassAs<WebKit::WebGraphicsContext3D>())); scoped_ptr<ResourceProvider> child_resource_provider( - ResourceProvider::Create(child_output_surface.get())); + ResourceProvider::Create(child_output_surface.get(), 0)); gfx::Size size(1, 1); WGC3Denum format = GL_RGBA; @@ -610,7 +610,7 @@ TEST_P(ResourceProviderTest, DeleteTransferredResources) { ResourceProviderContext::Create(shared_data_.get()) .PassAs<WebKit::WebGraphicsContext3D>())); scoped_ptr<ResourceProvider> child_resource_provider( - ResourceProvider::Create(child_output_surface.get())); + ResourceProvider::Create(child_output_surface.get(), 0)); gfx::Size size(1, 1); WGC3Denum format = GL_RGBA; @@ -667,7 +667,7 @@ TEST_P(ResourceProviderTest, TextureFilters) { ResourceProviderContext::Create(shared_data_.get()) .PassAs<WebKit::WebGraphicsContext3D>())); scoped_ptr<ResourceProvider> child_resource_provider( - ResourceProvider::Create(child_output_surface.get())); + ResourceProvider::Create(child_output_surface.get(), 0)); gfx::Size size(1, 1); WGC3Denum format = GL_RGBA; @@ -858,7 +858,7 @@ TEST_P(ResourceProviderTest, ScopedSampler) { TextureStateTrackingContext* context = static_cast<TextureStateTrackingContext*>(output_surface->context3d()); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get())); + ResourceProvider::Create(output_surface.get(), 0)); gfx::Size size(1, 1); WGC3Denum format = GL_RGBA; @@ -931,7 +931,7 @@ TEST_P(ResourceProviderTest, ManagedResource) { TextureStateTrackingContext* context = static_cast<TextureStateTrackingContext*>(output_surface->context3d()); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get())); + ResourceProvider::Create(output_surface.get(), 0)); gfx::Size size(1, 1); WGC3Denum format = GL_RGBA; @@ -1029,7 +1029,7 @@ TEST_P(ResourceProviderTest, TextureAllocation) { AllocationTrackingContext3D* context = static_cast<AllocationTrackingContext3D*>(output_surface->context3d()); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get())); + ResourceProvider::Create(output_surface.get(), 0)); // Lazy allocation. Don't allocate when creating the resource. EXPECT_CALL(*context, createTexture()).WillOnce(Return(texture_id)); @@ -1102,7 +1102,7 @@ TEST_P(ResourceProviderTest, ForcingAsyncUploadToComplete) { AllocationTrackingContext3D* context = static_cast<AllocationTrackingContext3D*>(output_surface->context3d()); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get())); + ResourceProvider::Create(output_surface.get(), 0)); EXPECT_CALL(*context, createTexture()).WillOnce(Return(texture_id)); EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(3); @@ -1137,7 +1137,7 @@ TEST_P(ResourceProviderTest, AbortForcedAsyncUpload) { AllocationTrackingContext3D* context = static_cast<AllocationTrackingContext3D*>(output_surface->context3d()); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get())); + ResourceProvider::Create(output_surface.get(), 0)); EXPECT_CALL(*context, createTexture()).WillRepeatedly(Return(texture_id)); EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(4); diff --git a/cc/resources/resource_update_controller_unittest.cc b/cc/resources/resource_update_controller_unittest.cc index 8b751c3..5b55bcd 100644 --- a/cc/resources/resource_update_controller_unittest.cc +++ b/cc/resources/resource_update_controller_unittest.cc @@ -137,7 +137,7 @@ class ResourceUpdateControllerTest : public Test { } resource_manager_->PrioritizeTextures(); - resource_provider_ = ResourceProvider::Create(output_surface_.get()); + resource_provider_ = ResourceProvider::Create(output_surface_.get(), 0); } void AppendFullUploadsOfIndexedTextureToUpdateQueue(int count, diff --git a/cc/resources/scoped_resource_unittest.cc b/cc/resources/scoped_resource_unittest.cc index 97e93d2..b08c1e2 100644 --- a/cc/resources/scoped_resource_unittest.cc +++ b/cc/resources/scoped_resource_unittest.cc @@ -16,7 +16,7 @@ namespace { TEST(ScopedResourceTest, NewScopedResource) { scoped_ptr<OutputSurface> context(CreateFakeOutputSurface()); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(context.get())); + ResourceProvider::Create(context.get(), 0)); scoped_ptr<ScopedResource> texture = ScopedResource::create(resource_provider.get()); @@ -31,7 +31,7 @@ TEST(ScopedResourceTest, NewScopedResource) { TEST(ScopedResourceTest, CreateScopedResource) { scoped_ptr<OutputSurface> context(CreateFakeOutputSurface()); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(context.get())); + ResourceProvider::Create(context.get(), 0)); scoped_ptr<ScopedResource> texture = ScopedResource::create(resource_provider.get()); texture->Allocate( @@ -49,7 +49,7 @@ TEST(ScopedResourceTest, CreateScopedResource) { TEST(ScopedResourceTest, ScopedResourceIsDeleted) { scoped_ptr<OutputSurface> context(CreateFakeOutputSurface()); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(context.get())); + ResourceProvider::Create(context.get(), 0)); { scoped_ptr<ScopedResource> texture = ScopedResource::create(resource_provider.get()); @@ -78,7 +78,7 @@ TEST(ScopedResourceTest, ScopedResourceIsDeleted) { TEST(ScopedResourceTest, LeakScopedResource) { scoped_ptr<OutputSurface> context(CreateFakeOutputSurface()); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(context.get())); + ResourceProvider::Create(context.get(), 0)); { scoped_ptr<ScopedResource> texture = ScopedResource::create(resource_provider.get()); diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc index da96c16..abd5a2d 100644 --- a/cc/test/pixel_test.cc +++ b/cc/test/pixel_test.cc @@ -62,12 +62,13 @@ void PixelTest::SetUp() { WebKit::WebGraphicsContext3D::Attributes())); output_surface_.reset(new OutputSurface( context3d.PassAs<WebKit::WebGraphicsContext3D>())); - resource_provider_ = ResourceProvider::Create(output_surface_.get()); + resource_provider_ = ResourceProvider::Create(output_surface_.get(), 0); fake_client_ = make_scoped_ptr(new PixelTestRendererClient(device_viewport_size_)); renderer_ = GLRenderer::Create(fake_client_.get(), output_surface_.get(), - resource_provider_.get()); + resource_provider_.get(), + 0); scoped_refptr<webkit::gpu::ContextProviderInProcess> offscreen_contexts = webkit::gpu::ContextProviderInProcess::Create(); diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 281671e..5361ef0 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -1282,8 +1282,8 @@ bool LayerTreeHostImpl::InitializeRenderer( if (!output_surface->BindToClient(this)) return false; - scoped_ptr<ResourceProvider> resource_provider = - ResourceProvider::Create(output_surface.get()); + scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create( + output_surface.get(), settings_.highp_threshold_min); if (!resource_provider) return false; @@ -1304,7 +1304,8 @@ bool LayerTreeHostImpl::InitializeRenderer( } else if (output_surface->context3d()) { renderer_ = GLRenderer::Create(this, output_surface.get(), - resource_provider.get()); + resource_provider.get(), + settings_.highp_threshold_min); } else if (output_surface->software_device()) { renderer_ = SoftwareRenderer::Create(this, output_surface.get(), diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 19e33e1..5dc4581 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -4276,7 +4276,7 @@ class TestRenderer : public GLRenderer, public RendererClient { TestRenderer(ResourceProvider* resource_provider, OutputSurface* output_surface, Proxy* proxy) - : GLRenderer(this, output_surface, resource_provider) {} + : GLRenderer(this, output_surface, resource_provider, 0) {} private: LayerTreeSettings settings_; @@ -4611,7 +4611,7 @@ TEST_F(LayerTreeHostImplTest, TestRemoveRenderPasses) { scoped_ptr<OutputSurface> output_surface(CreateOutputSurface()); ASSERT_TRUE(output_surface->context3d()); scoped_ptr<ResourceProvider> resource_provider = - ResourceProvider::Create(output_surface.get()); + ResourceProvider::Create(output_surface.get(), 0); scoped_ptr<TestRenderer> renderer = TestRenderer::Create(resource_provider.get(), diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc index 757ab4a..31daa0c 100644 --- a/cc/trees/layer_tree_settings.cc +++ b/cc/trees/layer_tree_settings.cc @@ -51,7 +51,8 @@ LayerTreeSettings::LayerTreeSettings() max_prepaint_tile_distance(4096), // At 256x256 tiles, 128 tiles cover an area of 2048x4096 pixels. max_tiles_for_interest_area(128), - max_unused_resource_memory_percentage(100) { + max_unused_resource_memory_percentage(100), + highp_threshold_min(0) { // TODO(danakj): Renable surface caching when we can do it more realiably. // crbug.com/170713 cache_render_pass_contents = false; diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h index 16eb1ac..d1f8e3c 100644 --- a/cc/trees/layer_tree_settings.h +++ b/cc/trees/layer_tree_settings.h @@ -56,6 +56,7 @@ class CC_EXPORT LayerTreeSettings { size_t max_prepaint_tile_distance; size_t max_tiles_for_interest_area; size_t max_unused_resource_memory_percentage; + int highp_threshold_min; LayerTreeDebugState initial_debug_state; }; |