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* |