| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 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 "chrome/gpu/gpu_backing_store_glx_context.h" | |
| 6 | |
| 7 #include "app/gfx/gl/gl_bindings.h" | |
| 8 #include "app/x11_util.h" | |
| 9 #include "base/scoped_ptr.h" | |
| 10 #include "chrome/gpu/gpu_thread.h" | |
| 11 | |
| 12 // Must be last. | |
| 13 #include <X11/Xutil.h> | |
| 14 | |
| 15 GpuBackingStoreGLXContext::GpuBackingStoreGLXContext(GpuThread* gpu_thread) | |
| 16 : gpu_thread_(gpu_thread), | |
| 17 tried_to_init_(false), | |
| 18 context_(NULL), | |
| 19 previous_window_id_(0), | |
| 20 frame_buffer_for_scrolling_(0), | |
| 21 is_frame_buffer_bound_(false), | |
| 22 temp_scroll_texture_id_(0) { | |
| 23 } | |
| 24 | |
| 25 GpuBackingStoreGLXContext::~GpuBackingStoreGLXContext() { | |
| 26 if (temp_scroll_texture_id_) { | |
| 27 glDeleteTextures(1, &temp_scroll_texture_id_); | |
| 28 temp_scroll_texture_id_ = 0; | |
| 29 } | |
| 30 | |
| 31 if (frame_buffer_for_scrolling_) | |
| 32 glDeleteFramebuffersEXT(1, &frame_buffer_for_scrolling_); | |
| 33 | |
| 34 if (context_) | |
| 35 glXDestroyContext(gpu_thread_->display(), context_); | |
| 36 } | |
| 37 | |
| 38 GLXContext GpuBackingStoreGLXContext::BindContext(XID window_id) { | |
| 39 DCHECK(!is_frame_buffer_bound_); | |
| 40 | |
| 41 if (tried_to_init_) { | |
| 42 if (!context_) | |
| 43 return NULL; | |
| 44 if (!previous_window_id_ || previous_window_id_ != window_id) { | |
| 45 bool success = glXMakeCurrent(gpu_thread_->display(), window_id, | |
| 46 context_); | |
| 47 DCHECK(success); | |
| 48 } | |
| 49 previous_window_id_ = window_id; | |
| 50 return context_; | |
| 51 } | |
| 52 tried_to_init_ = true; | |
| 53 | |
| 54 int attrib_list[] = { GLX_RGBA, GLX_DOUBLEBUFFER, 0 }; | |
| 55 scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> visual_info( | |
| 56 glXChooseVisual(gpu_thread_->display(), 0, attrib_list)); | |
| 57 if (!visual_info.get()) | |
| 58 return NULL; | |
| 59 | |
| 60 context_ = glXCreateContext(gpu_thread_->display(), visual_info.get(), | |
| 61 NULL, True); | |
| 62 bool success = glXMakeCurrent(gpu_thread_->display(), window_id, context_); | |
| 63 DCHECK(success); | |
| 64 return context_; | |
| 65 } | |
| 66 | |
| 67 bool GpuBackingStoreGLXContext::BindTextureForScrolling( | |
| 68 XID window_id, | |
| 69 const gfx::Size& size) { | |
| 70 DCHECK(!is_frame_buffer_bound_); | |
| 71 BindContext(window_id); | |
| 72 | |
| 73 // Create a new destination texture if the old one isn't properly sized. | |
| 74 // This means we try to re-use old ones without re-creating all the texture | |
| 75 // to save work in the common case of scrolling a window repeatedly that | |
| 76 // doesn't change size. | |
| 77 if (temp_scroll_texture_id_ == 0 || | |
| 78 size != temp_scroll_texture_size_) { | |
| 79 if (!temp_scroll_texture_id_) { | |
| 80 // There may be no temporary one created yet. | |
| 81 glGenTextures(1, &temp_scroll_texture_id_); | |
| 82 } | |
| 83 | |
| 84 // Create a new texture in the context with random garbage in it large | |
| 85 // enough to fit the required size. | |
| 86 glBindTexture(GL_TEXTURE_2D, temp_scroll_texture_id_); | |
| 87 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
| 88 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
| 89 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), | |
| 90 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); | |
| 91 glBindTexture(GL_TEXTURE_2D, 0); | |
| 92 } | |
| 93 | |
| 94 if (!frame_buffer_for_scrolling_) | |
| 95 glGenFramebuffersEXT(1, &frame_buffer_for_scrolling_); | |
| 96 glBindFramebufferEXT(GL_FRAMEBUFFER, frame_buffer_for_scrolling_); | |
| 97 is_frame_buffer_bound_ = true; | |
| 98 | |
| 99 // Release our color attachment. | |
| 100 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, | |
| 101 temp_scroll_texture_id_, 0); | |
| 102 | |
| 103 DCHECK(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == | |
| 104 GL_FRAMEBUFFER_COMPLETE_EXT); | |
| 105 return true; | |
| 106 } | |
| 107 | |
| 108 unsigned int GpuBackingStoreGLXContext::SwapTextureForScrolling( | |
| 109 unsigned int old_texture, | |
| 110 const gfx::Size& old_size) { | |
| 111 // Unbind the framebuffer, which we expect to be bound. | |
| 112 DCHECK(is_frame_buffer_bound_); | |
| 113 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); | |
| 114 is_frame_buffer_bound_ = false; | |
| 115 | |
| 116 DCHECK(temp_scroll_texture_id_); | |
| 117 unsigned int new_texture = temp_scroll_texture_id_; | |
| 118 | |
| 119 temp_scroll_texture_id_ = old_texture; | |
| 120 temp_scroll_texture_size_ = old_size; | |
| 121 | |
| 122 return new_texture; | |
| 123 } | |
| OLD | NEW |