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