Chromium Code Reviews| Index: cc/output/gl_renderer.cc |
| diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc |
| index e039947695c967740fc7ba88ba0e7df11abea869..ea7fe5ddd7e95b5c11be7160bbc2b38e6ca444d8 100644 |
| --- a/cc/output/gl_renderer.cc |
| +++ b/cc/output/gl_renderer.cc |
| @@ -11,7 +11,13 @@ |
| #include <vector> |
| #include "base/debug/trace_event.h" |
| +#include "base/debug/stack_trace.h" |
| #include "base/logging.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "base/strings/string_split.h" |
| +#include "base/strings/string_util.h" |
| +#include "base/strings/stringprintf.h" |
| +#include "build/build_config.h" |
| #include "cc/base/math_util.h" |
| #include "cc/layers/video_layer_impl.h" |
| #include "cc/output/compositor_frame.h" |
| @@ -25,6 +31,7 @@ |
| #include "cc/quads/picture_draw_quad.h" |
| #include "cc/quads/render_pass.h" |
| #include "cc/quads/stream_video_draw_quad.h" |
| +#include "cc/quads/draw_polygon.h" |
| #include "cc/quads/texture_draw_quad.h" |
| #include "cc/resources/layer_quad.h" |
| #include "cc/resources/scoped_resource.h" |
| @@ -482,10 +489,12 @@ void GLRenderer::DoNoOp() { |
| GLC(gl_, gl_->Flush()); |
| } |
| -void GLRenderer::DoDrawQuad(DrawingFrame* frame, const DrawQuad* quad) { |
| +void GLRenderer::DoDrawQuad(DrawingFrame* frame, |
| + const DrawQuad* quad, |
| + const gfx::QuadF* draw_region) { |
| DCHECK(quad->rect.Contains(quad->visible_rect)); |
| if (quad->material != DrawQuad::TEXTURE_CONTENT) { |
| - FlushTextureQuadCache(); |
| + FlushTextureQuadCache(false); |
| } |
| switch (quad->material) { |
| @@ -493,25 +502,30 @@ void GLRenderer::DoDrawQuad(DrawingFrame* frame, const DrawQuad* quad) { |
| NOTREACHED(); |
| break; |
| case DrawQuad::CHECKERBOARD: |
| - DrawCheckerboardQuad(frame, CheckerboardDrawQuad::MaterialCast(quad)); |
| + DrawCheckerboardQuad( |
| + frame, CheckerboardDrawQuad::MaterialCast(quad), draw_region); |
| break; |
| case DrawQuad::DEBUG_BORDER: |
| DrawDebugBorderQuad(frame, DebugBorderDrawQuad::MaterialCast(quad)); |
| break; |
| case DrawQuad::IO_SURFACE_CONTENT: |
| - DrawIOSurfaceQuad(frame, IOSurfaceDrawQuad::MaterialCast(quad)); |
| + DrawIOSurfaceQuad( |
| + frame, IOSurfaceDrawQuad::MaterialCast(quad), draw_region); |
| break; |
| case DrawQuad::PICTURE_CONTENT: |
| - DrawPictureQuad(frame, PictureDrawQuad::MaterialCast(quad)); |
| + DrawPictureQuad(frame, PictureDrawQuad::MaterialCast(quad), draw_region); |
| break; |
| case DrawQuad::RENDER_PASS: |
| - DrawRenderPassQuad(frame, RenderPassDrawQuad::MaterialCast(quad)); |
| + DrawRenderPassQuad( |
| + frame, RenderPassDrawQuad::MaterialCast(quad), draw_region); |
| break; |
| case DrawQuad::SOLID_COLOR: |
| - DrawSolidColorQuad(frame, SolidColorDrawQuad::MaterialCast(quad)); |
| + DrawSolidColorQuad( |
| + frame, SolidColorDrawQuad::MaterialCast(quad), draw_region); |
| break; |
| case DrawQuad::STREAM_VIDEO_CONTENT: |
| - DrawStreamVideoQuad(frame, StreamVideoDrawQuad::MaterialCast(quad)); |
| + DrawStreamVideoQuad( |
| + frame, StreamVideoDrawQuad::MaterialCast(quad), draw_region); |
| break; |
| case DrawQuad::SURFACE_CONTENT: |
| // Surface content should be fully resolved to other quad types before |
| @@ -519,19 +533,28 @@ void GLRenderer::DoDrawQuad(DrawingFrame* frame, const DrawQuad* quad) { |
| NOTREACHED(); |
| break; |
| case DrawQuad::TEXTURE_CONTENT: |
| - EnqueueTextureQuad(frame, TextureDrawQuad::MaterialCast(quad)); |
| + EnqueueTextureQuad( |
| + frame, TextureDrawQuad::MaterialCast(quad), draw_region); |
| break; |
| case DrawQuad::TILED_CONTENT: |
| - DrawTileQuad(frame, TileDrawQuad::MaterialCast(quad)); |
| + DrawTileQuad(frame, TileDrawQuad::MaterialCast(quad), draw_region); |
| break; |
| case DrawQuad::YUV_VIDEO_CONTENT: |
| - DrawYUVVideoQuad(frame, YUVVideoDrawQuad::MaterialCast(quad)); |
| + DrawYUVVideoQuad( |
| + frame, YUVVideoDrawQuad::MaterialCast(quad), draw_region); |
| break; |
| } |
| } |
| void GLRenderer::DrawCheckerboardQuad(const DrawingFrame* frame, |
| - const CheckerboardDrawQuad* quad) { |
| + const CheckerboardDrawQuad* quad, |
| + const gfx::QuadF* clip_region) { |
| + // TODO(thildebr) For now since checkerboards shouldn't be part of a 3D |
| + // context, clipping regions aren't supported so we skip drawing them |
| + // if this becomes the case. |
| + if (clip_region) { |
| + return; |
| + } |
| SetBlendEnabled(quad->ShouldDrawWithBlending()); |
| const TileCheckerboardProgram* program = GetTileCheckerboardProgram(); |
| @@ -573,6 +596,9 @@ void GLRenderer::DrawCheckerboardQuad(const DrawingFrame* frame, |
| program->vertex_shader().matrix_location()); |
| } |
| +// This function does not handle 3D sorting right now, since the debug border |
| +// quads are just drawn as their original quads and not in split pieces. This |
| +// results in some debug border quads drawing over foreground quads. |
| void GLRenderer::DrawDebugBorderQuad(const DrawingFrame* frame, |
| const DebugBorderDrawQuad* quad) { |
| SetBlendEnabled(quad->ShouldDrawWithBlending()); |
| @@ -952,7 +978,8 @@ scoped_ptr<ScopedResource> GLRenderer::GetBackgroundWithFilters( |
| } |
| void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, |
| - const RenderPassDrawQuad* quad) { |
| + const RenderPassDrawQuad* quad, |
| + const gfx::QuadF* clip_region) { |
| SetBlendEnabled(quad->ShouldDrawWithBlending()); |
| ScopedResource* contents_texture = |
| @@ -1058,8 +1085,25 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, |
| } |
| bool clipped = false; |
| - gfx::QuadF device_quad = MathUtil::MapQuad( |
| - contents_device_transform, SharedGeometryQuad(), &clipped); |
| + // The idea here is to scale the clip_region down to the 1.0x1.0 quad with |
| + // a top corner of -0.5,-0.5 to match the ShaderGeometryQuad(). Unfortunately |
| + // doesn't work properly yet. |
| + gfx::QuadF local_clip_region = SharedGeometryQuad(); |
| + if (clip_region) { |
| + gfx::RectF content_rect(quad->shared_quad_state->content_bounds); |
|
enne (OOO)
2014/09/24 17:35:30
I'm not sure I understand why this is needed. Als
|
| + // Scale this quad down to within the bounds of the SharedGeometryQuad |
| + gfx::PointF p1((clip_region->p1().x() / content_rect.width()) - 0.5f, |
| + (clip_region->p1().y() / content_rect.height()) - 0.5f); |
| + gfx::PointF p2((clip_region->p2().x() / content_rect.width()) - 0.5f, |
| + (clip_region->p2().y() / content_rect.height()) - 0.5f); |
| + gfx::PointF p3((clip_region->p3().x() / content_rect.width()) - 0.5f, |
| + (clip_region->p3().y() / content_rect.height()) - 0.5f); |
| + gfx::PointF p4((clip_region->p4().x() / content_rect.width()) - 0.5f, |
| + (clip_region->p4().y() / content_rect.height()) - 0.5f); |
| + local_clip_region = gfx::QuadF(p1, p2, p3, p4); |
| + } |
| + gfx::QuadF device_quad = |
| + MathUtil::MapQuad(contents_device_transform, local_clip_region, &clipped); |
| LayerQuad device_layer_bounds(gfx::QuadF(device_quad.BoundingBox())); |
| LayerQuad device_layer_edges(device_quad); |
| @@ -1365,6 +1409,59 @@ static void SolidColorUniformLocation(T program, |
| uniforms->color_location = program->fragment_shader().color_location(); |
| } |
| +// This function works in layer space to expand the split resulting quads needed |
| +// for sorting so that they "fill out" towards the edges for the AA that's |
| +// performed within the shaders. It makes sure to grow each sub-quad that |
| +// makes up the original quad by linearly interpolating points out torwards the |
| +// edges. |
| +static void ExpandDrawRegionToAAQuad(const gfx::QuadF& original_quad, |
| + const gfx::QuadF& aa_quad, |
| + gfx::QuadF* draw_region) { |
| + gfx::PointF region_points[] = {draw_region->p1(), draw_region->p2(), |
| + draw_region->p3(), draw_region->p4()}; |
| + |
| + // We find the bounding box of the original quad and the inflated AA quad |
| + // that was developed by SetupQuadForAntiAliasing. |
| + gfx::RectF original_rect = original_quad.BoundingBox(); |
| + gfx::RectF aa_rect = aa_quad.BoundingBox(); |
| + |
| + // For all 4 of the draw region points, we find the factor from 0.0 to 1.0 |
| + // of the X, Y values of the region points within the original quad. Since |
| + // the region quad lives within the boundaries of the original quad instead |
| + // of the AA quad, we need to inflate the values to match those of the AA |
| + // quad, so we apply the same factor, instead to the AA quad, to achieve the |
| + // new draw region points. |
| + // The |delta| values are just the width and height of the quads, and we |
| + // divide the x, y values we get by these to get them normalized from 0.0 |
| + // to 1.0. |
| + float min_x = original_rect.x(); |
| + float min_y = original_rect.y(); |
| + float delta_x = original_rect.width(); |
| + float delta_y = original_rect.height(); |
| + float min_aa_x = aa_rect.x(); |
| + float min_aa_y = aa_rect.y(); |
| + float delta_aa_x = aa_rect.width(); |
| + float delta_aa_y = aa_rect.height(); |
| + |
| + // Here we loop through the 4 vertices of the draw region and apply the |
| + // scaling that we get from x / delta_x, y / delta_y on the original quad |
| + // and apply those factors to delta_aa_x and delta_aa_y to get our final |
| + // points. |
| + for (int i = 0; i < 4; i++) { |
| + float x_factor = 0.0f; |
| + float y_factor = 0.0f; |
| + if (delta_x != 0.0f) |
| + x_factor = (region_points[i].x() - min_x) / delta_x; |
| + if (delta_y != 0.0f) |
| + y_factor = (region_points[i].y() - min_y) / delta_y; |
| + region_points[i].set_x(min_aa_x + (delta_aa_x * x_factor)); |
| + region_points[i].set_y(min_aa_y + (delta_aa_y * y_factor)); |
| + } |
| + |
| + *draw_region = gfx::QuadF( |
| + region_points[0], region_points[1], region_points[2], region_points[3]); |
| +} |
| + |
| // static |
| bool GLRenderer::SetupQuadForAntialiasing( |
| const gfx::Transform& device_transform, |
| @@ -1377,6 +1474,12 @@ bool GLRenderer::SetupQuadForAntialiasing( |
| gfx::QuadF device_layer_quad = MathUtil::MapQuad( |
| device_transform, gfx::QuadF(quad->visibleContentRect()), &clipped); |
| + // The 2d BoundingBox of the quad may still be empty even if the quad |
| + // was not clipped (if the plane is edge-on for example). |
| + if (device_layer_quad.BoundingBox().IsEmpty()) { |
| + return false; |
| + } |
| + |
| bool is_axis_aligned_in_target = device_layer_quad.IsRectilinear(); |
| bool is_nearest_rect_within_epsilon = |
| is_axis_aligned_in_target && |
| @@ -1451,7 +1554,8 @@ bool GLRenderer::SetupQuadForAntialiasing( |
| } |
| void GLRenderer::DrawSolidColorQuad(const DrawingFrame* frame, |
| - const SolidColorDrawQuad* quad) { |
| + const SolidColorDrawQuad* quad, |
| + const gfx::QuadF* clip_region) { |
| gfx::Rect tile_rect = quad->visible_rect; |
| SkColor color = quad->color; |
| @@ -1470,11 +1574,23 @@ void GLRenderer::DrawSolidColorQuad(const DrawingFrame* frame, |
| return; |
| gfx::QuadF local_quad = gfx::QuadF(gfx::RectF(tile_rect)); |
| + gfx::QuadF original_quad = local_quad; |
| float edge[24]; |
| bool use_aa = |
| - settings_->allow_antialiasing && !quad->force_anti_aliasing_off && |
| + settings_->allow_antialiasing && |
| SetupQuadForAntialiasing(device_transform, quad, &local_quad, edge); |
| + gfx::QuadF local_draw_region; |
| + if (!clip_region) { |
| + local_draw_region = local_quad; |
| + } else { |
| + local_draw_region = *clip_region; |
| + } |
| + |
| + if (use_aa) { |
| + ExpandDrawRegionToAAQuad(original_quad, local_quad, &local_draw_region); |
| + } |
| + |
| SolidColorProgramUniforms uniforms; |
| if (use_aa) |
| SolidColorUniformLocation(GetSolidColorProgramAA(), &uniforms); |
| @@ -1501,10 +1617,10 @@ void GLRenderer::DrawSolidColorQuad(const DrawingFrame* frame, |
| // to use antialiasing. |
| SetBlendEnabled(quad->ShouldDrawWithBlending() || use_aa); |
| - // Normalize to tile_rect. |
| - local_quad.Scale(1.0f / tile_rect.width(), 1.0f / tile_rect.height()); |
| + //Normalize to tile_rect. |
| + local_draw_region.Scale(1.0f / tile_rect.width(), 1.0f / tile_rect.height()); |
| - SetShaderQuadF(local_quad, uniforms.quad_location); |
| + SetShaderQuadF(local_draw_region, uniforms.quad_location); |
| // The transform and vertex data are used to figure out the extents that the |
| // un-antialiased quad should have and which vertex this is and the float |
| @@ -1546,13 +1662,15 @@ static void TileUniformLocation(T program, TileProgramUniforms* uniforms) { |
| } |
| void GLRenderer::DrawTileQuad(const DrawingFrame* frame, |
| - const TileDrawQuad* quad) { |
| - DrawContentQuad(frame, quad, quad->resource_id); |
| + const TileDrawQuad* quad, |
| + const gfx::QuadF* clip_region) { |
| + DrawContentQuad(frame, quad, quad->resource_id, clip_region); |
| } |
| void GLRenderer::DrawContentQuad(const DrawingFrame* frame, |
| const ContentDrawQuadBase* quad, |
| - ResourceProvider::ResourceId resource_id) { |
| + ResourceProvider::ResourceId resource_id, |
| + const gfx::QuadF* clip_region) { |
| gfx::Rect tile_rect = quad->visible_rect; |
| gfx::RectF tex_coord_rect = MathUtil::ScaleRectProportional( |
| @@ -1599,11 +1717,23 @@ void GLRenderer::DrawContentQuad(const DrawingFrame* frame, |
| return; |
| gfx::QuadF local_quad = gfx::QuadF(gfx::RectF(tile_rect)); |
| + gfx::QuadF original_quad = local_quad; |
| float edge[24]; |
| bool use_aa = |
| settings_->allow_antialiasing && |
| SetupQuadForAntialiasing(device_transform, quad, &local_quad, edge); |
| + gfx::QuadF local_draw_region; |
| + if (!clip_region) { |
| + local_draw_region = local_quad; |
| + } else { |
| + local_draw_region = *clip_region; |
| + } |
| + |
| + if (use_aa) { |
| + ExpandDrawRegionToAAQuad(original_quad, local_quad, &local_draw_region); |
| + } |
| + |
| bool scaled = (tex_to_geom_scale_x != 1.f || tex_to_geom_scale_y != 1.f); |
| GLenum filter = (use_aa || scaled || |
| !quad->quadTransform().IsIdentityOrIntegerTranslation()) |
| @@ -1707,10 +1837,9 @@ void GLRenderer::DrawContentQuad(const DrawingFrame* frame, |
| SetBlendEnabled(quad->ShouldDrawWithBlending() || use_aa); |
| // Normalize to tile_rect. |
| - local_quad.Scale(1.0f / tile_rect.width(), 1.0f / tile_rect.height()); |
| - |
| + local_draw_region.Scale(1.0f / tile_rect.width(), 1.0f / tile_rect.height()); |
| SetShaderOpacity(quad->opacity(), uniforms.alpha_location); |
| - SetShaderQuadF(local_quad, uniforms.quad_location); |
| + SetShaderQuadF(local_draw_region, uniforms.quad_location); |
| // The transform and vertex data are used to figure out the extents that the |
| // un-antialiased quad should have and which vertex this is and the float |
| @@ -1724,7 +1853,8 @@ void GLRenderer::DrawContentQuad(const DrawingFrame* frame, |
| } |
| void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame, |
| - const YUVVideoDrawQuad* quad) { |
| + const YUVVideoDrawQuad* quad, |
| + const gfx::QuadF* clip_region) { |
| SetBlendEnabled(quad->ShouldDrawWithBlending()); |
| TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired( |
| @@ -1843,15 +1973,28 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame, |
| break; |
| } |
| + // The transform and vertex data are used to figure out the extents that the |
| + // un-antialiased quad should have and which vertex this is and the float |
| + // quad passed in via uniform is the actual geometry that gets used to draw |
| + // it. This is why this centered rect is used and not the original quad_rect. |
| + gfx::RectF tile_rect = quad->visible_rect; |
| GLC(gl_, gl_->UniformMatrix3fv(yuv_matrix_location, 1, 0, yuv_to_rgb)); |
| GLC(gl_, gl_->Uniform3fv(yuv_adj_location, 1, yuv_adjust)); |
| SetShaderOpacity(quad->opacity(), alpha_location); |
| - DrawQuadGeometry(frame, quad->quadTransform(), quad->rect, matrix_location); |
| + if (!clip_region) { |
| + DrawQuadGeometry(frame, quad->quadTransform(), tile_rect, matrix_location); |
| + } else { |
| + gfx::QuadF region_quad = *clip_region; |
| + region_quad.Scale(1.0f / tile_rect.width(), 1.0f / tile_rect.height()); |
| + DrawQuadGeometryClippedByQuadF( |
| + frame, quad->quadTransform(), tile_rect, region_quad, matrix_location); |
| + } |
| } |
| void GLRenderer::DrawStreamVideoQuad(const DrawingFrame* frame, |
| - const StreamVideoDrawQuad* quad) { |
| + const StreamVideoDrawQuad* quad, |
| + const gfx::QuadF* clip_region) { |
| SetBlendEnabled(quad->ShouldDrawWithBlending()); |
| static float gl_matrix[16]; |
| @@ -1882,14 +2025,23 @@ void GLRenderer::DrawStreamVideoQuad(const DrawingFrame* frame, |
| SetShaderOpacity(quad->opacity(), |
| program->fragment_shader().alpha_location()); |
| - DrawQuadGeometry(frame, |
| - quad->quadTransform(), |
| - quad->rect, |
| - program->vertex_shader().matrix_location()); |
| + if (!clip_region) { |
| + DrawQuadGeometry(frame, |
| + quad->quadTransform(), |
| + quad->rect, |
| + program->vertex_shader().matrix_location()); |
| + } else { |
| + DrawQuadGeometryClippedByQuadF(frame, |
| + quad->quadTransform(), |
| + quad->rect, |
| + *clip_region, |
| + program->vertex_shader().matrix_location()); |
| + } |
| } |
| void GLRenderer::DrawPictureQuad(const DrawingFrame* frame, |
| - const PictureDrawQuad* quad) { |
| + const PictureDrawQuad* quad, |
| + const gfx::QuadF* clip_region) { |
| if (on_demand_tile_raster_bitmap_.width() != quad->texture_size.width() || |
| on_demand_tile_raster_bitmap_.height() != quad->texture_size.height()) { |
| on_demand_tile_raster_bitmap_.allocN32Pixels(quad->texture_size.width(), |
| @@ -1933,7 +2085,7 @@ void GLRenderer::DrawPictureQuad(const DrawingFrame* frame, |
| gfx::Rect(quad->texture_size), |
| gfx::Vector2d()); |
| - DrawContentQuad(frame, quad, on_demand_tile_raster_resource_id_); |
| + DrawContentQuad(frame, quad, on_demand_tile_raster_resource_id_, clip_region); |
| } |
| struct TextureProgramBinding { |
| @@ -1949,6 +2101,7 @@ struct TextureProgramBinding { |
| int program_id; |
| int sampler_location; |
| int matrix_location; |
| + int transform_location; |
| int background_color_location; |
| }; |
| @@ -1964,10 +2117,17 @@ struct TexTransformTextureProgramBinding : TextureProgramBinding { |
| int vertex_opacity_location; |
| }; |
| -void GLRenderer::FlushTextureQuadCache() { |
| +void GLRenderer::FlushTextureQuadCache(bool using_clip_region) { |
| // Check to see if we have anything to draw. |
| if (draw_cache_.program_id == 0) |
| return; |
| +/* |
| + if (!using_clip_region) { |
| + shared_geometry_->PrepareForDraw(); |
| + } else { |
| + clipped_geometry_->PrepareForDraw(); |
| + } |
| +*/ |
| // Set the correct blending mode. |
| SetBlendEnabled(draw_cache_.needs_blending); |
| @@ -2026,10 +2186,34 @@ void GLRenderer::FlushTextureQuadCache() { |
| draw_cache_.uv_xform_data.resize(0); |
| draw_cache_.vertex_opacity_data.resize(0); |
| draw_cache_.matrix_data.resize(0); |
| +/* |
| + if (using_clip_region) { |
| + shared_geometry_->PrepareForDraw(); |
| + }*/ |
| +} |
| + |
| +void PrintQuad(const gfx::QuadF& quad) { |
| + LOG(ERROR) << "quad"; |
| + LOG(ERROR) << quad.p1().x() << ", " << quad.p1().y(); |
| + LOG(ERROR) << quad.p2().x() << ", " << quad.p2().y(); |
| + LOG(ERROR) << quad.p3().x() << ", " << quad.p3().y(); |
| + LOG(ERROR) << quad.p4().x() << ", " << quad.p4().y(); |
| } |
| void GLRenderer::EnqueueTextureQuad(const DrawingFrame* frame, |
| - const TextureDrawQuad* quad) { |
| + const TextureDrawQuad* quad, |
| + const gfx::QuadF* clip_region) { |
| + //TODO(awoloszyn):: THIS IS VERY SUSPICIOUS, this is going to invole |
| + // a huge amount of state swapping where it may not be necessary |
| + // Here we need to flush out everything that's already in the cache because |
| + // we need to enqueue a single quad, switch geometry bindings, and then |
| + // flush that single quad. |
| + if (clip_region) { |
| + // We send in false here because we want to flush what's currently in the |
| + // queue using the shared_geometry and not clipped_geometry |
| +// FlushTextureQuadCache(false); |
| + } |
| + |
| TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired( |
| gl_, |
| &highp_threshold_cache_, |
| @@ -2060,7 +2244,7 @@ void GLRenderer::EnqueueTextureQuad(const DrawingFrame* frame, |
| draw_cache_.needs_blending != quad->ShouldDrawWithBlending() || |
| draw_cache_.background_color != quad->background_color || |
| draw_cache_.matrix_data.size() >= 8) { |
| - FlushTextureQuadCache(); |
| + FlushTextureQuadCache(false); |
| draw_cache_.program_id = binding.program_id; |
| draw_cache_.resource_id = resource_id; |
| draw_cache_.needs_blending = quad->ShouldDrawWithBlending(); |
| @@ -2074,7 +2258,12 @@ void GLRenderer::EnqueueTextureQuad(const DrawingFrame* frame, |
| } |
| // Generate the uv-transform |
| - draw_cache_.uv_xform_data.push_back(UVTransform(quad)); |
| + if (!clip_region) { |
| + draw_cache_.uv_xform_data.push_back(UVTransform(quad)); |
| + } else { |
| + Float4 uv_transform = {{0.0f, 0.0f, 1.0f, 1.0f}}; |
| + draw_cache_.uv_xform_data.push_back(uv_transform); |
| + } |
| // Generate the vertex opacity |
| const float opacity = quad->opacity(); |
| @@ -2091,10 +2280,40 @@ void GLRenderer::EnqueueTextureQuad(const DrawingFrame* frame, |
| Float16 m; |
| quad_rect_matrix.matrix().asColMajorf(m.data); |
| draw_cache_.matrix_data.push_back(m); |
| + |
| + if (clip_region) { |
| + // Now we make the clip_region fit inside the regular SharedGeometryQuad |
| + // and send that in to be rendered. |
| + gfx::PointF p1(clip_region->p1().x() * (1.0f / quad->rect.width()) - 0.5f, |
| + clip_region->p1().y() * (1.0f / quad->rect.height()) - 0.5f); |
| + gfx::PointF p2(clip_region->p2().x() * (1.0f / quad->rect.width()) - 0.5f, |
| + clip_region->p2().y() * (1.0f / quad->rect.height()) - 0.5f); |
| + gfx::PointF p3(clip_region->p3().x() * (1.0f / quad->rect.width()) - 0.5f, |
| + clip_region->p3().y() * (1.0f / quad->rect.height()) - 0.5f); |
| + gfx::PointF p4(clip_region->p4().x() * (1.0f / quad->rect.width()) - 0.5f, |
| + clip_region->p4().y() * (1.0f / quad->rect.height()) - 0.5f); |
| + gfx::QuadF scaled_region(p1, p2, p3, p4); |
| + |
| + float uv[8]; |
| + uv[0] = p1.x() + 0.5f; |
| + uv[1] = p1.y() + 0.5f; |
| + uv[2] = p2.x() + 0.5f; |
| + uv[3] = p2.y() + 0.5f; |
| + uv[4] = p3.x() + 0.5f; |
| + uv[5] = p3.y() + 0.5f; |
| + uv[6] = p4.x() + 0.5f; |
| + uv[7] = p4.y() + 0.5f; |
| + |
| + clipped_geometry_->InitializeCustomQuadWithUVs(scaled_region, uv); |
| + //TODO(awoloszyn) Again, if we flush with EVERY call, we are doing something |
| + //wrong |
| + //FlushTextureQuadCache(true); |
| + } |
| } |
| void GLRenderer::DrawIOSurfaceQuad(const DrawingFrame* frame, |
| - const IOSurfaceDrawQuad* quad) { |
| + const IOSurfaceDrawQuad* quad, |
| + const gfx::QuadF* clip_region) { |
| SetBlendEnabled(quad->ShouldDrawWithBlending()); |
| TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired( |
| @@ -2133,8 +2352,16 @@ void GLRenderer::DrawIOSurfaceQuad(const DrawingFrame* frame, |
| DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_)); |
| GLC(gl_, gl_->BindTexture(GL_TEXTURE_RECTANGLE_ARB, lock.texture_id())); |
| - DrawQuadGeometry( |
| - frame, quad->quadTransform(), quad->rect, binding.matrix_location); |
| + if (!clip_region) { |
| + DrawQuadGeometry( |
| + frame, quad->quadTransform(), quad->rect, binding.matrix_location); |
| + } else { |
| + DrawQuadGeometryClippedByQuadF(frame, |
| + quad->quadTransform(), |
| + quad->rect, |
| + *clip_region, |
| + binding.matrix_location); |
| + } |
| GLC(gl_, gl_->BindTexture(GL_TEXTURE_RECTANGLE_ARB, 0)); |
| } |
| @@ -2155,7 +2382,9 @@ void GLRenderer::FinishDrawingFrame(DrawingFrame* frame) { |
| ScheduleOverlays(frame); |
| } |
| -void GLRenderer::FinishDrawingQuadList() { FlushTextureQuadCache(); } |
| +void GLRenderer::FinishDrawingQuadList() { |
| + FlushTextureQuadCache(false); |
| +} |
| bool GLRenderer::FlippedFramebuffer() const { return true; } |
| @@ -2163,7 +2392,7 @@ void GLRenderer::EnsureScissorTestEnabled() { |
| if (is_scissor_enabled_) |
| return; |
| - FlushTextureQuadCache(); |
| + FlushTextureQuadCache(false); |
| GLC(gl_, gl_->Enable(GL_SCISSOR_TEST)); |
| is_scissor_enabled_ = true; |
| } |
| @@ -2172,7 +2401,7 @@ void GLRenderer::EnsureScissorTestDisabled() { |
| if (!is_scissor_enabled_) |
| return; |
| - FlushTextureQuadCache(); |
| + FlushTextureQuadCache(false); |
| GLC(gl_, gl_->Disable(GL_SCISSOR_TEST)); |
| is_scissor_enabled_ = false; |
| } |
| @@ -2241,10 +2470,30 @@ void GLRenderer::SetUseProgram(unsigned program) { |
| program_shadow_ = program; |
| } |
| +void GLRenderer::DrawQuadGeometryClippedByQuadF( |
| + const DrawingFrame* frame, |
| + const gfx::Transform& draw_transform, |
| + const gfx::RectF& quad_rect, |
| + const gfx::QuadF& clipping_region_quad, |
| + int matrix_location) { |
| +// clipped_geometry_->PrepareForDraw(); |
| + clipped_geometry_->InitializeCustomQuad(clipping_region_quad); |
| + static float gl_matrix[16]; |
| + ToGLMatrix(&gl_matrix[0], frame->projection_matrix); |
| + GLC(gl_, gl_->UniformMatrix4fv(matrix_location, 1, false, &gl_matrix[0])); |
| + |
| + GLC(gl_, |
| + gl_->DrawElements(GL_TRIANGLES, |
| + 6, |
| + GL_UNSIGNED_SHORT, |
| + reinterpret_cast<const void*>(0))); |
| +} |
| + |
| void GLRenderer::DrawQuadGeometry(const DrawingFrame* frame, |
| const gfx::Transform& draw_transform, |
| const gfx::RectF& quad_rect, |
| int matrix_location) { |
| +// shared_geometry_->PrepareForDraw(); |
| gfx::Transform quad_rect_matrix; |
| QuadRectTransform(&quad_rect_matrix, draw_transform, quad_rect); |
| static float gl_matrix[16]; |
| @@ -2668,9 +2917,8 @@ void GLRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) { |
| // may cause undesired GPU pipeline flushes. |
| if (scissor_rect == scissor_rect_ && !scissor_rect_needs_reset_) |
| return; |
| - |
| scissor_rect_ = scissor_rect; |
| - FlushTextureQuadCache(); |
| + FlushTextureQuadCache(false); |
| GLC(gl_, |
| gl_->Scissor(scissor_rect.x(), |
| scissor_rect.y(), |
| @@ -2695,8 +2943,10 @@ void GLRenderer::InitializeSharedObjects() { |
| // Create an FBO for doing offscreen rendering. |
| GLC(gl_, gl_->GenFramebuffers(1, &offscreen_framebuffer_id_)); |
| - shared_geometry_ = make_scoped_ptr( |
| - new GeometryBinding(gl_, QuadVertexRect())); |
| + shared_geometry_ = |
| + make_scoped_ptr(new GeometryBinding(gl_, QuadVertexRect(), 8)); |
| + clipped_geometry_ = |
| + make_scoped_ptr(new GeometryBindingQuad(gl_, QuadVertexRect())); |
| } |
| const GLRenderer::TileCheckerboardProgram* |