diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/libwebrtc/test/linux/glx_renderer.cc | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/third_party/libwebrtc/test/linux/glx_renderer.cc b/third_party/libwebrtc/test/linux/glx_renderer.cc new file mode 100644 index 0000000000..509a6c286e --- /dev/null +++ b/third_party/libwebrtc/test/linux/glx_renderer.cc @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "test/linux/glx_renderer.h" + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <stdlib.h> + +namespace webrtc { +namespace test { + +GlxRenderer::GlxRenderer(size_t width, size_t height) + : width_(width), height_(height), display_(NULL), context_(NULL) { + RTC_DCHECK_GT(width, 0); + RTC_DCHECK_GT(height, 0); +} + +GlxRenderer::~GlxRenderer() { + Destroy(); +} + +bool GlxRenderer::Init(const char* window_title) { + if ((display_ = XOpenDisplay(NULL)) == NULL) { + Destroy(); + return false; + } + + int screen = DefaultScreen(display_); + + XVisualInfo* vi; + int attr_list[] = { + GLX_DOUBLEBUFFER, GLX_RGBA, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, + GLX_BLUE_SIZE, 4, GLX_DEPTH_SIZE, 16, None, + }; + + if ((vi = glXChooseVisual(display_, screen, attr_list)) == NULL) { + Destroy(); + return false; + } + + context_ = glXCreateContext(display_, vi, 0, true); + if (context_ == NULL) { + Destroy(); + return false; + } + + XSetWindowAttributes window_attributes; + window_attributes.colormap = XCreateColormap( + display_, RootWindow(display_, vi->screen), vi->visual, AllocNone); + window_attributes.border_pixel = 0; + window_attributes.event_mask = StructureNotifyMask | ExposureMask; + window_ = XCreateWindow(display_, RootWindow(display_, vi->screen), 0, 0, + width_, height_, 0, vi->depth, InputOutput, + vi->visual, CWBorderPixel | CWColormap | CWEventMask, + &window_attributes); + XFree(vi); + + XSetStandardProperties(display_, window_, window_title, window_title, None, + NULL, 0, NULL); + + Atom wm_delete = XInternAtom(display_, "WM_DELETE_WINDOW", True); + if (wm_delete != None) { + XSetWMProtocols(display_, window_, &wm_delete, 1); + } + + XMapRaised(display_, window_); + + if (!glXMakeCurrent(display_, window_, context_)) { + Destroy(); + return false; + } + GlRenderer::Init(); + if (!glXMakeCurrent(display_, None, NULL)) { + Destroy(); + return false; + } + + Resize(width_, height_); + return true; +} + +void GlxRenderer::Destroy() { + if (context_ != NULL) { + glXMakeCurrent(display_, window_, context_); + GlRenderer::Destroy(); + glXMakeCurrent(display_, None, NULL); + glXDestroyContext(display_, context_); + context_ = NULL; + } + + if (display_ != NULL) { + XCloseDisplay(display_); + display_ = NULL; + } +} + +GlxRenderer* GlxRenderer::Create(const char* window_title, + size_t width, + size_t height) { + GlxRenderer* glx_renderer = new GlxRenderer(width, height); + if (!glx_renderer->Init(window_title)) { + // TODO(pbos): Add GLX-failed warning here? + delete glx_renderer; + return NULL; + } + return glx_renderer; +} + +void GlxRenderer::Resize(size_t width, size_t height) { + width_ = width; + height_ = height; + if (!glXMakeCurrent(display_, window_, context_)) { + abort(); + } + GlRenderer::ResizeViewport(width_, height_); + if (!glXMakeCurrent(display_, None, NULL)) { + abort(); + } + + XSizeHints* size_hints = XAllocSizeHints(); + if (size_hints == NULL) { + abort(); + } + size_hints->flags = PAspect; + size_hints->min_aspect.x = size_hints->max_aspect.x = width_; + size_hints->min_aspect.y = size_hints->max_aspect.y = height_; + XSetWMNormalHints(display_, window_, size_hints); + XFree(size_hints); + + XWindowChanges wc; + wc.width = static_cast<int>(width); + wc.height = static_cast<int>(height); + XConfigureWindow(display_, window_, CWWidth | CWHeight, &wc); +} + +void GlxRenderer::OnFrame(const webrtc::VideoFrame& frame) { + if (static_cast<size_t>(frame.width()) != width_ || + static_cast<size_t>(frame.height()) != height_) { + Resize(static_cast<size_t>(frame.width()), + static_cast<size_t>(frame.height())); + } + + XEvent event; + if (!glXMakeCurrent(display_, window_, context_)) { + abort(); + } + while (XPending(display_)) { + XNextEvent(display_, &event); + switch (event.type) { + case ConfigureNotify: + GlRenderer::ResizeViewport(event.xconfigure.width, + event.xconfigure.height); + break; + default: + break; + } + } + + GlRenderer::OnFrame(frame); + glXSwapBuffers(display_, window_); + + if (!glXMakeCurrent(display_, None, NULL)) { + abort(); + } +} +} // namespace test +} // namespace webrtc |