1 // Copyright 2011 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_layer_impl.h"
7 #include "base/stringprintf.h"
8 #include "cc/layer_tree_impl.h"
9 #include "cc/quad_sink.h"
10 #include "cc/renderer.h"
11 #include "cc/texture_draw_quad.h"
15 TextureLayerImpl::TextureLayerImpl(LayerTreeImpl
* treeImpl
, int id
, bool usesMailbox
)
16 : LayerImpl(treeImpl
, id
)
18 , m_externalTextureResource(0)
19 , m_premultipliedAlpha(true)
21 , m_uvTopLeft(0.f
, 0.f
)
22 , m_uvBottomRight(1.f
, 1.f
)
23 , m_hasPendingMailbox(false)
24 , m_usesMailbox(usesMailbox
)
26 m_vertexOpacity
[0] = 1.0f
;
27 m_vertexOpacity
[1] = 1.0f
;
28 m_vertexOpacity
[2] = 1.0f
;
29 m_vertexOpacity
[3] = 1.0f
;
32 TextureLayerImpl::~TextureLayerImpl()
34 if (m_externalTextureResource
) {
35 DCHECK(m_usesMailbox
);
36 ResourceProvider
* provider
= layerTreeImpl()->resource_provider();
37 provider
->deleteResource(m_externalTextureResource
);
39 if (m_hasPendingMailbox
)
40 m_pendingTextureMailbox
.RunReleaseCallback(m_pendingTextureMailbox
.sync_point());
43 void TextureLayerImpl::setTextureMailbox(const TextureMailbox
& mailbox
)
45 DCHECK(m_usesMailbox
);
46 // Same mailbox name was commited, nothing to do.
47 if (m_pendingTextureMailbox
.Equals(mailbox
))
49 // Two commits without a draw, ack the previous mailbox.
50 if (m_hasPendingMailbox
)
51 m_pendingTextureMailbox
.RunReleaseCallback(m_pendingTextureMailbox
.sync_point());
53 m_pendingTextureMailbox
= mailbox
;
54 m_hasPendingMailbox
= true;
57 scoped_ptr
<LayerImpl
> TextureLayerImpl::createLayerImpl(LayerTreeImpl
* treeImpl
)
59 return TextureLayerImpl::create(treeImpl
, id(), m_usesMailbox
).PassAs
<LayerImpl
>();
62 void TextureLayerImpl::pushPropertiesTo(LayerImpl
* layer
)
64 LayerImpl::pushPropertiesTo(layer
);
66 TextureLayerImpl
* textureLayer
= static_cast<TextureLayerImpl
*>(layer
);
67 textureLayer
->setFlipped(m_flipped
);
68 textureLayer
->setUVTopLeft(m_uvTopLeft
);
69 textureLayer
->setUVBottomRight(m_uvBottomRight
);
70 textureLayer
->setVertexOpacity(m_vertexOpacity
);
71 textureLayer
->setPremultipliedAlpha(m_premultipliedAlpha
);
73 textureLayer
->setTextureMailbox(m_pendingTextureMailbox
);
75 textureLayer
->setTextureId(m_textureId
);
80 void TextureLayerImpl::willDraw(ResourceProvider
* resourceProvider
)
85 DCHECK(!m_externalTextureResource
);
86 m_externalTextureResource
= resourceProvider
->createResourceFromExternalTexture(m_textureId
);
90 if (!m_hasPendingMailbox
)
93 if (m_externalTextureResource
) {
94 resourceProvider
->deleteResource(m_externalTextureResource
);
95 m_externalTextureResource
= 0;
97 if (!m_pendingTextureMailbox
.IsEmpty())
98 m_externalTextureResource
= resourceProvider
->createResourceFromTextureMailbox(m_pendingTextureMailbox
);
99 m_hasPendingMailbox
= false;
102 void TextureLayerImpl::appendQuads(QuadSink
& quadSink
, AppendQuadsData
& appendQuadsData
)
104 if (!m_externalTextureResource
)
107 SharedQuadState
* sharedQuadState
= quadSink
.useSharedQuadState(createSharedQuadState());
108 appendDebugBorderQuad(quadSink
, sharedQuadState
, appendQuadsData
);
110 gfx::Rect
quadRect(gfx::Point(), contentBounds());
111 gfx::Rect
opaqueRect(contentsOpaque() ? quadRect
: gfx::Rect());
112 scoped_ptr
<TextureDrawQuad
> quad
= TextureDrawQuad::Create();
113 quad
->SetNew(sharedQuadState
, quadRect
, opaqueRect
, m_externalTextureResource
, m_premultipliedAlpha
, m_uvTopLeft
, m_uvBottomRight
, m_vertexOpacity
, m_flipped
);
115 // Perform explicit clipping on a quad to avoid setting a scissor later.
116 if (sharedQuadState
->is_clipped
&& quad
->PerformClipping())
117 sharedQuadState
->is_clipped
= false;
118 if (!quad
->rect
.IsEmpty())
119 quadSink
.append(quad
.PassAs
<DrawQuad
>(), appendQuadsData
);
122 void TextureLayerImpl::didDraw(ResourceProvider
* resourceProvider
)
126 if (!m_externalTextureResource
)
128 // FIXME: the following assert will not be true when sending resources to a
129 // parent compositor. A synchronization scheme (double-buffering or
130 // pipelining of updates) for the client will need to exist to solve this.
131 DCHECK(!resourceProvider
->inUseByConsumer(m_externalTextureResource
));
132 resourceProvider
->deleteResource(m_externalTextureResource
);
133 m_externalTextureResource
= 0;
136 void TextureLayerImpl::dumpLayerProperties(std::string
* str
, int indent
) const
138 str
->append(indentString(indent
));
139 base::StringAppendF(str
, "texture layer texture id: %u premultiplied: %d\n", m_textureId
, m_premultipliedAlpha
);
140 LayerImpl::dumpLayerProperties(str
, indent
);
143 void TextureLayerImpl::setVertexOpacity(const float vertexOpacity
[4]) {
144 m_vertexOpacity
[0] = vertexOpacity
[0];
145 m_vertexOpacity
[1] = vertexOpacity
[1];
146 m_vertexOpacity
[2] = vertexOpacity
[2];
147 m_vertexOpacity
[3] = vertexOpacity
[3];
150 void TextureLayerImpl::didLoseOutputSurface()
153 m_externalTextureResource
= 0;
156 const char* TextureLayerImpl::layerTypeAsString() const
158 return "TextureLayer";
161 bool TextureLayerImpl::canClipSelf() const