1 // Copyright 2012 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 #ifndef COMPONENTS_VIZ_COMMON_QUADS_DRAW_QUAD_H_
6 #define COMPONENTS_VIZ_COMMON_QUADS_DRAW_QUAD_H_
7 
8 #include <stddef.h>
9 
10 #include "base/callback.h"
11 #include "components/viz/common/quads/shared_quad_state.h"
12 #include "components/viz/common/resources/resource_id.h"
13 #include "components/viz/common/viz_common_export.h"
14 
15 namespace base {
16 namespace trace_event {
17 class TracedValue;
18 }
19 }  // namespace base
20 
21 namespace viz {
22 
23 // DrawQuad is a bag of data used for drawing a quad. Because different
24 // materials need different bits of per-quad data to render, classes that derive
25 // from DrawQuad store additional data in their derived instance. The Material
26 // enum is used to "safely" downcast to the derived class.
27 // Note: quads contain rects and sizes, which live in different spaces. There is
28 // the "content space", which is the arbitrary space in which the quad's
29 // geometry is defined (generally related to the layer that produced the quad,
30 // e.g. the geometry space for PictureLayerImpls or the layer's coordinate space
31 // for most other layers). There is also the "target space", which is the space,
32 // in "physical" pixels, of the render target where the quads is drawn. The
33 // quad's transform maps the content space to the target space.
34 class VIZ_COMMON_EXPORT DrawQuad {
35  public:
36   enum class Material {
37     kInvalid,
38     kDebugBorder,
39     kPictureContent,
40     // This is the compositor, pre-aggregation, draw quad.
41     kCompositorRenderPass,
42     // This is the viz, post-aggregation, draw quad.
43     kAggregatedRenderPass,
44     kSolidColor,
45     kStreamVideoContent,
46     kSurfaceContent,
47     kTextureContent,
48     kTiledContent,
49     kYuvVideoContent,
50     kVideoHole,
51     kMaxValue = kVideoHole
52   };
53 
54   DrawQuad(const DrawQuad& other);
55   virtual ~DrawQuad();
56 
57   Material material;
58 
59   // This rect, after applying the quad_transform(), gives the geometry that
60   // this quad should draw to. This rect lives in content space.
61   gfx::Rect rect;
62 
63   // Allows changing the rect that gets drawn to make it smaller. This value
64   // should be clipped to |rect|. This rect lives in content space.
65   gfx::Rect visible_rect;
66 
67   // By default blending is used when some part of the quad is not opaque.
68   // With this setting, it is possible to force blending on regardless of the
69   // opaque area.
70   bool needs_blending;
71 
72   // Stores state common to a large bundle of quads; kept separate for memory
73   // efficiency. There is special treatment to reconstruct these pointers
74   // during serialization.
75   const SharedQuadState* shared_quad_state;
76 
IsDebugQuad()77   bool IsDebugQuad() const { return material == Material::kDebugBorder; }
78 
ShouldDrawWithBlending()79   bool ShouldDrawWithBlending() const {
80     return needs_blending || shared_quad_state->opacity < 1.0f ||
81            shared_quad_state->blend_mode != SkBlendMode::kSrcOver ||
82            !shared_quad_state->mask_filter_info.IsEmpty();
83   }
84 
85   // Is the left edge of this tile aligned with the originating layer's
86   // left edge?
IsLeftEdge()87   bool IsLeftEdge() const {
88     return rect.x() == shared_quad_state->quad_layer_rect.x();
89   }
90 
91   // Is the top edge of this tile aligned with the originating layer's
92   // top edge?
IsTopEdge()93   bool IsTopEdge() const {
94     return rect.y() == shared_quad_state->quad_layer_rect.y();
95   }
96 
97   // Is the right edge of this tile aligned with the originating layer's
98   // right edge?
IsRightEdge()99   bool IsRightEdge() const {
100     return rect.right() == shared_quad_state->quad_layer_rect.right();
101   }
102 
103   // Is the bottom edge of this tile aligned with the originating layer's
104   // bottom edge?
IsBottomEdge()105   bool IsBottomEdge() const {
106     return rect.bottom() == shared_quad_state->quad_layer_rect.bottom();
107   }
108 
109   // Is any edge of this tile aligned with the originating layer's
110   // corresponding edge?
IsEdge()111   bool IsEdge() const {
112     return IsLeftEdge() || IsTopEdge() || IsRightEdge() || IsBottomEdge();
113   }
114 
115   void AsValueInto(base::trace_event::TracedValue* value) const;
116 
117   struct VIZ_COMMON_EXPORT Resources {
118     enum : size_t { kMaxResourceIdCount = 4 };
119     Resources();
120 
beginResources121     ResourceId* begin() { return ids; }
endResources122     ResourceId* end() {
123       DCHECK_LE(count, kMaxResourceIdCount);
124       return ids + count;
125     }
126 
beginResources127     const ResourceId* begin() const { return ids; }
endResources128     const ResourceId* end() const {
129       DCHECK_LE(count, kMaxResourceIdCount);
130       return ids + count;
131     }
132 
133     uint32_t count;
134     ResourceId ids[kMaxResourceIdCount];
135   };
136 
137   Resources resources;
138 
139  protected:
140   DrawQuad();
141 
142   void SetAll(const SharedQuadState* shared_quad_state,
143               Material material,
144               const gfx::Rect& rect,
145               const gfx::Rect& visible_rect,
146               bool needs_blending);
147   virtual void ExtendValue(base::trace_event::TracedValue* value) const = 0;
148 };
149 
150 }  // namespace viz
151 
152 #endif  // COMPONENTS_VIZ_COMMON_QUADS_DRAW_QUAD_H_
153