binding.dart 4.31 KB
Newer Older
1 2 3 4
// 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.

5
import 'dart:ui' as ui show window;
6

7
import 'package:flutter/gestures.dart';
8
import 'package:flutter/scheduler.dart';
Ian Hickson's avatar
Ian Hickson committed
9
import 'package:flutter/services.dart';
10
import 'package:mojo/core.dart' as core;
Hixie's avatar
Hixie committed
11
import 'package:sky_services/semantics/semantics.mojom.dart' as mojom;
12 13

import 'box.dart';
14
import 'debug.dart';
15 16
import 'object.dart';
import 'view.dart';
Hixie's avatar
Hixie committed
17
import 'semantics.dart';
18

Ian Hickson's avatar
Ian Hickson committed
19
export 'package:flutter/gestures.dart' show HitTestResult;
20

Florian Loitsch's avatar
Florian Loitsch committed
21
/// The glue between the render tree and the Flutter engine.
22
abstract class Renderer extends Object with Scheduler, Services
Ian Hickson's avatar
Ian Hickson committed
23
  implements HitTestable {
24

25
  @override
Ian Hickson's avatar
Ian Hickson committed
26 27
  void initInstances() {
    super.initInstances();
28
    _instance = this;
Ian Hickson's avatar
Ian Hickson committed
29 30
    ui.window.onMetricsChanged = handleMetricsChanged;
    initRenderView();
31
    initSemantics();
32
    assert(renderView != null);
33 34 35 36
    assert(() {
      initServiceExtensions();
      return true;
    });
Ian Hickson's avatar
Ian Hickson committed
37 38
    addPersistentFrameCallback(_handlePersistentFrameCallback);
  }
39

Ian Hickson's avatar
Ian Hickson committed
40 41
  static Renderer _instance;
  static Renderer get instance => _instance;
42

Ian Hickson's avatar
Ian Hickson committed
43 44 45 46
  void initRenderView() {
    if (renderView == null) {
      renderView = new RenderView();
      renderView.scheduleInitialFrame();
47
    }
48
    handleMetricsChanged(); // configures renderView's metrics
49 50
  }

51 52 53 54
  /// The render tree's owner, which maintains dirty state for layout,
  /// composite, paint, and accessibility semantics
  final PipelineOwner pipelineOwner = new PipelineOwner();

Florian Loitsch's avatar
Florian Loitsch committed
55
  /// The render tree that's attached to the output surface.
56
  RenderView get renderView => _renderView;
57
  RenderView _renderView;
Ian Hickson's avatar
Ian Hickson committed
58
  void set renderView(RenderView value) {
59
    assert(value != null);
Ian Hickson's avatar
Ian Hickson committed
60 61 62 63 64
    if (_renderView == value)
      return;
    if (_renderView != null)
      _renderView.detach();
    _renderView = value;
65
    _renderView.attach(pipelineOwner);
66 67
  }

Ian Hickson's avatar
Ian Hickson committed
68
  void handleMetricsChanged() {
69
    assert(renderView != null);
70
    renderView.configuration = new ViewConfiguration(size: ui.window.size);
71 72
  }

73 74
  void initSemantics() {
    SemanticsNode.onSemanticsEnabled = renderView.scheduleInitialSemantics;
75
    shell.provideService(mojom.SemanticsServer.serviceName, (core.MojoMessagePipeEndpoint endpoint) {
76 77
      mojom.SemanticsServerStub server = new mojom.SemanticsServerStub.fromEndpoint(endpoint);
      server.impl = new SemanticsServer();
78
    });
Hixie's avatar
Hixie committed
79 80
  }

81 82 83 84
  void _handlePersistentFrameCallback(Duration timeStamp) {
    beginFrame();
  }

Ian Hickson's avatar
Ian Hickson committed
85
  /// Pump the rendering pipeline to generate a frame.
86
  void beginFrame() {
87
    assert(renderView != null);
88 89 90
    pipelineOwner.flushLayout();
    pipelineOwner.flushCompositingBits();
    pipelineOwner.flushPaint();
Hixie's avatar
Hixie committed
91
    renderView.compositeFrame(); // this sends the bits to the GPU
92
    if (SemanticsNode.hasListeners) {
93
      pipelineOwner.flushSemantics();
94
      SemanticsNode.sendSemanticsTree();
Hixie's avatar
Hixie committed
95
    }
96 97
  }

98
  @override
Ian Hickson's avatar
Ian Hickson committed
99
  void hitTest(HitTestResult result, Point position) {
100 101
    assert(renderView != null);
    renderView.hitTest(result, position: position);
Ian Hickson's avatar
Ian Hickson committed
102
    super.hitTest(result, position);
103
  }
104
}
105

Florian Loitsch's avatar
Florian Loitsch committed
106
/// Prints a textual representation of the entire render tree.
107
void debugDumpRenderTree() {
108
  debugPrint(Renderer.instance?.renderView?.toStringDeep());
109
}
110

Florian Loitsch's avatar
Florian Loitsch committed
111
/// Prints a textual representation of the entire layer tree.
112
void debugDumpLayerTree() {
113
  debugPrint(Renderer.instance?.renderView?.layer?.toStringDeep());
Ian Hickson's avatar
Ian Hickson committed
114 115
}

Hixie's avatar
Hixie committed
116 117 118 119
/// Prints a textual representation of the entire semantics tree.
/// This will only work if there is a semantics client attached.
/// Otherwise, the tree is empty and this will print "null".
void debugDumpSemanticsTree() {
120
  debugPrint(Renderer.instance?.renderView?.debugSemantics?.toStringDeep() ?? 'Semantics not collected.');
Hixie's avatar
Hixie committed
121 122
}

Ian Hickson's avatar
Ian Hickson committed
123 124
/// A concrete binding for applications that use the Rendering framework
/// directly. This is the glue that binds the framework to the Flutter engine.
125 126 127 128 129 130 131
///
/// You would only use this binding if you are writing to the
/// rendering layer directly. If you are writing to a higher-level
/// library, such as the Flutter Widgets library, then you would use
/// that layer's binding.
///
/// See also [BindingBase].
132
class RenderingFlutterBinding extends BindingBase with Scheduler, Gesturer, Services, Renderer {
Ian Hickson's avatar
Ian Hickson committed
133
  RenderingFlutterBinding({ RenderBox root }) {
134
    assert(renderView != null);
Ian Hickson's avatar
Ian Hickson committed
135 136
    renderView.child = root;
  }
137
}