15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/texture_image_transport_surface.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_channel.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_channel_manager.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_messages.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/sync_point_manager.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/context_group.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/gpu_scheduler.h"
1810fa3987b403dcc25174693e4947dd4cd8b8612epiman@chromium.org#include "gpu/command_buffer/service/mailbox_manager.h"
19b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "ui/gl/scoped_binders.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using gpu::gles2::ContextGroup;
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using gpu::gles2::GLES2Decoder;
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using gpu::gles2::MailboxManager;
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using gpu::gles2::Texture;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using gpu::gles2::TextureManager;
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using gpu::gles2::TextureRef;
2710fa3987b403dcc25174693e4947dd4cd8b8612epiman@chromium.orgusing gpu::Mailbox;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace {
317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool IsContextValid(ImageTransportHelper* helper) {
337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return helper->stub()->decoder()->GetGLContext()->IsCurrent(NULL) ||
347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      helper->stub()->decoder()->WasContextLost();
357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // namespace
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TextureImageTransportSurface::TextureImageTransportSurface(
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GpuChannelManager* manager,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GpuCommandBufferStub* stub,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::GLSurfaceHandle& handle)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : fbo_id_(0),
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        current_size_(1, 1),
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        scale_factor_(1.f),
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        stub_destroyed_(false),
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        backbuffer_suggested_allocation_(true),
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        frontbuffer_suggested_allocation_(true),
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        handle_(handle),
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        is_swap_buffers_pending_(false),
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        did_unschedule_(false) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper_.reset(new ImageTransportHelper(this,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         manager,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         stub,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         gfx::kNullPluginWindow));
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TextureImageTransportSurface::~TextureImageTransportSurface() {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(stub_destroyed_);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Destroy();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextureImageTransportSurface::Initialize() {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mailbox_manager_ =
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      helper_->stub()->decoder()->GetContextGroup()->mailbox_manager();
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GpuChannelManager* manager = helper_->manager();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  surface_ = manager->GetDefaultOffscreenSurface();
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!surface_.get())
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!helper_->Initialize())
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GpuChannel* parent_channel = manager->LookupChannel(handle_.parent_client_id);
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (parent_channel) {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const CommandLine* command_line = CommandLine::ForCurrentProcess();
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess))
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      helper_->SetPreemptByFlag(parent_channel->GetPreemptionFlag());
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextureImageTransportSurface::Destroy() {
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (surface_.get())
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    surface_ = NULL;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper_->Destroy();
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextureImageTransportSurface::DeferDraws() {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The command buffer hit a draw/clear command that could clobber the
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // texture in use by the UI compositor. If a Swap is pending, abort
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // processing of the command by returning true and unschedule until the Swap
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ack arrives.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!did_unschedule_);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_swap_buffers_pending_) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    did_unschedule_ = true;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    helper_->SetScheduled(false);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextureImageTransportSurface::IsOffscreen() {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)unsigned int TextureImageTransportSurface::GetBackingFrameBufferObject() {
1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(IsContextValid(helper_.get()));
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!fbo_id_) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glGenFramebuffersEXT(1, &fbo_id_);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_id_);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    helper_->stub()->AddDestructionObserver(this);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateBackTexture();
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return fbo_id_;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) {
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!is_swap_buffers_pending_);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (backbuffer_suggested_allocation_ == allocation)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     return true;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backbuffer_suggested_allocation_ = allocation;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (backbuffer_suggested_allocation_) {
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(!backbuffer_.get());
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateBackTexture();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ReleaseBackTexture();
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (frontbuffer_suggested_allocation_ == allocation)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frontbuffer_suggested_allocation_ = allocation;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // If a swapbuffers is in flight, wait for the ack before releasing the front
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // buffer:
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // - we don't know yet which texture the browser will want to keep
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // - we want to ensure we don't destroy a texture that is in flight before the
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // browser got a reference on it.
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!frontbuffer_suggested_allocation_ &&
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      !is_swap_buffers_pending_ &&
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      helper_->MakeCurrent()) {
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ReleaseFrontTexture();
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* TextureImageTransportSurface::GetShareHandle() {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetHandle();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* TextureImageTransportSurface::GetDisplay() {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return surface_.get() ? surface_->GetDisplay() : NULL;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* TextureImageTransportSurface::GetConfig() {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return surface_.get() ? surface_->GetConfig() : NULL;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TextureImageTransportSurface::OnResize(gfx::Size size,
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                            float scale_factor) {
169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(size.width(), 1);
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK_GE(size.height(), 1);
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_size_ = size;
17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scale_factor_ = scale_factor;
1735e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  if (backbuffer_suggested_allocation_)
1745e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    CreateBackTexture();
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TextureImageTransportSurface::OnWillDestroyStub() {
1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(IsContextValid(helper_.get()));
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  helper_->stub()->RemoveDestructionObserver(this);
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We are losing the stub owning us, this is our last chance to clean up the
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // resources we allocated in the stub's context.
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ReleaseBackTexture();
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ReleaseFrontTexture();
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (fbo_id_) {
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glDeleteFramebuffersEXT(1, &fbo_id_);
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CHECK_GL_ERROR();
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fbo_id_ = 0;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stub_destroyed_ = true;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TextureImageTransportSurface::SetLatencyInfo(
19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const ui::LatencyInfo& latency_info) {
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  latency_info_ = latency_info;
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void TextureImageTransportSurface::WakeUpGpu() {
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NOTIMPLEMENTED();
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextureImageTransportSurface::SwapBuffers() {
2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(IsContextValid(helper_.get()));
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(backbuffer_suggested_allocation_);
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!frontbuffer_suggested_allocation_)
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!backbuffer_.get()) {
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Swap without valid backing.";
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(backbuffer_size() == current_size_);
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.size = backbuffer_size();
21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.scale_factor = scale_factor_;
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.mailbox_name.assign(
22110fa3987b403dcc25174693e4947dd4cd8b8612epiman@chromium.org      reinterpret_cast<const char*>(&back_mailbox_),
22210fa3987b403dcc25174693e4947dd4cd8b8612epiman@chromium.org      sizeof(back_mailbox_));
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glFlush();
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.latency_info = latency_info_;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper_->SendAcceleratedSurfaceBuffersSwapped(params);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_swap_buffers_pending_);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_swap_buffers_pending_ = true;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextureImageTransportSurface::PostSubBuffer(
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int x, int y, int width, int height) {
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(IsContextValid(helper_.get()));
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(backbuffer_suggested_allocation_);
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!frontbuffer_suggested_allocation_)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::Rect new_damage_rect(x, y, width, height);
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(gfx::Rect(gfx::Point(), current_size_).Contains(new_damage_rect));
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An empty damage rect is a successful no-op.
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (new_damage_rect.IsEmpty())
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!backbuffer_.get()) {
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Swap without valid backing.";
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(current_size_ == backbuffer_size());
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params;
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.surface_size = backbuffer_size();
25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.surface_scale_factor = scale_factor_;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.x = x;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.y = y;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.width = width;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.height = height;
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.mailbox_name.assign(
26110fa3987b403dcc25174693e4947dd4cd8b8612epiman@chromium.org      reinterpret_cast<const char*>(&back_mailbox_),
26210fa3987b403dcc25174693e4947dd4cd8b8612epiman@chromium.org      sizeof(back_mailbox_));
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glFlush();
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.latency_info = latency_info_;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper_->SendAcceleratedSurfacePostSubBuffer(params);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_swap_buffers_pending_);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_swap_buffers_pending_ = true;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TextureImageTransportSurface::GetExtensions() {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string extensions = gfx::GLSurface::GetExtensions();
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions += extensions.empty() ? "" : " ";
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions += "GL_CHROMIUM_front_buffer_cached ";
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions += "GL_CHROMIUM_post_sub_buffer";
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extensions;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size TextureImageTransportSurface::GetSize() {
283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return current_size_;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* TextureImageTransportSurface::GetHandle() {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return surface_.get() ? surface_->GetHandle() : NULL;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned TextureImageTransportSurface::GetFormat() {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return surface_.get() ? surface_->GetFormat() : 0;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TextureImageTransportSurface::OnBufferPresented(
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AcceleratedSurfaceMsg_BufferPresented_Params& params) {
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (params.sync_point == 0) {
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BufferPresentedImpl(params.mailbox_name);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    helper_->manager()->sync_point_manager()->AddSyncPointCallback(
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        params.sync_point,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&TextureImageTransportSurface::BufferPresentedImpl,
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   this,
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   params.mailbox_name));
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TextureImageTransportSurface::BufferPresentedImpl(
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& mailbox_name) {
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(is_swap_buffers_pending_);
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  is_swap_buffers_pending_ = false;
3117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // When we wait for a sync point, we may get called back after the stub is
3137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // destroyed. In that case there's no need to do anything with the returned
3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // mailbox.
3157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (stub_destroyed_)
3167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
3177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should not have allowed the backbuffer to be discarded while the ack
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // was pending.
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(backbuffer_suggested_allocation_);
321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(backbuffer_.get());
322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool swap = true;
324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!mailbox_name.empty()) {
325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(mailbox_name.length() == GL_MAILBOX_SIZE_CHROMIUM);
326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!memcmp(mailbox_name.data(),
32710fa3987b403dcc25174693e4947dd4cd8b8612epiman@chromium.org                &back_mailbox_,
328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                mailbox_name.length())) {
329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // The browser has skipped the frame to unblock the GPU process, waiting
330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // for one of the right size, and returned the back buffer, so don't swap.
331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      swap = false;
332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (swap) {
335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    std::swap(backbuffer_, frontbuffer_);
33610fa3987b403dcc25174693e4947dd4cd8b8612epiman@chromium.org    std::swap(back_mailbox_, front_mailbox_);
337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We're relying on the fact that the parent context is
340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // finished with its context when it inserts the sync point that
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // triggers this callback.
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (helper_->MakeCurrent()) {
343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (frontbuffer_.get() && !frontbuffer_suggested_allocation_)
344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ReleaseFrontTexture();
345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!backbuffer_.get() || backbuffer_size() != current_size_)
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateBackTexture();
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AttachBackTextureToFBO();
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Even if MakeCurrent fails, schedule anyway, to trigger the lost context
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // logic.
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (did_unschedule_) {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    did_unschedule_ = false;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    helper_->SetScheduled(true);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextureImageTransportSurface::OnResizeViewACK() {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TextureImageTransportSurface::ReleaseBackTexture() {
3647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(IsContextValid(helper_.get()));
365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  backbuffer_ = NULL;
36610fa3987b403dcc25174693e4947dd4cd8b8612epiman@chromium.org  back_mailbox_ = Mailbox();
367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  glFlush();
368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CHECK_GL_ERROR();
369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void TextureImageTransportSurface::ReleaseFrontTexture() {
3727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(IsContextValid(helper_.get()));
373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  frontbuffer_ = NULL;
37410fa3987b403dcc25174693e4947dd4cd8b8612epiman@chromium.org  front_mailbox_ = Mailbox();
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glFlush();
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_GL_ERROR();
3774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  helper_->SendAcceleratedSurfaceRelease();
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TextureImageTransportSurface::CreateBackTexture() {
3817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(IsContextValid(helper_.get()));
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If |is_swap_buffers_pending| we are waiting for our backbuffer
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // in the mailbox, so we shouldn't be reallocating it now.
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!is_swap_buffers_pending_);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (backbuffer_.get() && backbuffer_size() == current_size_)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VLOG(1) << "Allocating new backbuffer texture";
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GLES2Decoder* decoder = helper_->stub()->decoder();
392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TextureManager* texture_manager =
393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      decoder->GetContextGroup()->texture_manager();
394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!backbuffer_.get()) {
39510fa3987b403dcc25174693e4947dd4cd8b8612epiman@chromium.org    mailbox_manager_->GenerateMailbox(&back_mailbox_);
396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    GLuint service_id;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glGenTextures(1, &service_id);
398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    backbuffer_ = TextureRef::Create(texture_manager, 0, service_id);
399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    texture_manager->SetTarget(backbuffer_.get(), GL_TEXTURE_2D);
400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Texture* texture = texture_manager->Produce(backbuffer_.get());
40110fa3987b403dcc25174693e4947dd4cd8b8612epiman@chromium.org    mailbox_manager_->ProduceTexture(GL_TEXTURE_2D, back_mailbox_, texture);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D,
406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                            backbuffer_->service_id());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        current_size_.width(), current_size_.height(), 0,
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GL_RGBA, GL_UNSIGNED_BYTE, NULL);
410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    gpu::gles2::ErrorState* error_state = decoder->GetErrorState();
411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    texture_manager->SetParameter("Backbuffer",
412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  error_state,
413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  backbuffer_.get(),
414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  GL_TEXTURE_MIN_FILTER,
415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  GL_LINEAR);
416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    texture_manager->SetParameter("Backbuffer",
417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  error_state,
418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  backbuffer_.get(),
419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  GL_TEXTURE_MAG_FILTER,
420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  GL_LINEAR);
421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    texture_manager->SetParameter("Backbuffer",
422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  error_state,
423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  backbuffer_.get(),
424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  GL_TEXTURE_WRAP_S,
425868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  GL_CLAMP_TO_EDGE);
426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    texture_manager->SetParameter("Backbuffer",
427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  error_state,
428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  backbuffer_.get(),
429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  GL_TEXTURE_WRAP_T,
430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  GL_CLAMP_TO_EDGE);
431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    texture_manager->SetLevelInfo(backbuffer_.get(),
432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  GL_TEXTURE_2D,
433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  0,
434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  GL_RGBA,
435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  current_size_.width(),
436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  current_size_.height(),
437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  1,
438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  0,
439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  GL_RGBA,
440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  GL_UNSIGNED_BYTE,
441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  true);
442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(texture_manager->CanRender(backbuffer_.get()));
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_GL_ERROR();
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AttachBackTextureToFBO();
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextureImageTransportSurface::AttachBackTextureToFBO() {
4507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(IsContextValid(helper_.get()));
451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(backbuffer_.get());
452a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  gfx::ScopedFrameBufferBinder fbo_binder(fbo_id_);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GL_COLOR_ATTACHMENT0,
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GL_TEXTURE_2D,
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      backbuffer_->service_id(),
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_GL_ERROR();
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status != GL_FRAMEBUFFER_COMPLETE) {
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DLOG(FATAL) << "Framebuffer incomplete: " << status;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
469