Chromium Code Reviews| 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.h" | 7 #include "base/metrics/histogram.h" |
| 8 #include "cc/quads/solid_color_draw_quad.h" | 8 #include "cc/quads/solid_color_draw_quad.h" |
| 9 #include "cc/quads/stream_video_draw_quad.h" | 9 #include "cc/quads/stream_video_draw_quad.h" |
| 10 #include "cc/quads/texture_draw_quad.h" | 10 #include "cc/quads/texture_draw_quad.h" |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 71 const TextureDrawQuad* quad, | 71 const TextureDrawQuad* quad, |
| 72 CALayerOverlay* ca_layer_overlay) { | 72 CALayerOverlay* ca_layer_overlay) { |
| 73 unsigned resource_id = quad->resource_id(); | 73 unsigned resource_id = quad->resource_id(); |
| 74 if (!resource_provider->IsOverlayCandidate(resource_id)) | 74 if (!resource_provider->IsOverlayCandidate(resource_id)) |
| 75 return CA_LAYER_FAILED_TEXTURE_NOT_CANDIDATE; | 75 return CA_LAYER_FAILED_TEXTURE_NOT_CANDIDATE; |
| 76 if (quad->y_flipped) { | 76 if (quad->y_flipped) { |
| 77 // The anchor point is at the bottom-left corner of the CALayer. The | 77 // The anchor point is at the bottom-left corner of the CALayer. The |
| 78 // transformation that flips the contents of the layer without changing its | 78 // transformation that flips the contents of the layer without changing its |
| 79 // frame is the composition of a vertical flip about the anchor point, and a | 79 // frame is the composition of a vertical flip about the anchor point, and a |
| 80 // translation by the height of the layer. | 80 // translation by the height of the layer. |
| 81 ca_layer_overlay->transform.preTranslate( | 81 ca_layer_overlay->shared_state->transform.preTranslate( |
| 82 0, ca_layer_overlay->bounds_rect.height(), 0); | 82 0, ca_layer_overlay->bounds_rect.height(), 0); |
| 83 ca_layer_overlay->transform.preScale(1, -1, 1); | 83 ca_layer_overlay->shared_state->transform.preScale(1, -1, 1); |
| 84 } | 84 } |
| 85 ca_layer_overlay->contents_resource_id = resource_id; | 85 ca_layer_overlay->contents_resource_id = resource_id; |
| 86 ca_layer_overlay->contents_rect = | 86 ca_layer_overlay->contents_rect = |
| 87 BoundingRect(quad->uv_top_left, quad->uv_bottom_right); | 87 BoundingRect(quad->uv_top_left, quad->uv_bottom_right); |
| 88 ca_layer_overlay->background_color = quad->background_color; | 88 ca_layer_overlay->background_color = quad->background_color; |
| 89 for (int i = 1; i < 4; ++i) { | 89 for (int i = 1; i < 4; ++i) { |
| 90 if (quad->vertex_opacity[i] != quad->vertex_opacity[0]) | 90 if (quad->vertex_opacity[i] != quad->vertex_opacity[0]) |
| 91 return CA_LAYER_FAILED_DIFFERENT_VERTEX_OPACITIES; | 91 return CA_LAYER_FAILED_DIFFERENT_VERTEX_OPACITIES; |
| 92 } | 92 } |
| 93 ca_layer_overlay->opacity *= quad->vertex_opacity[0]; | 93 ca_layer_overlay->shared_state->opacity *= quad->vertex_opacity[0]; |
| 94 ca_layer_overlay->filter = quad->nearest_neighbor ? GL_NEAREST : GL_LINEAR; | 94 ca_layer_overlay->filter = quad->nearest_neighbor ? GL_NEAREST : GL_LINEAR; |
| 95 return CA_LAYER_SUCCESS; | 95 return CA_LAYER_SUCCESS; |
| 96 } | 96 } |
| 97 | 97 |
| 98 CALayerResult FromTileQuad(ResourceProvider* resource_provider, | 98 CALayerResult FromTileQuad(ResourceProvider* resource_provider, |
| 99 const TileDrawQuad* quad, | 99 const TileDrawQuad* quad, |
| 100 CALayerOverlay* ca_layer_overlay) { | 100 CALayerOverlay* ca_layer_overlay) { |
| 101 unsigned resource_id = quad->resource_id(); | 101 unsigned resource_id = quad->resource_id(); |
| 102 if (!resource_provider->IsOverlayCandidate(resource_id)) | 102 if (!resource_provider->IsOverlayCandidate(resource_id)) |
| 103 return CA_LAYER_FAILED_TILE_NOT_CANDIDATE; | 103 return CA_LAYER_FAILED_TILE_NOT_CANDIDATE; |
| 104 ca_layer_overlay->contents_resource_id = resource_id; | 104 ca_layer_overlay->contents_resource_id = resource_id; |
| 105 ca_layer_overlay->contents_rect = quad->tex_coord_rect; | 105 ca_layer_overlay->contents_rect = quad->tex_coord_rect; |
| 106 ca_layer_overlay->contents_rect.Scale(1.f / quad->texture_size.width(), | 106 ca_layer_overlay->contents_rect.Scale(1.f / quad->texture_size.width(), |
| 107 1.f / quad->texture_size.height()); | 107 1.f / quad->texture_size.height()); |
| 108 return CA_LAYER_SUCCESS; | 108 return CA_LAYER_SUCCESS; |
| 109 } | 109 } |
| 110 | 110 |
| 111 CALayerResult FromDrawQuad(ResourceProvider* resource_provider, | 111 class CALayerOverlayProcessor { |
| 112 const gfx::RectF& display_rect, | 112 public: |
| 113 const DrawQuad* quad, | 113 CALayerResult FromDrawQuad(ResourceProvider* resource_provider, |
| 114 CALayerOverlay* ca_layer_overlay, | 114 const gfx::RectF& display_rect, |
| 115 bool* skip) { | 115 const DrawQuad* quad, |
| 116 if (quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode) | 116 CALayerOverlay* ca_layer_overlay, |
| 117 return CA_LAYER_FAILED_QUAD_BLEND_MODE; | 117 bool* skip) { |
| 118 if (quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode) | |
| 119 return CA_LAYER_FAILED_QUAD_BLEND_MODE; | |
| 118 | 120 |
| 119 // Early-out for invisible quads. | 121 // Early-out for invisible quads. |
| 120 if (quad->shared_quad_state->opacity == 0.f) { | 122 if (quad->shared_quad_state->opacity == 0.f) { |
| 121 *skip = true; | 123 *skip = true; |
| 122 return CA_LAYER_SUCCESS; | 124 return CA_LAYER_SUCCESS; |
| 125 } | |
| 126 | |
| 127 // Enable edge anti-aliasing only on layer boundaries. | |
| 128 ca_layer_overlay->edge_aa_mask = 0; | |
| 129 if (quad->IsLeftEdge()) | |
| 130 ca_layer_overlay->edge_aa_mask |= GL_CA_LAYER_EDGE_LEFT_CHROMIUM; | |
| 131 if (quad->IsRightEdge()) | |
| 132 ca_layer_overlay->edge_aa_mask |= GL_CA_LAYER_EDGE_RIGHT_CHROMIUM; | |
| 133 if (quad->IsBottomEdge()) | |
| 134 ca_layer_overlay->edge_aa_mask |= GL_CA_LAYER_EDGE_BOTTOM_CHROMIUM; | |
| 135 if (quad->IsTopEdge()) | |
| 136 ca_layer_overlay->edge_aa_mask |= GL_CA_LAYER_EDGE_TOP_CHROMIUM; | |
| 137 | |
| 138 if (most_recent_shared_quad_state_ != quad->shared_quad_state) { | |
| 139 most_recent_shared_quad_state_ = quad->shared_quad_state; | |
| 140 most_recent_overlay_shared_state_ = new CALayerOverlaySharedState; | |
| 141 // Set rect clipping and sorting context ID. | |
| 142 most_recent_overlay_shared_state_->sorting_context_id = | |
| 143 quad->shared_quad_state->sorting_context_id; | |
| 144 most_recent_overlay_shared_state_->is_clipped = | |
| 145 quad->shared_quad_state->is_clipped; | |
| 146 most_recent_overlay_shared_state_->clip_rect = | |
| 147 gfx::RectF(quad->shared_quad_state->clip_rect); | |
| 148 | |
| 149 most_recent_overlay_shared_state_->opacity = | |
| 150 quad->shared_quad_state->opacity; | |
| 151 most_recent_overlay_shared_state_->transform = | |
| 152 quad->shared_quad_state->quad_to_target_transform.matrix(); | |
| 153 } | |
| 154 ca_layer_overlay->shared_state = most_recent_overlay_shared_state_; | |
| 155 | |
| 156 ca_layer_overlay->bounds_rect = gfx::RectF(quad->rect); | |
| 157 | |
| 158 switch (quad->material) { | |
| 159 case DrawQuad::TEXTURE_CONTENT: | |
| 160 return FromTextureQuad(resource_provider, | |
| 161 TextureDrawQuad::MaterialCast(quad), | |
| 162 ca_layer_overlay); | |
| 163 case DrawQuad::TILED_CONTENT: | |
| 164 return FromTileQuad(resource_provider, TileDrawQuad::MaterialCast(quad), | |
| 165 ca_layer_overlay); | |
| 166 case DrawQuad::SOLID_COLOR: | |
| 167 return FromSolidColorDrawQuad(SolidColorDrawQuad::MaterialCast(quad), | |
| 168 ca_layer_overlay, skip); | |
| 169 case DrawQuad::STREAM_VIDEO_CONTENT: | |
| 170 return FromStreamVideoQuad(resource_provider, | |
| 171 StreamVideoDrawQuad::MaterialCast(quad), | |
| 172 ca_layer_overlay); | |
| 173 case DrawQuad::DEBUG_BORDER: | |
| 174 return CA_LAYER_FAILED_DEBUG_BORDER; | |
| 175 case DrawQuad::PICTURE_CONTENT: | |
| 176 return CA_LAYER_FAILED_PICTURE_CONTENT; | |
| 177 case DrawQuad::RENDER_PASS: | |
| 178 return CA_LAYER_FAILED_RENDER_PASS; | |
| 179 case DrawQuad::SURFACE_CONTENT: | |
| 180 return CA_LAYER_FAILED_SURFACE_CONTENT; | |
| 181 case DrawQuad::YUV_VIDEO_CONTENT: | |
| 182 return CA_LAYER_FAILED_YUV_VIDEO_CONTENT; | |
| 183 default: | |
| 184 break; | |
| 185 } | |
| 186 | |
| 187 return CA_LAYER_FAILED_UNKNOWN; | |
| 123 } | 188 } |
| 124 | 189 |
| 125 // Enable edge anti-aliasing only on layer boundaries. | 190 private: |
| 126 ca_layer_overlay->edge_aa_mask = 0; | 191 const SharedQuadState* most_recent_shared_quad_state_ = nullptr; |
| 127 if (quad->IsLeftEdge()) | 192 scoped_refptr<CALayerOverlaySharedState> most_recent_overlay_shared_state_; |
| 128 ca_layer_overlay->edge_aa_mask |= GL_CA_LAYER_EDGE_LEFT_CHROMIUM; | 193 }; |
| 129 if (quad->IsRightEdge()) | |
| 130 ca_layer_overlay->edge_aa_mask |= GL_CA_LAYER_EDGE_RIGHT_CHROMIUM; | |
| 131 if (quad->IsBottomEdge()) | |
| 132 ca_layer_overlay->edge_aa_mask |= GL_CA_LAYER_EDGE_BOTTOM_CHROMIUM; | |
| 133 if (quad->IsTopEdge()) | |
| 134 ca_layer_overlay->edge_aa_mask |= GL_CA_LAYER_EDGE_TOP_CHROMIUM; | |
| 135 | |
| 136 // Set rect clipping and sorting context ID. | |
| 137 ca_layer_overlay->sorting_context_id = | |
| 138 quad->shared_quad_state->sorting_context_id; | |
| 139 ca_layer_overlay->is_clipped = quad->shared_quad_state->is_clipped; | |
| 140 ca_layer_overlay->clip_rect = gfx::RectF(quad->shared_quad_state->clip_rect); | |
| 141 | |
| 142 ca_layer_overlay->opacity = quad->shared_quad_state->opacity; | |
| 143 ca_layer_overlay->bounds_rect = gfx::RectF(quad->rect); | |
| 144 ca_layer_overlay->transform = | |
| 145 quad->shared_quad_state->quad_to_target_transform.matrix(); | |
| 146 | |
| 147 switch (quad->material) { | |
| 148 case DrawQuad::TEXTURE_CONTENT: | |
| 149 return FromTextureQuad(resource_provider, | |
| 150 TextureDrawQuad::MaterialCast(quad), | |
| 151 ca_layer_overlay); | |
| 152 case DrawQuad::TILED_CONTENT: | |
| 153 return FromTileQuad(resource_provider, TileDrawQuad::MaterialCast(quad), | |
| 154 ca_layer_overlay); | |
| 155 case DrawQuad::SOLID_COLOR: | |
| 156 return FromSolidColorDrawQuad(SolidColorDrawQuad::MaterialCast(quad), | |
| 157 ca_layer_overlay, skip); | |
| 158 case DrawQuad::STREAM_VIDEO_CONTENT: | |
| 159 return FromStreamVideoQuad(resource_provider, | |
| 160 StreamVideoDrawQuad::MaterialCast(quad), | |
| 161 ca_layer_overlay); | |
| 162 case DrawQuad::DEBUG_BORDER: | |
| 163 return CA_LAYER_FAILED_DEBUG_BORDER; | |
| 164 case DrawQuad::PICTURE_CONTENT: | |
| 165 return CA_LAYER_FAILED_PICTURE_CONTENT; | |
| 166 case DrawQuad::RENDER_PASS: | |
| 167 return CA_LAYER_FAILED_RENDER_PASS; | |
| 168 case DrawQuad::SURFACE_CONTENT: | |
| 169 return CA_LAYER_FAILED_SURFACE_CONTENT; | |
| 170 case DrawQuad::YUV_VIDEO_CONTENT: | |
| 171 return CA_LAYER_FAILED_YUV_VIDEO_CONTENT; | |
| 172 default: | |
| 173 break; | |
| 174 } | |
| 175 | |
| 176 return CA_LAYER_FAILED_UNKNOWN; | |
| 177 } | |
| 178 | 194 |
| 179 } // namespace | 195 } // namespace |
| 180 | 196 |
| 181 CALayerOverlay::CALayerOverlay() : filter(GL_LINEAR) {} | 197 CALayerOverlay::CALayerOverlay() : filter(GL_LINEAR) {} |
| 182 | 198 |
| 183 CALayerOverlay::CALayerOverlay(const CALayerOverlay& other) = default; | 199 CALayerOverlay::CALayerOverlay(const CALayerOverlay& other) = default; |
| 184 | 200 |
| 185 CALayerOverlay::~CALayerOverlay() {} | 201 CALayerOverlay::~CALayerOverlay() {} |
| 186 | 202 |
| 187 bool ProcessForCALayerOverlays(ResourceProvider* resource_provider, | 203 bool ProcessForCALayerOverlays(ResourceProvider* resource_provider, |
| 188 const gfx::RectF& display_rect, | 204 const gfx::RectF& display_rect, |
| 189 const QuadList& quad_list, | 205 const QuadList& quad_list, |
| 190 CALayerOverlayList* ca_layer_overlays) { | 206 CALayerOverlayList* ca_layer_overlays) { |
| 191 CALayerResult result = CA_LAYER_SUCCESS; | 207 CALayerResult result = CA_LAYER_SUCCESS; |
| 192 ca_layer_overlays->reserve(quad_list.size()); | 208 ca_layer_overlays->reserve(quad_list.size()); |
| 193 | 209 |
| 210 CALayerOverlayProcessor processor; | |
|
ccameron
2016/07/18 22:56:57
Maybe roll resource provider and display rect into
erikchen
2016/07/19 00:15:27
Good suggestion, maybe in a future CL?
| |
| 194 for (auto it = quad_list.BackToFrontBegin(); it != quad_list.BackToFrontEnd(); | 211 for (auto it = quad_list.BackToFrontBegin(); it != quad_list.BackToFrontEnd(); |
| 195 ++it) { | 212 ++it) { |
| 196 const DrawQuad* quad = *it; | 213 const DrawQuad* quad = *it; |
| 197 CALayerOverlay ca_layer; | 214 CALayerOverlay ca_layer; |
| 198 bool skip = false; | 215 bool skip = false; |
| 199 result = | 216 result = processor.FromDrawQuad(resource_provider, display_rect, quad, |
| 200 FromDrawQuad(resource_provider, display_rect, quad, &ca_layer, &skip); | 217 &ca_layer, &skip); |
| 201 if (result != CA_LAYER_SUCCESS) | 218 if (result != CA_LAYER_SUCCESS) |
| 202 break; | 219 break; |
| 203 | 220 |
| 204 if (skip) | 221 if (skip) |
| 205 continue; | 222 continue; |
| 206 | 223 |
| 207 // It is not possible to correctly represent two different clipping settings | 224 // It is not possible to correctly represent two different clipping settings |
| 208 // within one sorting context. | 225 // within one sorting context. |
| 209 if (!ca_layer_overlays->empty()) { | 226 if (!ca_layer_overlays->empty()) { |
| 210 const CALayerOverlay& previous_ca_layer = ca_layer_overlays->back(); | 227 const CALayerOverlay& previous_ca_layer = ca_layer_overlays->back(); |
| 211 if (ca_layer.sorting_context_id && | 228 if (ca_layer.shared_state->sorting_context_id && |
| 212 previous_ca_layer.sorting_context_id == ca_layer.sorting_context_id) { | 229 previous_ca_layer.shared_state->sorting_context_id == |
| 213 if (previous_ca_layer.is_clipped != ca_layer.is_clipped || | 230 ca_layer.shared_state->sorting_context_id) { |
| 214 previous_ca_layer.clip_rect != ca_layer.clip_rect) { | 231 if (previous_ca_layer.shared_state->is_clipped != |
| 232 ca_layer.shared_state->is_clipped || | |
| 233 previous_ca_layer.shared_state->clip_rect != | |
| 234 ca_layer.shared_state->clip_rect) { | |
| 215 result = CA_LAYER_FAILED_DIFFERENT_CLIP_SETTINGS; | 235 result = CA_LAYER_FAILED_DIFFERENT_CLIP_SETTINGS; |
| 216 break; | 236 break; |
| 217 } | 237 } |
| 218 } | 238 } |
| 219 } | 239 } |
| 220 | 240 |
| 221 ca_layer_overlays->push_back(ca_layer); | 241 ca_layer_overlays->push_back(ca_layer); |
| 222 } | 242 } |
| 223 | 243 |
| 224 UMA_HISTOGRAM_ENUMERATION("Compositing.Renderer.CALayerResult", result, | 244 UMA_HISTOGRAM_ENUMERATION("Compositing.Renderer.CALayerResult", result, |
| 225 CA_LAYER_FAILED_COUNT); | 245 CA_LAYER_FAILED_COUNT); |
| 226 | 246 |
| 227 if (result != CA_LAYER_SUCCESS) { | 247 if (result != CA_LAYER_SUCCESS) { |
| 228 ca_layer_overlays->clear(); | 248 ca_layer_overlays->clear(); |
| 229 return false; | 249 return false; |
| 230 } | 250 } |
| 231 return true; | 251 return true; |
| 232 } | 252 } |
| 233 | 253 |
| 234 } // namespace cc | 254 } // namespace cc |
| OLD | NEW |