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     kRenderPass,
41     kSolidColor,
42     kStreamVideoContent,
43     kSurfaceContent,
44     kTextureContent,
45     kTiledContent,
46     kYuvVideoContent,
47     kVideoHole,
48     kMaxValue = kVideoHole
49   };
50 
51   DrawQuad(const DrawQuad& other);
52   virtual ~DrawQuad();
53 
54   Material material;
55 
56   // This rect, after applying the quad_transform(), gives the geometry that
57   // this quad should draw to. This rect lives in content space.
58   gfx::Rect rect;
59 
60   // Allows changing the rect that gets drawn to make it smaller. This value
61   // should be clipped to |rect|. This rect lives in content space.
62   gfx::Rect visible_rect;
63 
64   // By default blending is used when some part of the quad is not opaque.
65   // With this setting, it is possible to force blending on regardless of the
66   // opaque area.
67   bool needs_blending;
68 
69   // Stores state common to a large bundle of quads; kept separate for memory
70   // efficiency. There is special treatment to reconstruct these pointers
71   // during serialization.
72   const SharedQuadState* shared_quad_state;
73 
IsDebugQuad()74   bool IsDebugQuad() const { return material == Material::kDebugBorder; }
75 
76   bool ShouldDrawWithBlending(bool=false) const {
77     return needs_blending || shared_quad_state->opacity < 1.0f ||
78            shared_quad_state->blend_mode != SkBlendMode::kSrcOver ||
79            !shared_quad_state->rounded_corner_bounds.IsEmpty();
80   }
81 
82   // Is the left edge of this tile aligned with the originating layer's
83   // left edge?
IsLeftEdge()84   bool IsLeftEdge() const {
85     return rect.x() == shared_quad_state->quad_layer_rect.x();
86   }
87 
88   // Is the top edge of this tile aligned with the originating layer's
89   // top edge?
IsTopEdge()90   bool IsTopEdge() const {
91     return rect.y() == shared_quad_state->quad_layer_rect.y();
92   }
93 
94   // Is the right edge of this tile aligned with the originating layer's
95   // right edge?
IsRightEdge()96   bool IsRightEdge() const {
97     return rect.right() == shared_quad_state->quad_layer_rect.right();
98   }
99 
100   // Is the bottom edge of this tile aligned with the originating layer's
101   // bottom edge?
IsBottomEdge()102   bool IsBottomEdge() const {
103     return rect.bottom() == shared_quad_state->quad_layer_rect.bottom();
104   }
105 
106   // Is any edge of this tile aligned with the originating layer's
107   // corresponding edge?
IsEdge()108   bool IsEdge() const {
109     return IsLeftEdge() || IsTopEdge() || IsRightEdge() || IsBottomEdge();
110   }
111 
112   void AsValueInto(base::trace_event::TracedValue* value) const;
113 
114   struct VIZ_COMMON_EXPORT Resources {
115     enum : size_t { kMaxResourceIdCount = 4 };
116     Resources();
117 
beginResources118     ResourceId* begin() { return ids; }
endResources119     ResourceId* end() {
120       DCHECK_LE(count, kMaxResourceIdCount);
121       return ids + count;
122     }
123 
beginResources124     const ResourceId* begin() const { return ids; }
endResources125     const ResourceId* end() const {
126       DCHECK_LE(count, kMaxResourceIdCount);
127       return ids + count;
128     }
129 
130     uint32_t count;
131     ResourceId ids[kMaxResourceIdCount];
132   };
133 
134   Resources resources;
135 
136  protected:
137   DrawQuad();
138 
139   void SetAll(const SharedQuadState* shared_quad_state,
140               Material material,
141               const gfx::Rect& rect,
142               const gfx::Rect& visible_rect,
143               bool needs_blending);
144   virtual void ExtendValue(base::trace_event::TracedValue* value) const = 0;
145 };
146 
147 }  // namespace viz
148 
149 #endif  // COMPONENTS_VIZ_COMMON_QUADS_DRAW_QUAD_H_
150