Home | History | Annotate | Download | only in output
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "cc/output/overlay_strategy_single_on_top.h"
      6 
      7 #include "cc/quads/draw_quad.h"
      8 #include "cc/quads/texture_draw_quad.h"
      9 #include "ui/gfx/geometry/rect_conversions.h"
     10 #include "ui/gfx/transform.h"
     11 
     12 namespace cc {
     13 
     14 OverlayStrategySingleOnTop::OverlayStrategySingleOnTop(
     15     OverlayCandidateValidator* capability_checker,
     16     ResourceProvider* resource_provider)
     17     : capability_checker_(capability_checker),
     18       resource_provider_(resource_provider) {}
     19 
     20 bool OverlayStrategySingleOnTop::Attempt(
     21     RenderPassList* render_passes_in_draw_order,
     22     OverlayCandidateList* candidate_list) {
     23   // Only attempt to handle very simple case for now.
     24   if (!capability_checker_)
     25     return false;
     26 
     27   RenderPass* root_render_pass = render_passes_in_draw_order->back();
     28   DCHECK(root_render_pass);
     29 
     30   QuadList& quad_list = root_render_pass->quad_list;
     31   QuadList::Iterator candidate_iterator = quad_list.end();
     32   for (QuadList::Iterator it = quad_list.begin(); it != quad_list.end(); ++it) {
     33     const DrawQuad* draw_quad = &*it;
     34     if (draw_quad->material == DrawQuad::TEXTURE_CONTENT) {
     35       const TextureDrawQuad& quad = *TextureDrawQuad::MaterialCast(draw_quad);
     36       if (!resource_provider_->AllowOverlay(quad.resource_id)) {
     37         continue;
     38       }
     39       // Check that no prior quads overlap it.
     40       bool intersects = false;
     41       gfx::RectF rect = draw_quad->rect;
     42       draw_quad->quadTransform().TransformRect(&rect);
     43       for (QuadList::Iterator overlap_iter = quad_list.begin();
     44            overlap_iter != it;
     45            ++overlap_iter) {
     46         gfx::RectF overlap_rect = overlap_iter->rect;
     47         overlap_iter->quadTransform().TransformRect(&overlap_rect);
     48         if (rect.Intersects(overlap_rect)) {
     49           intersects = true;
     50           break;
     51         }
     52       }
     53       if (intersects)
     54         continue;
     55       candidate_iterator = it;
     56       break;
     57     }
     58   }
     59   if (candidate_iterator == quad_list.end())
     60     return false;
     61   const TextureDrawQuad& quad =
     62       *TextureDrawQuad::MaterialCast(&*candidate_iterator);
     63 
     64   // Simple quads only.
     65   gfx::OverlayTransform overlay_transform =
     66       OverlayCandidate::GetOverlayTransform(quad.quadTransform(), quad.flipped);
     67   if (overlay_transform == gfx::OVERLAY_TRANSFORM_INVALID ||
     68       !quad.quadTransform().IsIdentityOrTranslation() || quad.needs_blending ||
     69       quad.shared_quad_state->opacity != 1.f ||
     70       quad.shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode ||
     71       quad.premultiplied_alpha || quad.background_color != SK_ColorTRANSPARENT)
     72     return false;
     73 
     74   // Add our primary surface.
     75   OverlayCandidateList candidates;
     76   OverlayCandidate main_image;
     77   main_image.display_rect = root_render_pass->output_rect;
     78   main_image.format = RGBA_8888;
     79   candidates.push_back(main_image);
     80 
     81   // Add the overlay.
     82   OverlayCandidate candidate;
     83   candidate.transform = overlay_transform;
     84   candidate.display_rect =
     85       OverlayCandidate::GetOverlayRect(quad.quadTransform(), quad.rect);
     86   candidate.uv_rect = BoundingRect(quad.uv_top_left, quad.uv_bottom_right);
     87   candidate.format = RGBA_8888;
     88   candidate.resource_id = quad.resource_id;
     89   candidate.plane_z_order = 1;
     90   candidates.push_back(candidate);
     91 
     92   // Check for support.
     93   capability_checker_->CheckOverlaySupport(&candidates);
     94 
     95   // If the candidate can be handled by an overlay, create a pass for it.
     96   if (candidates[1].overlay_handled) {
     97     quad_list.EraseAndInvalidateAllPointers(candidate_iterator);
     98     candidate_list->swap(candidates);
     99     return true;
    100   }
    101   return false;
    102 }
    103 
    104 }  // namespace cc
    105