| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/output/ca_layer_overlay.h" | 5 #include "cc/output/ca_layer_overlay.h" |
| 6 | 6 |
| 7 #include "base/metrics/histogram_macros.h" | 7 #include "base/metrics/histogram_macros.h" |
| 8 #include "cc/quads/render_pass_draw_quad.h" | 8 #include "cc/quads/render_pass_draw_quad.h" |
| 9 #include "cc/quads/solid_color_draw_quad.h" | 9 #include "cc/quads/solid_color_draw_quad.h" |
| 10 #include "cc/quads/stream_video_draw_quad.h" | 10 #include "cc/quads/stream_video_draw_quad.h" |
| 11 #include "cc/quads/texture_draw_quad.h" | 11 #include "cc/quads/texture_draw_quad.h" |
| 12 #include "cc/quads/tile_draw_quad.h" | 12 #include "cc/quads/tile_draw_quad.h" |
| 13 #include "cc/resources/resource_provider.h" | 13 #include "cc/resources/resource_provider.h" |
| 14 #include "gpu/GLES2/gl2extchromium.h" | 14 #include "gpu/GLES2/gl2extchromium.h" |
| 15 | 15 |
| 16 namespace cc { | 16 namespace cc { |
| 17 | 17 |
| 18 namespace { | 18 namespace { |
| 19 | 19 |
| 20 // If there are too many RenderPassDrawQuads, we shouldn't use Core Animation to |
| 21 // present them as individual layers, since that potentially doubles the amount |
| 22 // of work needed to present them. cc has to blit them into an IOSurface, and |
| 23 // then Core Animation has to blit them to the final surface. |
| 24 // https://crbug.com/636884. |
| 25 const int kTooManyRenderPassDrawQuads = 30; |
| 26 |
| 20 // This enum is used for histogram states and should only have new values added | 27 // This enum is used for histogram states and should only have new values added |
| 21 // to the end before COUNT. | 28 // to the end before COUNT. |
| 22 enum CALayerResult { | 29 enum CALayerResult { |
| 23 CA_LAYER_SUCCESS = 0, | 30 CA_LAYER_SUCCESS = 0, |
| 24 CA_LAYER_FAILED_UNKNOWN, | 31 CA_LAYER_FAILED_UNKNOWN, |
| 25 CA_LAYER_FAILED_IO_SURFACE_NOT_CANDIDATE, | 32 CA_LAYER_FAILED_IO_SURFACE_NOT_CANDIDATE, |
| 26 CA_LAYER_FAILED_STREAM_VIDEO_NOT_CANDIDATE, | 33 CA_LAYER_FAILED_STREAM_VIDEO_NOT_CANDIDATE, |
| 27 CA_LAYER_FAILED_STREAM_VIDEO_TRANSFORM, | 34 CA_LAYER_FAILED_STREAM_VIDEO_TRANSFORM, |
| 28 CA_LAYER_FAILED_TEXTURE_NOT_CANDIDATE, | 35 CA_LAYER_FAILED_TEXTURE_NOT_CANDIDATE, |
| 29 CA_LAYER_FAILED_TEXTURE_Y_FLIPPED, | 36 CA_LAYER_FAILED_TEXTURE_Y_FLIPPED, |
| 30 CA_LAYER_FAILED_TILE_NOT_CANDIDATE, | 37 CA_LAYER_FAILED_TILE_NOT_CANDIDATE, |
| 31 CA_LAYER_FAILED_QUAD_BLEND_MODE, | 38 CA_LAYER_FAILED_QUAD_BLEND_MODE, |
| 32 CA_LAYER_FAILED_QUAD_TRANSFORM, | 39 CA_LAYER_FAILED_QUAD_TRANSFORM, |
| 33 CA_LAYER_FAILED_QUAD_CLIPPING, | 40 CA_LAYER_FAILED_QUAD_CLIPPING, |
| 34 CA_LAYER_FAILED_DEBUG_BORDER, | 41 CA_LAYER_FAILED_DEBUG_BORDER, |
| 35 CA_LAYER_FAILED_PICTURE_CONTENT, | 42 CA_LAYER_FAILED_PICTURE_CONTENT, |
| 36 CA_LAYER_FAILED_RENDER_PASS, | 43 CA_LAYER_FAILED_RENDER_PASS, |
| 37 CA_LAYER_FAILED_SURFACE_CONTENT, | 44 CA_LAYER_FAILED_SURFACE_CONTENT, |
| 38 CA_LAYER_FAILED_YUV_VIDEO_CONTENT, | 45 CA_LAYER_FAILED_YUV_VIDEO_CONTENT, |
| 39 CA_LAYER_FAILED_DIFFERENT_CLIP_SETTINGS, | 46 CA_LAYER_FAILED_DIFFERENT_CLIP_SETTINGS, |
| 40 CA_LAYER_FAILED_DIFFERENT_VERTEX_OPACITIES, | 47 CA_LAYER_FAILED_DIFFERENT_VERTEX_OPACITIES, |
| 41 CA_LAYER_FAILED_RENDER_PASS_FILTER_SCALE, | 48 CA_LAYER_FAILED_RENDER_PASS_FILTER_SCALE, |
| 42 CA_LAYER_FAILED_RENDER_PASS_BACKGROUND_FILTERS, | 49 CA_LAYER_FAILED_RENDER_PASS_BACKGROUND_FILTERS, |
| 43 CA_LAYER_FAILED_RENDER_PASS_MASK, | 50 CA_LAYER_FAILED_RENDER_PASS_MASK, |
| 44 CA_LAYER_FAILED_RENDER_PASS_FILTER_OPERATION, | 51 CA_LAYER_FAILED_RENDER_PASS_FILTER_OPERATION, |
| 45 CA_LAYER_FAILED_RENDER_PASS_SORTING_CONTEXT_ID, | 52 CA_LAYER_FAILED_RENDER_PASS_SORTING_CONTEXT_ID, |
| 53 CA_LAYER_FAILED_TOO_MANY_RENDER_PASS_DRAW_QUADS, |
| 46 CA_LAYER_FAILED_COUNT, | 54 CA_LAYER_FAILED_COUNT, |
| 47 }; | 55 }; |
| 48 | 56 |
| 49 bool FilterOperationSupported(const FilterOperation& operation) { | 57 bool FilterOperationSupported(const FilterOperation& operation) { |
| 50 switch (operation.type()) { | 58 switch (operation.type()) { |
| 51 case FilterOperation::GRAYSCALE: | 59 case FilterOperation::GRAYSCALE: |
| 52 case FilterOperation::SEPIA: | 60 case FilterOperation::SEPIA: |
| 53 case FilterOperation::SATURATE: | 61 case FilterOperation::SATURATE: |
| 54 case FilterOperation::HUE_ROTATE: | 62 case FilterOperation::HUE_ROTATE: |
| 55 case FilterOperation::INVERT: | 63 case FilterOperation::INVERT: |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 1.f / quad->texture_size.height()); | 160 1.f / quad->texture_size.height()); |
| 153 return CA_LAYER_SUCCESS; | 161 return CA_LAYER_SUCCESS; |
| 154 } | 162 } |
| 155 | 163 |
| 156 class CALayerOverlayProcessor { | 164 class CALayerOverlayProcessor { |
| 157 public: | 165 public: |
| 158 CALayerResult FromDrawQuad(ResourceProvider* resource_provider, | 166 CALayerResult FromDrawQuad(ResourceProvider* resource_provider, |
| 159 const gfx::RectF& display_rect, | 167 const gfx::RectF& display_rect, |
| 160 const DrawQuad* quad, | 168 const DrawQuad* quad, |
| 161 CALayerOverlay* ca_layer_overlay, | 169 CALayerOverlay* ca_layer_overlay, |
| 162 bool* skip) { | 170 bool* skip, |
| 171 bool* render_pass_draw_quad) { |
| 163 if (quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode) | 172 if (quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode) |
| 164 return CA_LAYER_FAILED_QUAD_BLEND_MODE; | 173 return CA_LAYER_FAILED_QUAD_BLEND_MODE; |
| 165 | 174 |
| 166 // Early-out for invisible quads. | 175 // Early-out for invisible quads. |
| 167 if (quad->shared_quad_state->opacity == 0.f) { | 176 if (quad->shared_quad_state->opacity == 0.f) { |
| 168 *skip = true; | 177 *skip = true; |
| 169 return CA_LAYER_SUCCESS; | 178 return CA_LAYER_SUCCESS; |
| 170 } | 179 } |
| 171 | 180 |
| 172 // Enable edge anti-aliasing only on layer boundaries. | 181 // Enable edge anti-aliasing only on layer boundaries. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 193 | 202 |
| 194 most_recent_overlay_shared_state_->opacity = | 203 most_recent_overlay_shared_state_->opacity = |
| 195 quad->shared_quad_state->opacity; | 204 quad->shared_quad_state->opacity; |
| 196 most_recent_overlay_shared_state_->transform = | 205 most_recent_overlay_shared_state_->transform = |
| 197 quad->shared_quad_state->quad_to_target_transform.matrix(); | 206 quad->shared_quad_state->quad_to_target_transform.matrix(); |
| 198 } | 207 } |
| 199 ca_layer_overlay->shared_state = most_recent_overlay_shared_state_; | 208 ca_layer_overlay->shared_state = most_recent_overlay_shared_state_; |
| 200 | 209 |
| 201 ca_layer_overlay->bounds_rect = gfx::RectF(quad->rect); | 210 ca_layer_overlay->bounds_rect = gfx::RectF(quad->rect); |
| 202 | 211 |
| 212 *render_pass_draw_quad = quad->material == DrawQuad::RENDER_PASS; |
| 203 switch (quad->material) { | 213 switch (quad->material) { |
| 204 case DrawQuad::TEXTURE_CONTENT: | 214 case DrawQuad::TEXTURE_CONTENT: |
| 205 return FromTextureQuad(resource_provider, | 215 return FromTextureQuad(resource_provider, |
| 206 TextureDrawQuad::MaterialCast(quad), | 216 TextureDrawQuad::MaterialCast(quad), |
| 207 ca_layer_overlay); | 217 ca_layer_overlay); |
| 208 case DrawQuad::TILED_CONTENT: | 218 case DrawQuad::TILED_CONTENT: |
| 209 return FromTileQuad(resource_provider, TileDrawQuad::MaterialCast(quad), | 219 return FromTileQuad(resource_provider, TileDrawQuad::MaterialCast(quad), |
| 210 ca_layer_overlay); | 220 ca_layer_overlay); |
| 211 case DrawQuad::SOLID_COLOR: | 221 case DrawQuad::SOLID_COLOR: |
| 212 return FromSolidColorDrawQuad(SolidColorDrawQuad::MaterialCast(quad), | 222 return FromSolidColorDrawQuad(SolidColorDrawQuad::MaterialCast(quad), |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 | 257 |
| 248 CALayerOverlay::~CALayerOverlay() {} | 258 CALayerOverlay::~CALayerOverlay() {} |
| 249 | 259 |
| 250 bool ProcessForCALayerOverlays(ResourceProvider* resource_provider, | 260 bool ProcessForCALayerOverlays(ResourceProvider* resource_provider, |
| 251 const gfx::RectF& display_rect, | 261 const gfx::RectF& display_rect, |
| 252 const QuadList& quad_list, | 262 const QuadList& quad_list, |
| 253 CALayerOverlayList* ca_layer_overlays) { | 263 CALayerOverlayList* ca_layer_overlays) { |
| 254 CALayerResult result = CA_LAYER_SUCCESS; | 264 CALayerResult result = CA_LAYER_SUCCESS; |
| 255 ca_layer_overlays->reserve(quad_list.size()); | 265 ca_layer_overlays->reserve(quad_list.size()); |
| 256 | 266 |
| 267 int render_pass_draw_quad_count = 0; |
| 257 CALayerOverlayProcessor processor; | 268 CALayerOverlayProcessor processor; |
| 258 for (auto it = quad_list.BackToFrontBegin(); it != quad_list.BackToFrontEnd(); | 269 for (auto it = quad_list.BackToFrontBegin(); it != quad_list.BackToFrontEnd(); |
| 259 ++it) { | 270 ++it) { |
| 260 const DrawQuad* quad = *it; | 271 const DrawQuad* quad = *it; |
| 261 CALayerOverlay ca_layer; | 272 CALayerOverlay ca_layer; |
| 262 bool skip = false; | 273 bool skip = false; |
| 274 bool render_pass_draw_quad = false; |
| 263 result = processor.FromDrawQuad(resource_provider, display_rect, quad, | 275 result = processor.FromDrawQuad(resource_provider, display_rect, quad, |
| 264 &ca_layer, &skip); | 276 &ca_layer, &skip, &render_pass_draw_quad); |
| 265 if (result != CA_LAYER_SUCCESS) | 277 if (result != CA_LAYER_SUCCESS) |
| 266 break; | 278 break; |
| 267 | 279 |
| 280 if (render_pass_draw_quad) { |
| 281 ++render_pass_draw_quad_count; |
| 282 if (render_pass_draw_quad_count > kTooManyRenderPassDrawQuads) { |
| 283 result = CA_LAYER_FAILED_TOO_MANY_RENDER_PASS_DRAW_QUADS; |
| 284 break; |
| 285 } |
| 286 } |
| 287 |
| 268 if (skip) | 288 if (skip) |
| 269 continue; | 289 continue; |
| 270 | 290 |
| 271 // It is not possible to correctly represent two different clipping settings | 291 // It is not possible to correctly represent two different clipping settings |
| 272 // within one sorting context. | 292 // within one sorting context. |
| 273 if (!ca_layer_overlays->empty()) { | 293 if (!ca_layer_overlays->empty()) { |
| 274 const CALayerOverlay& previous_ca_layer = ca_layer_overlays->back(); | 294 const CALayerOverlay& previous_ca_layer = ca_layer_overlays->back(); |
| 275 if (ca_layer.shared_state->sorting_context_id && | 295 if (ca_layer.shared_state->sorting_context_id && |
| 276 previous_ca_layer.shared_state->sorting_context_id == | 296 previous_ca_layer.shared_state->sorting_context_id == |
| 277 ca_layer.shared_state->sorting_context_id) { | 297 ca_layer.shared_state->sorting_context_id) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 292 CA_LAYER_FAILED_COUNT); | 312 CA_LAYER_FAILED_COUNT); |
| 293 | 313 |
| 294 if (result != CA_LAYER_SUCCESS) { | 314 if (result != CA_LAYER_SUCCESS) { |
| 295 ca_layer_overlays->clear(); | 315 ca_layer_overlays->clear(); |
| 296 return false; | 316 return false; |
| 297 } | 317 } |
| 298 return true; | 318 return true; |
| 299 } | 319 } |
| 300 | 320 |
| 301 } // namespace cc | 321 } // namespace cc |
| OLD | NEW |