12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/io_surface_layer_impl.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/gl_renderer.h"  // For the GLC() macro.
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/output_surface.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/io_surface_draw_quad.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/layer_tree_impl.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "cc/trees/occlusion_tracker.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/GLES2/gl2extchromium.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gpu/command_buffer/client/gles2_interface.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/khronos/GLES2/gl2.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/khronos/GLES2/gl2ext.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IOSurfaceLayerImpl::IOSurfaceLayerImpl(LayerTreeImpl* tree_impl, int id)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : LayerImpl(tree_impl, id),
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      io_surface_id_(0),
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      io_surface_changed_(false),
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      io_surface_resource_id_(0) {}
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IOSurfaceLayerImpl::~IOSurfaceLayerImpl() {
27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DestroyResource();
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void IOSurfaceLayerImpl::DestroyResource() {
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (io_surface_resource_id_) {
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ResourceProvider* resource_provider =
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        layer_tree_impl()->resource_provider();
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    resource_provider->DeleteResource(io_surface_resource_id_);
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    io_surface_resource_id_ = 0;
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<LayerImpl> IOSurfaceLayerImpl::CreateLayerImpl(
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeImpl* tree_impl) {
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return IOSurfaceLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void IOSurfaceLayerImpl::PushPropertiesTo(LayerImpl* layer) {
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerImpl::PushPropertiesTo(layer);
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IOSurfaceLayerImpl* io_surface_layer =
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<IOSurfaceLayerImpl*>(layer);
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool IOSurfaceLayerImpl::WillDraw(DrawMode draw_mode,
53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  ResourceProvider* resource_provider) {
54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (draw_mode != DRAW_MODE_HARDWARE)
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (io_surface_changed_) {
58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    DestroyResource();
59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    io_surface_resource_id_ = resource_provider->CreateResourceFromIOSurface(
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        io_surface_size_, io_surface_id_);
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    io_surface_changed_ = false;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return LayerImpl::WillDraw(draw_mode, resource_provider);
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid IOSurfaceLayerImpl::AppendQuads(
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderPass* render_pass,
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const OcclusionTracker<LayerImpl>& occlusion_tracker,
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    AppendQuadsData* append_quads_data) {
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SharedQuadState* shared_quad_state =
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      render_pass->CreateAndAppendSharedQuadState();
73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  PopulateSharedQuadState(shared_quad_state);
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  AppendDebugBorderQuad(
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      render_pass, content_bounds(), shared_quad_state, append_quads_data);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect quad_rect(content_bounds());
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect opaque_rect(contents_opaque() ? quad_rect : gfx::Rect());
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Rect visible_quad_rect =
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      occlusion_tracker.GetCurrentOcclusionForLayer(
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            draw_properties().target_space_transform)
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          .GetUnoccludedContentRect(quad_rect);
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (visible_quad_rect.IsEmpty())
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  IOSurfaceDrawQuad* quad =
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      render_pass->CreateAndAppendDrawQuad<IOSurfaceDrawQuad>();
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  quad->SetNew(shared_quad_state,
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               quad_rect,
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               opaque_rect,
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               visible_quad_rect,
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               io_surface_size_,
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               io_surface_resource_id_,
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               IOSurfaceDrawQuad::FLIPPED);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void IOSurfaceLayerImpl::ReleaseResources() {
99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // We don't have a valid resource ID in the new context; however,
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the IOSurface is still valid.
101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DestroyResource();
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  io_surface_changed_ = true;
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void IOSurfaceLayerImpl::SetIOSurfaceProperties(unsigned io_surface_id,
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                const gfx::Size& size) {
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (io_surface_id_ != io_surface_id)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    io_surface_changed_ = true;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  io_surface_id_ = io_surface_id;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  io_surface_size_ = size;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* IOSurfaceLayerImpl::LayerTypeAsString() const {
115a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return "cc::IOSurfaceLayerImpl";
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
119