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 "gpu/command_buffer/service/gl_context_virtual.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/gl_state_restorer_impl.h"
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_surface.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLContextVirtual::GLContextVirtual(
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::GLShareGroup* share_group,
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::GLContext* shared_context,
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::WeakPtr<gles2::GLES2Decoder> decoder)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  : GLContext(share_group),
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shared_context_(shared_context),
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    display_(NULL),
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    decoder_(decoder) {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Display* GLContextVirtual::display() {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return display_;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLContextVirtual::Initialize(
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::GLSurface* compatible_surface, gfx::GpuPreference gpu_preference) {
29a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SetGLStateRestorer(new GLStateRestorerImpl(decoder_));
30a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  display_ = static_cast<gfx::Display*>(compatible_surface->GetDisplay());
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Virtual contexts obviously can't make a context that is compatible
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // with the surface (the context already exists), but we do need to
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // make a context current for SetupForVirtualization() below.
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!IsCurrent(compatible_surface)) {
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!shared_context_->MakeCurrent(compatible_surface)) {
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // This is likely an error. The real context should be made as
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // compatible with all required surfaces when it was created.
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      LOG(ERROR) << "Failed MakeCurrent(compatible_surface)";
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  shared_context_->SetupForVirtualization();
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  shared_context_->MakeVirtuallyCurrent(this, compatible_surface);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLContextVirtual::Destroy() {
51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shared_context_->OnReleaseVirtuallyCurrent(this);
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  shared_context_ = NULL;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  display_ = NULL;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLContextVirtual::MakeCurrent(gfx::GLSurface* surface) {
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (decoder_.get())
585e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    return shared_context_->MakeVirtuallyCurrent(this, surface);
595e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)
605e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  LOG(ERROR) << "Trying to make virtual context current without decoder.";
615e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  return false;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLContextVirtual::ReleaseCurrent(gfx::GLSurface* surface) {
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (IsCurrent(surface)) {
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    shared_context_->OnReleaseVirtuallyCurrent(this);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shared_context_->ReleaseCurrent(surface);
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLContextVirtual::IsCurrent(gfx::GLSurface* surface) {
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If it's a real surface it needs to be current.
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (surface &&
7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      !surface->IsOffscreen())
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return shared_context_->IsCurrent(surface);
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Otherwise, only insure the context itself is current.
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return shared_context_->IsCurrent(NULL);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* GLContextVirtual::GetHandle() {
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return shared_context_->GetHandle();
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GLContextVirtual::SetSwapInterval(int interval) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shared_context_->SetSwapInterval(interval);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GLContextVirtual::GetExtensions() {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return shared_context_->GetExtensions();
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLContextVirtual::GetTotalGpuMemory(size_t* bytes) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return shared_context_->GetTotalGpuMemory(bytes);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLContextVirtual::SetSafeToForceGpuSwitch() {
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(ccameron): This will not work if two contexts that disagree
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // about whether or not forced gpu switching may be done both share
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the same underlying shared_context_.
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return shared_context_->SetSafeToForceGpuSwitch();
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GLContextVirtual::WasAllocatedUsingRobustnessExtension() {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return shared_context_->WasAllocatedUsingRobustnessExtension();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GLContextVirtual::SetUnbindFboOnMakeCurrent() {
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  shared_context_->SetUnbindFboOnMakeCurrent();
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLContextVirtual::~GLContextVirtual() {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Destroy();
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gpu
117