Amir Hardon bebedc379d Add an overlay surface on top of embedded UIViews. (flutter/engine#6726)
The overlay surfaces are going to be the same IOSSurface implementation
with the platform views controller set to null (so these are surfaces
that don't support embedding platform views to them).

  * Adds a FlutterOverlayView which is a UIView that's showing an
    overlay surface.
  * Creates an overlay surface for each embedded UIView (done in
    FlutterPlatformViewsController).
  * Changes CompositeEmbeddedView to return a new canvas.
  * Makes the PlatformViewLayer replace the PaintContext's canvas with
    the canvas for the overlay view.
  * Changed canvas in PaintContext to be a pointer so it can be changed.

TBD in following PRs:
  * Copy the current canvas state when replacing a canvas in PaintContext.
  * Make FlutterOverlayView work with a GL backend (currently it only
    works with software rendering)
2018-11-01 17:45:16 -07:00

63 lines
2.2 KiB
C++

// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/flow/layers/clip_rrect_layer.h"
namespace flow {
ClipRRectLayer::ClipRRectLayer(Clip clip_behavior)
: clip_behavior_(clip_behavior) {}
ClipRRectLayer::~ClipRRectLayer() = default;
void ClipRRectLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
SkRect child_paint_bounds = SkRect::MakeEmpty();
PrerollChildren(context, matrix, &child_paint_bounds);
if (child_paint_bounds.intersect(clip_rrect_.getBounds())) {
set_paint_bounds(child_paint_bounds);
}
}
#if defined(OS_FUCHSIA)
void ClipRRectLayer::UpdateScene(SceneUpdateContext& context) {
FML_DCHECK(needs_system_composite());
// TODO(MZ-137): Need to be able to express the radii as vectors.
scenic::RoundedRectangle shape(
context.session(), // session
clip_rrect_.width(), // width
clip_rrect_.height(), // height
clip_rrect_.radii(SkRRect::kUpperLeft_Corner).x(), // top_left_radius
clip_rrect_.radii(SkRRect::kUpperRight_Corner).x(), // top_right_radius
clip_rrect_.radii(SkRRect::kLowerRight_Corner)
.x(), // bottom_right_radius
clip_rrect_.radii(SkRRect::kLowerLeft_Corner).x() // bottom_left_radius
);
// TODO(liyuqian): respect clip_behavior_
SceneUpdateContext::Clip clip(context, shape, clip_rrect_.getBounds());
UpdateSceneChildren(context);
}
#endif // defined(OS_FUCHSIA)
void ClipRRectLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "ClipRRectLayer::Paint");
FML_DCHECK(needs_painting());
SkAutoCanvasRestore save(context.canvas, true);
context.canvas->clipRRect(clip_rrect_, clip_behavior_ != Clip::hardEdge);
if (clip_behavior_ == Clip::antiAliasWithSaveLayer) {
context.canvas->saveLayer(paint_bounds(), nullptr);
}
PaintChildren(context);
if (clip_behavior_ == Clip::antiAliasWithSaveLayer) {
context.canvas->restore();
}
}
} // namespace flow