OLD | NEW |
| (Empty) |
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 #include "cc/io_surface_layer_impl.h" | |
6 | |
7 #include "base/stringprintf.h" | |
8 #include "cc/output/gl_renderer.h" // For the GLC() macro. | |
9 #include "cc/output/output_surface.h" | |
10 #include "cc/quad_sink.h" | |
11 #include "cc/quads/io_surface_draw_quad.h" | |
12 #include "cc/trees/layer_tree_impl.h" | |
13 #include "gpu/GLES2/gl2extchromium.h" | |
14 #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3
D.h" | |
15 #include "third_party/khronos/GLES2/gl2.h" | |
16 #include "third_party/khronos/GLES2/gl2ext.h" | |
17 | |
18 namespace cc { | |
19 | |
20 IOSurfaceLayerImpl::IOSurfaceLayerImpl(LayerTreeImpl* tree_impl, int id) | |
21 : LayerImpl(tree_impl, id), | |
22 io_surface_id_(0), | |
23 io_surface_changed_(false), | |
24 io_surface_texture_id_(0) {} | |
25 | |
26 IOSurfaceLayerImpl::~IOSurfaceLayerImpl() { | |
27 if (!io_surface_texture_id_) | |
28 return; | |
29 | |
30 OutputSurface* output_surface = layer_tree_impl()->output_surface(); | |
31 // FIXME: Implement this path for software compositing. | |
32 WebKit::WebGraphicsContext3D* context3d = output_surface->context3d(); | |
33 if (context3d) | |
34 context3d->deleteTexture(io_surface_texture_id_); | |
35 } | |
36 | |
37 scoped_ptr<LayerImpl> IOSurfaceLayerImpl::CreateLayerImpl( | |
38 LayerTreeImpl* tree_impl) { | |
39 return IOSurfaceLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>(); | |
40 } | |
41 | |
42 void IOSurfaceLayerImpl::PushPropertiesTo(LayerImpl* layer) { | |
43 LayerImpl::PushPropertiesTo(layer); | |
44 | |
45 IOSurfaceLayerImpl* io_surface_layer = | |
46 static_cast<IOSurfaceLayerImpl*>(layer); | |
47 io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_); | |
48 } | |
49 | |
50 void IOSurfaceLayerImpl::WillDraw(ResourceProvider* resource_provider) { | |
51 LayerImpl::WillDraw(resource_provider); | |
52 | |
53 if (io_surface_changed_) { | |
54 WebKit::WebGraphicsContext3D* context3d = | |
55 resource_provider->GraphicsContext3D(); | |
56 if (!context3d) { | |
57 // FIXME: Implement this path for software compositing. | |
58 return; | |
59 } | |
60 | |
61 // FIXME: Do this in a way that we can track memory usage. | |
62 if (!io_surface_texture_id_) | |
63 io_surface_texture_id_ = context3d->createTexture(); | |
64 | |
65 GLC(context3d, context3d->activeTexture(GL_TEXTURE0)); | |
66 GLC(context3d, | |
67 context3d->bindTexture(GL_TEXTURE_RECTANGLE_ARB, | |
68 io_surface_texture_id_)); | |
69 GLC(context3d, | |
70 context3d->texParameteri( | |
71 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); | |
72 GLC(context3d, | |
73 context3d->texParameteri( | |
74 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); | |
75 GLC(context3d, | |
76 context3d->texParameteri( | |
77 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); | |
78 GLC(context3d, | |
79 context3d->texParameteri( | |
80 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); | |
81 context3d->texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB, | |
82 io_surface_size_.width(), | |
83 io_surface_size_.height(), | |
84 io_surface_id_, | |
85 0); | |
86 // Do not check for error conditions. texImageIOSurface2DCHROMIUM is | |
87 // supposed to hold on to the last good IOSurface if the new one is already | |
88 // closed. This is only a possibility during live resizing of plugins. | |
89 // However, it seems that this is not sufficient to completely guard against | |
90 // garbage being drawn. If this is found to be a significant issue, it may | |
91 // be necessary to explicitly tell the embedder when to free the surfaces it | |
92 // has allocated. | |
93 io_surface_changed_ = false; | |
94 } | |
95 } | |
96 | |
97 void IOSurfaceLayerImpl::AppendQuads(QuadSink* quad_sink, | |
98 AppendQuadsData* append_quads_data) { | |
99 SharedQuadState* shared_quad_state = | |
100 quad_sink->UseSharedQuadState(CreateSharedQuadState()); | |
101 AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data); | |
102 | |
103 gfx::Rect quad_rect(gfx::Point(), content_bounds()); | |
104 gfx::Rect opaque_rect(contents_opaque() ? quad_rect : gfx::Rect()); | |
105 scoped_ptr<IOSurfaceDrawQuad> quad = IOSurfaceDrawQuad::Create(); | |
106 quad->SetNew(shared_quad_state, | |
107 quad_rect, | |
108 opaque_rect, | |
109 io_surface_size_, | |
110 io_surface_texture_id_, | |
111 IOSurfaceDrawQuad::FLIPPED); | |
112 quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data); | |
113 } | |
114 | |
115 void IOSurfaceLayerImpl::DumpLayerProperties(std::string* str, | |
116 int indent) const { | |
117 str->append(IndentString(indent)); | |
118 base::StringAppendF(str, | |
119 "iosurface id: %u texture id: %u\n", | |
120 io_surface_id_, | |
121 io_surface_texture_id_); | |
122 LayerImpl::DumpLayerProperties(str, indent); | |
123 } | |
124 | |
125 void IOSurfaceLayerImpl::DidLoseOutputSurface() { | |
126 // We don't have a valid texture ID in the new context; however, | |
127 // the IOSurface is still valid. | |
128 io_surface_texture_id_ = 0; | |
129 io_surface_changed_ = true; | |
130 } | |
131 | |
132 void IOSurfaceLayerImpl::SetIOSurfaceProperties(unsigned io_surface_id, | |
133 gfx::Size size) { | |
134 if (io_surface_id_ != io_surface_id) | |
135 io_surface_changed_ = true; | |
136 | |
137 io_surface_id_ = io_surface_id; | |
138 io_surface_size_ = size; | |
139 } | |
140 | |
141 const char* IOSurfaceLayerImpl::LayerTypeAsString() const { | |
142 return "IOSurfaceLayer"; | |
143 } | |
144 | |
145 } // namespace cc | |
OLD | NEW |