summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorbrianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-01 23:03:11 +0000
committerbrianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-01 23:03:11 +0000
commit075d8aae89b630b505f97f437e665cf1968eb4c0 (patch)
treeeb66ede0e1cb085f42500924e9e9fc8c564ffca5 /cc
parent58430f338d50e9df8ca7066652b347b1ef7ff52d (diff)
downloadchromium_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')
-rw-r--r--cc/cc_tests.gyp1
-rw-r--r--cc/debug/fake_web_graphics_context_3d.cc44
-rw-r--r--cc/debug/fake_web_graphics_context_3d.h2
-rw-r--r--cc/layers/nine_patch_layer_unittest.cc2
-rw-r--r--cc/layers/tiled_layer_unittest.cc2
-rw-r--r--cc/output/gl_renderer.cc379
-rw-r--r--cc/output/gl_renderer.h65
-rw-r--r--cc/output/gl_renderer_unittest.cc71
-rw-r--r--cc/output/program_binding.h11
-rw-r--r--cc/output/shader.cc340
-rw-r--r--cc/output/shader.h64
-rw-r--r--cc/output/shader_unittest.cc46
-rw-r--r--cc/output/software_renderer_unittest.cc2
-rw-r--r--cc/output/texture_copier.cc32
-rw-r--r--cc/output/texture_copier.h11
-rw-r--r--cc/output/texture_copier_unittest.cc2
-rw-r--r--cc/resources/picture_layer_tiling_set_unittest.cc2
-rw-r--r--cc/resources/prioritized_resource_unittest.cc3
-rw-r--r--cc/resources/resource_provider.cc11
-rw-r--r--cc/resources/resource_provider.h5
-rw-r--r--cc/resources/resource_provider_unittest.cc18
-rw-r--r--cc/resources/resource_update_controller_unittest.cc2
-rw-r--r--cc/resources/scoped_resource_unittest.cc8
-rw-r--r--cc/test/pixel_test.cc5
-rw-r--r--cc/trees/layer_tree_host_impl.cc7
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc4
-rw-r--r--cc/trees/layer_tree_settings.cc3
-rw-r--r--cc/trees/layer_tree_settings.h1
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;
};