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"
11 TextureDrawQuad::TextureDrawQuad()
13 premultiplied_alpha(false),
17 scoped_ptr
<TextureDrawQuad
> TextureDrawQuad::Create() {
18 return make_scoped_ptr(new TextureDrawQuad
);
21 void TextureDrawQuad::SetNew(const SharedQuadState
* shared_quad_state
,
22 gfx::Rect rect
, gfx::Rect opaque_rect
,
23 unsigned resource_id
, bool premultiplied_alpha
,
24 const gfx::RectF
& uv_rect
,
25 const float vertex_opacity
[4], bool flipped
) {
26 gfx::Rect visible_rect
= rect
;
27 bool needs_blending
= vertex_opacity
[0] != 1.0f
|| vertex_opacity
[1] != 1.0f
28 || vertex_opacity
[2] != 1.0f
|| vertex_opacity
[3] != 1.0f
;
29 DrawQuad::SetAll(shared_quad_state
, DrawQuad::TEXTURE_CONTENT
, rect
,
30 opaque_rect
, visible_rect
, needs_blending
);
31 this->resource_id
= resource_id
;
32 this->premultiplied_alpha
= premultiplied_alpha
;
33 this->uv_rect
= uv_rect
;
34 this->vertex_opacity
[0] = vertex_opacity
[0];
35 this->vertex_opacity
[1] = vertex_opacity
[1];
36 this->vertex_opacity
[2] = vertex_opacity
[2];
37 this->vertex_opacity
[3] = vertex_opacity
[3];
38 this->flipped
= flipped
;
41 void TextureDrawQuad::SetAll(const SharedQuadState
* shared_quad_state
,
42 gfx::Rect rect
, gfx::Rect opaque_rect
,
43 gfx::Rect visible_rect
, bool needs_blending
,
44 unsigned resource_id
, bool premultiplied_alpha
,
45 const gfx::RectF
& uv_rect
,
46 const float vertex_opacity
[4], bool flipped
) {
47 DrawQuad::SetAll(shared_quad_state
, DrawQuad::TEXTURE_CONTENT
, rect
,
48 opaque_rect
, visible_rect
, needs_blending
);
49 this->resource_id
= resource_id
;
50 this->premultiplied_alpha
= premultiplied_alpha
;
51 this->uv_rect
= uv_rect
;
52 this->vertex_opacity
[0] = vertex_opacity
[0];
53 this->vertex_opacity
[1] = vertex_opacity
[1];
54 this->vertex_opacity
[2] = vertex_opacity
[2];
55 this->vertex_opacity
[3] = vertex_opacity
[3];
56 this->flipped
= flipped
;
59 const TextureDrawQuad
* TextureDrawQuad::MaterialCast(const DrawQuad
* quad
) {
60 DCHECK(quad
->material
== DrawQuad::TEXTURE_CONTENT
);
61 return static_cast<const TextureDrawQuad
*>(quad
);
64 bool TextureDrawQuad::PerformClipping() {
65 // This only occurs if the rect is only scaled and translated (and thus still
67 if (!quadTransform().IsScaleOrTranslation())
70 // Grab our scale and make sure it's positive.
71 float x_scale
= quadTransform().matrix().getDouble(0, 0);
72 float y_scale
= quadTransform().matrix().getDouble(1, 1);
73 if (x_scale
<= 0.0f
|| y_scale
<= 0.0f
)
77 gfx::Vector2dF
offset(quadTransform().matrix().getDouble(0, 3),
78 quadTransform().matrix().getDouble(1, 3));
80 // Transform the rect by the scale and offset.
81 gfx::RectF rectF
= rect
;
82 rectF
.Scale(x_scale
, y_scale
);
85 // Perform clipping and check to see if the result is empty.
86 gfx::RectF clippedRect
= IntersectRects(rectF
, clipRect());
87 if (clippedRect
.IsEmpty()) {
89 uv_rect
= gfx::RectF();
93 // Create a new uv-rect by clipping the old one to the new bounds.
96 + uv_rect
.width() / rectF
.width() * (clippedRect
.x() - rectF
.x()),
98 + uv_rect
.height() / rectF
.height() * (clippedRect
.y() - rectF
.y()),
99 uv_rect
.width() / rectF
.width() * clippedRect
.width(),
100 uv_rect
.height() / rectF
.height() * clippedRect
.height());
102 // Indexing according to the quad vertex generation:
106 if (vertex_opacity
[0] != vertex_opacity
[1]
107 || vertex_opacity
[0] != vertex_opacity
[2]
108 || vertex_opacity
[0] != vertex_opacity
[3]) {
109 const float x1
= (clippedRect
.x() - rectF
.x()) / rectF
.width();
110 const float y1
= (clippedRect
.y() - rectF
.y()) / rectF
.height();
111 const float x3
= (clippedRect
.right() - rectF
.x()) / rectF
.width();
112 const float y3
= (clippedRect
.bottom() - rectF
.y()) / rectF
.height();
113 const float x1y1
= x1
* vertex_opacity
[2] + (1.0f
- x1
) * vertex_opacity
[1];
114 const float x1y3
= x1
* vertex_opacity
[3] + (1.0f
- x1
) * vertex_opacity
[0];
115 const float x3y1
= x3
* vertex_opacity
[2] + (1.0f
- x3
) * vertex_opacity
[1];
116 const float x3y3
= x3
* vertex_opacity
[3] + (1.0f
- x3
) * vertex_opacity
[0];
117 vertex_opacity
[0] = y3
* x1y3
+ (1.0f
- y3
) * x1y1
;
118 vertex_opacity
[1] = y1
* x1y3
+ (1.0f
- y1
) * x1y1
;
119 vertex_opacity
[2] = y1
* x3y3
+ (1.0f
- y1
) * x3y1
;
120 vertex_opacity
[3] = y3
* x3y3
+ (1.0f
- y3
) * x3y1
;
123 // Move the clipped rectangle back into its space.
124 clippedRect
-= offset
;
125 clippedRect
.Scale(1.0f
/ x_scale
, 1.0f
/ y_scale
);
126 rect
= gfx::Rect(static_cast<int>(clippedRect
.x() + 0.5f
),
127 static_cast<int>(clippedRect
.y() + 0.5f
),
128 static_cast<int>(clippedRect
.width() + 0.5f
),
129 static_cast<int>(clippedRect
.height() + 0.5f
));