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.
5 #include "cc/texture_draw_quad.h"
7 #include "base/logging.h"
8 #include "ui/gfx/vector2d_f.h"
12 TextureDrawQuad::TextureDrawQuad()
14 premultiplied_alpha(false),
18 scoped_ptr
<TextureDrawQuad
> TextureDrawQuad::Create() {
19 return make_scoped_ptr(new TextureDrawQuad
);
22 void TextureDrawQuad::SetNew(const SharedQuadState
* shared_quad_state
,
23 gfx::Rect rect
, gfx::Rect opaque_rect
,
24 unsigned resource_id
, bool premultiplied_alpha
,
25 gfx::PointF uv_top_left
,
26 gfx::PointF uv_bottom_right
,
27 const float vertex_opacity
[4], bool flipped
) {
28 gfx::Rect visible_rect
= rect
;
29 bool needs_blending
= vertex_opacity
[0] != 1.0f
|| vertex_opacity
[1] != 1.0f
30 || vertex_opacity
[2] != 1.0f
|| vertex_opacity
[3] != 1.0f
;
31 DrawQuad::SetAll(shared_quad_state
, DrawQuad::TEXTURE_CONTENT
, rect
,
32 opaque_rect
, visible_rect
, needs_blending
);
33 this->resource_id
= resource_id
;
34 this->premultiplied_alpha
= premultiplied_alpha
;
35 this->uv_top_left
= uv_top_left
;
36 this->uv_bottom_right
= uv_bottom_right
;
37 this->vertex_opacity
[0] = vertex_opacity
[0];
38 this->vertex_opacity
[1] = vertex_opacity
[1];
39 this->vertex_opacity
[2] = vertex_opacity
[2];
40 this->vertex_opacity
[3] = vertex_opacity
[3];
41 this->flipped
= flipped
;
44 void TextureDrawQuad::SetAll(const SharedQuadState
* shared_quad_state
,
45 gfx::Rect rect
, gfx::Rect opaque_rect
,
46 gfx::Rect visible_rect
, bool needs_blending
,
47 unsigned resource_id
, bool premultiplied_alpha
,
48 gfx::PointF uv_top_left
,
49 gfx::PointF uv_bottom_right
,
50 const float vertex_opacity
[4], bool flipped
) {
51 DrawQuad::SetAll(shared_quad_state
, DrawQuad::TEXTURE_CONTENT
, rect
,
52 opaque_rect
, visible_rect
, needs_blending
);
53 this->resource_id
= resource_id
;
54 this->premultiplied_alpha
= premultiplied_alpha
;
55 this->uv_top_left
= uv_top_left
;
56 this->uv_bottom_right
= uv_bottom_right
;
57 this->vertex_opacity
[0] = vertex_opacity
[0];
58 this->vertex_opacity
[1] = vertex_opacity
[1];
59 this->vertex_opacity
[2] = vertex_opacity
[2];
60 this->vertex_opacity
[3] = vertex_opacity
[3];
61 this->flipped
= flipped
;
64 void TextureDrawQuad::AppendResources(
65 ResourceProvider::ResourceIdArray
* resources
) {
66 resources
->push_back(resource_id
);
69 const TextureDrawQuad
* TextureDrawQuad::MaterialCast(const DrawQuad
* quad
) {
70 DCHECK(quad
->material
== DrawQuad::TEXTURE_CONTENT
);
71 return static_cast<const TextureDrawQuad
*>(quad
);
74 bool TextureDrawQuad::PerformClipping() {
75 // This only occurs if the rect is only scaled and translated (and thus still
77 if (!quadTransform().IsPositiveScaleOrTranslation())
80 // Grab our scale and make sure it's positive.
81 float x_scale
= static_cast<float>(quadTransform().matrix().getDouble(0, 0));
82 float y_scale
= static_cast<float>(quadTransform().matrix().getDouble(1, 1));
85 gfx::Vector2dF
offset(
86 static_cast<float>(quadTransform().matrix().getDouble(0, 3)),
87 static_cast<float>(quadTransform().matrix().getDouble(1, 3)));
89 // Transform the rect by the scale and offset.
90 gfx::RectF rectF
= rect
;
91 rectF
.Scale(x_scale
, y_scale
);
94 // Perform clipping and check to see if the result is empty.
95 gfx::RectF clippedRect
= IntersectRects(rectF
, clipRect());
96 if (clippedRect
.IsEmpty()) {
98 uv_top_left
= gfx::PointF();
99 uv_bottom_right
= gfx::PointF();
103 // Create a new uv-rect by clipping the old one to the new bounds.
104 gfx::Vector2dF
uv_scale(uv_bottom_right
- uv_top_left
);
105 uv_scale
.Scale(1.f
/ rectF
.width(), 1.f
/ rectF
.height());
106 uv_bottom_right
= uv_top_left
+
108 clippedRect
.bottom_right() - rectF
.origin(),
111 uv_top_left
= uv_top_left
+
113 clippedRect
.origin() - rectF
.origin(),
117 // Indexing according to the quad vertex generation:
121 if (vertex_opacity
[0] != vertex_opacity
[1]
122 || vertex_opacity
[0] != vertex_opacity
[2]
123 || vertex_opacity
[0] != vertex_opacity
[3]) {
124 const float x1
= (clippedRect
.x() - rectF
.x()) / rectF
.width();
125 const float y1
= (clippedRect
.y() - rectF
.y()) / rectF
.height();
126 const float x3
= (clippedRect
.right() - rectF
.x()) / rectF
.width();
127 const float y3
= (clippedRect
.bottom() - rectF
.y()) / rectF
.height();
128 const float x1y1
= x1
* vertex_opacity
[2] + (1.0f
- x1
) * vertex_opacity
[1];
129 const float x1y3
= x1
* vertex_opacity
[3] + (1.0f
- x1
) * vertex_opacity
[0];
130 const float x3y1
= x3
* vertex_opacity
[2] + (1.0f
- x3
) * vertex_opacity
[1];
131 const float x3y3
= x3
* vertex_opacity
[3] + (1.0f
- x3
) * vertex_opacity
[0];
132 vertex_opacity
[0] = y3
* x1y3
+ (1.0f
- y3
) * x1y1
;
133 vertex_opacity
[1] = y1
* x1y3
+ (1.0f
- y1
) * x1y1
;
134 vertex_opacity
[2] = y1
* x3y3
+ (1.0f
- y1
) * x3y1
;
135 vertex_opacity
[3] = y3
* x3y3
+ (1.0f
- y3
) * x3y1
;
138 // Move the clipped rectangle back into its space.
139 clippedRect
-= offset
;
140 clippedRect
.Scale(1.0f
/ x_scale
, 1.0f
/ y_scale
);
141 rect
= gfx::Rect(static_cast<int>(clippedRect
.x() + 0.5f
),
142 static_cast<int>(clippedRect
.y() + 0.5f
),
143 static_cast<int>(clippedRect
.width() + 0.5f
),
144 static_cast<int>(clippedRect
.height() + 0.5f
));