summaryrefslogtreecommitdiffstats
path: root/ui/compositor/paint_context.h
blob: a754ee469858b80a69c22be61b744aa9c006be79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// 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.

#ifndef UI_COMPOSITOR_PAINT_CONTEXT_H_
#define UI_COMPOSITOR_PAINT_CONTEXT_H_

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "ui/compositor/compositor_export.h"
#include "ui/gfx/geometry/rect.h"

namespace cc {
class DisplayItemList;
}

namespace gfx {
class Canvas;
}

class SkPictureRecorder;

namespace ui {
class ClipTransformRecorder;
class CompositingRecorder;
class PaintRecorder;

class COMPOSITOR_EXPORT PaintContext {
 public:
  // Construct a PaintContext that may only re-paint the area in the
  // |invalidation|.
  PaintContext(gfx::Canvas* canvas, const gfx::Rect& invalidation);

  // Construct a PaintContext that may only re-paint the area in the
  // |invalidation|.
  PaintContext(cc::DisplayItemList* list,
               float device_scale_factor,
               const gfx::Rect& bounds,
               const gfx::Rect& invalidation);

  // Construct a PaintContext that will re-paint everything (no consideration
  // for invalidation).
  explicit PaintContext(gfx::Canvas* canvas);

  PaintContext(const PaintContext& other);

  ~PaintContext();

  // Clone a PaintContext with an additional |offset|.
  PaintContext CloneWithPaintOffset(const gfx::Vector2d& offset) const {
    return PaintContext(*this, offset);
  }

  // Clone a PaintContext that has no consideration for invalidation.
  PaintContext CloneWithoutInvalidation() const {
    return PaintContext(canvas_);
  }

  // When true, IsRectInvalid() can be called, otherwise its result would be
  // invalid.
  bool CanCheckInvalid() const { return !invalidation_.IsEmpty(); }

  // When true, if a thing is not invalidated it does not need to paint itself.
  // When false, everything should provide an output when painting regardless of
  // being invalidated in order to remain visible.
  bool ShouldEarlyOutOfPaintingWhenValid() const { return !!canvas_; }

  // When true, the |bounds| touches an invalidated area, so should be
  // re-painted. When false, re-painting can be skipped. Bounds should be in
  // the local space with offsets up to the painting root in the PaintContext.
  bool IsRectInvalid(const gfx::Rect& bounds) const {
    DCHECK(CanCheckInvalid());
    return invalidation_.Intersects(bounds + offset_);
  }

#if DCHECK_IS_ON()
  void Visited(void* visited) const {
    if (!root_visited_)
      root_visited_ = visited;
  }
  void* RootVisited() const { return root_visited_; }
  const gfx::Vector2d& PaintOffset() const { return offset_; }
#endif

  const gfx::Rect& InvalidationForTesting() const { return invalidation_; }

 private:
  // The Recorder classes need access to the internal canvas and friends, but we
  // don't want to expose them on this class so that people must go through the
  // recorders to access them.
  friend class ClipTransformRecorder;
  friend class CompositingRecorder;
  friend class PaintRecorder;
  // The Cache class also needs to access the DisplayItemList to append its
  // cache contents.
  friend class PaintCache;

  PaintContext& operator=(const PaintContext& other) = delete;

  // Clone a PaintContext with an additional |offset|.
  PaintContext(const PaintContext& other, const gfx::Vector2d& offset);

  gfx::Canvas* canvas_;
  cc::DisplayItemList* list_;
  scoped_ptr<SkPictureRecorder> recorder_;
  // The device scale of the frame being painted. Used to determine which bitmap
  // resources to use in the frame.
  float device_scale_factor_;
  // The bounds of the area being painted. Not all of it may be invalidated from
  // the previous frame.
  gfx::Rect bounds_;
  // Invalidation in the space of the paint root (ie the space of the layer
  // backing the paint taking place).
  gfx::Rect invalidation_;
  // Offset from the PaintContext to the space of the paint root and the
  // |invalidation_|.
  gfx::Vector2d offset_;

#if DCHECK_IS_ON()
  // Used to verify that the |invalidation_| is only used to compare against
  // rects in the same space.
  mutable void* root_visited_;
  // Used to verify that paint recorders are not nested. True while a paint
  // recorder is active.
  mutable bool inside_paint_recorder_;
#endif
};

}  // namespace ui

#endif  // UI_COMPOSITOR_PAINT_CONTEXT_H_