From patchwork Tue May 15 08:44:09 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: alexandros.frantzis@linaro.org X-Patchwork-Id: 8639 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id F2E1C23EAB for ; Tue, 15 May 2012 08:44:13 +0000 (UTC) Received: from mail-yx0-f180.google.com (mail-yx0-f180.google.com [209.85.213.180]) by fiordland.canonical.com (Postfix) with ESMTP id 90C85A18309 for ; Tue, 15 May 2012 08:44:13 +0000 (UTC) Received: by yenq6 with SMTP id q6so6436284yen.11 for ; Tue, 15 May 2012 01:44:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf :content-type:mime-version:x-launchpad-project:x-launchpad-branch :x-launchpad-message-rationale:x-launchpad-branch-revision-number :x-launchpad-notification-type:to:from:subject:message-id:date :reply-to:sender:errors-to:precedence:x-generated-by :x-launchpad-hash:x-gm-message-state; bh=/YAMF7/jgg1qKZlhwsoC8atYhI/QonSwXgqdjtEwzKg=; b=WoAtxrpXX5Z219XEgbxCPBroS5x0xmyqe2tD+fYsfvJRgVLHNSY9av443v1mAzvEVW TDYh7X5RoSWbUvPB8L9uvFf8r/SAgWqiphSGa45knNWcHv1vbi9rHqyBLBpKiElfVsm2 fbhLwT1Yz3BnqNrxFeg3f9nsK/L58UPjY6HV3k2Xl55rBrr9pb71Ru7MFnWbd3YzKvye SDd2CdOJvIXhHEkrplY+EtS6nRJlSZGsqofOBcYU9g9uaXK8xikIW3lpQH8E3+xdNqFd b5bSCwrp6/ZXNhXziSEMAMVfQHvThktrpvtuwJsb7hu8Izr27XBAAXidddLAHLljZWuv ogeg== Received: by 10.50.154.169 with SMTP id vp9mr6254652igb.53.1337071452806; Tue, 15 May 2012 01:44:12 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.35.72 with SMTP id o8csp403793ibd; Tue, 15 May 2012 01:44:11 -0700 (PDT) Received: by 10.180.81.66 with SMTP id y2mr27869491wix.22.1337071450734; Tue, 15 May 2012 01:44:10 -0700 (PDT) Received: from indium.canonical.com (indium.canonical.com. [91.189.90.7]) by mx.google.com with ESMTPS id z55si18771026wem.97.2012.05.15.01.44.10 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 15 May 2012 01:44:10 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) client-ip=91.189.90.7; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) smtp.mail=bounces@canonical.com Received: from ackee.canonical.com ([91.189.89.26]) by indium.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1SUDMX-0005Do-V8 for ; Tue, 15 May 2012 08:44:09 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id DCCEFE023D for ; Tue, 15 May 2012 08:44:09 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: glmark2 X-Launchpad-Branch: ~glmark2-dev/glmark2/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 208 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~glmark2-dev/glmark2/trunk] Rev 208: CanvasX11*: Allow user configuration of visual used for rendering. Message-Id: <20120515084409.21820.27948.launchpad@ackee.canonical.com> Date: Tue, 15 May 2012 08:44:09 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="15238"; Instance="launchpad-lazr.conf" X-Launchpad-Hash: 447da33569434a60124dd91cb4eeffaa552025f0 X-Gm-Message-State: ALoCoQkLVIu6ArRZX49w6+wvTFBt5IPvMadzRvVMQEW2GVZ0aTEIlWm/7drmt5duadpAkUB1Zyfn Merge authors: Alexandros Frantzis (afrantzis) Related merge proposals: https://code.launchpad.net/~linaro-graphics-wg/glmark2/configurable-visual/+merge/105642 proposed by: Alexandros Frantzis (afrantzis) review: Approve - Jesse Barker (jesse-barker) ------------------------------------------------------------ revno: 208 [merge] committer: Alexandros Frantzis branch nick: trunk timestamp: Tue 2012-05-15 11:40:46 +0300 message: CanvasX11*: Allow user configuration of visual used for rendering. added: src/gl-visual-config.cpp src/gl-visual-config.h modified: doc/glmark2.1.in src/canvas-x11-egl.cpp src/canvas-x11-egl.h src/canvas-x11-glx.cpp src/canvas-x11-glx.h src/canvas-x11.cpp src/canvas-x11.h src/canvas.h src/main.cpp src/options.cpp src/options.h --- lp:glmark2 https://code.launchpad.net/~glmark2-dev/glmark2/trunk You are subscribed to branch lp:glmark2. To unsubscribe from this branch go to https://code.launchpad.net/~glmark2-dev/glmark2/trunk/+edit-subscription === modified file 'doc/glmark2.1.in' --- doc/glmark2.1.in 2012-03-22 10:37:35 +0000 +++ doc/glmark2.1.in 2012-05-10 09:19:38 +0000 @@ -27,6 +27,11 @@ \fB\-\-off-screen\fR Render to an off-screen surface .TP +\fB--visual-config\fR +The visual configuration to use for the rendering target: +\'red=R:green=G:blue=B:alpha=A:buffer=BUF'. The parameters may be defined +in any order, and any omitted parameters assume a default value of '1' +.TP \fB\-\-reuse\-context\fR Use a single context for all scenes (by default, each scene gets its own context) === modified file 'src/canvas-x11-egl.cpp' --- src/canvas-x11-egl.cpp 2012-03-20 11:16:03 +0000 +++ src/canvas-x11-egl.cpp 2012-05-11 13:53:08 +0000 @@ -25,6 +25,7 @@ #include #include +#include /********************* * Protected methods * @@ -87,17 +88,12 @@ } void -CanvasX11EGL::get_glvisualinfo(GLVisualInfo &gl_visinfo) +CanvasX11EGL::get_glvisualconfig(GLVisualConfig &visual_config) { if (!ensure_egl_config()) return; - eglGetConfigAttrib(egl_display_, egl_config_, EGL_BUFFER_SIZE, &gl_visinfo.buffer_size); - eglGetConfigAttrib(egl_display_, egl_config_, EGL_RED_SIZE, &gl_visinfo.red_size); - eglGetConfigAttrib(egl_display_, egl_config_, EGL_GREEN_SIZE, &gl_visinfo.green_size); - eglGetConfigAttrib(egl_display_, egl_config_, EGL_BLUE_SIZE, &gl_visinfo.blue_size); - eglGetConfigAttrib(egl_display_, egl_config_, EGL_ALPHA_SIZE, &gl_visinfo.alpha_size); - eglGetConfigAttrib(egl_display_, egl_config_, EGL_DEPTH_SIZE, &gl_visinfo.depth_size); + get_glvisualconfig_egl(egl_config_, visual_config); } /******************* @@ -129,12 +125,13 @@ bool CanvasX11EGL::ensure_egl_config() { - static const EGLint attribs[] = { - EGL_RED_SIZE, 1, - EGL_GREEN_SIZE, 1, - EGL_BLUE_SIZE, 1, - EGL_ALPHA_SIZE, 1, - EGL_DEPTH_SIZE, 1, + const EGLint attribs[] = { + EGL_RED_SIZE, visual_config_.red, + EGL_GREEN_SIZE, visual_config_.green, + EGL_BLUE_SIZE, visual_config_.blue, + EGL_ALPHA_SIZE, visual_config_.alpha, + EGL_DEPTH_SIZE, visual_config_.depth, + EGL_BUFFER_SIZE, visual_config_.buffer, #ifdef USE_GLESv2 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, #elif USE_GL @@ -151,14 +148,32 @@ if (!ensure_egl_display()) return false; - if (!eglChooseConfig(egl_display_, attribs, &egl_config_, - 1, &num_configs)) + /* Find out how many configs match the attributes */ + if (!eglChooseConfig(egl_display_, attribs, 0, 0, &num_configs)) { + Log::error("eglChooseConfig() (explore) failed with error: %d\n", + eglGetError()); + return false; + } + + if (num_configs == 0) { + Log::error("eglChooseConfig() didn't return any configs\n"); + return false; + } + + /* Get all the matching configs */ + std::vector configs(num_configs); + + if (!eglChooseConfig(egl_display_, attribs, &(configs[0]), + num_configs, &num_configs)) { Log::error("eglChooseConfig() failed with error: %d\n", eglGetError()); return false; } + /* Select the best matching config */ + egl_config_ = select_best_config(configs); + if (!eglGetConfigAttrib(egl_display_, egl_config_, EGL_NATIVE_VISUAL_ID, &vid)) { @@ -281,3 +296,45 @@ GLExtensions::UnmapBuffer = glUnmapBuffer; #endif } + +void +CanvasX11EGL::get_glvisualconfig_egl(EGLConfig config, GLVisualConfig &visual_config) +{ + eglGetConfigAttrib(egl_display_, config, EGL_BUFFER_SIZE, &visual_config.buffer); + eglGetConfigAttrib(egl_display_, config, EGL_RED_SIZE, &visual_config.red); + eglGetConfigAttrib(egl_display_, config, EGL_GREEN_SIZE, &visual_config.green); + eglGetConfigAttrib(egl_display_, config, EGL_BLUE_SIZE, &visual_config.blue); + eglGetConfigAttrib(egl_display_, config, EGL_ALPHA_SIZE, &visual_config.alpha); + eglGetConfigAttrib(egl_display_, config, EGL_DEPTH_SIZE, &visual_config.depth); +} + +EGLConfig +CanvasX11EGL::select_best_config(std::vector configs) +{ + int best_score(INT_MIN); + EGLConfig best_config(0); + + /* + * Go through all the configs and choose the one with the best score, + * i.e., the one better matching the requested config. + */ + for (std::vector::const_iterator iter = configs.begin(); + iter != configs.end(); + iter++) + { + const EGLConfig config(*iter); + GLVisualConfig vc; + int score; + + get_glvisualconfig_egl(config, vc); + + score = vc.match_score(visual_config_); + + if (score > best_score) { + best_score = score; + best_config = config; + } + } + + return best_config; +} === modified file 'src/canvas-x11-egl.h' --- src/canvas-x11-egl.h 2012-03-19 16:55:27 +0000 +++ src/canvas-x11-egl.h 2012-05-11 13:53:08 +0000 @@ -25,6 +25,7 @@ #include "canvas-x11.h" #include +#include /** * Canvas for rendering to an X11 window using EGL. @@ -43,7 +44,7 @@ bool make_current(); bool reset_context(); void swap_buffers() { eglSwapBuffers(egl_display_, egl_surface_); } - void get_glvisualinfo(GLVisualInfo &gl_visinfo); + void get_glvisualconfig(GLVisualConfig &visual_config); private: bool ensure_egl_display(); @@ -51,6 +52,8 @@ bool ensure_egl_context(); bool ensure_egl_surface(); void init_gl_extensions(); + void get_glvisualconfig_egl(EGLConfig config, GLVisualConfig &visual_config); + EGLConfig select_best_config(std::vector configs); EGLDisplay egl_display_; EGLSurface egl_surface_; === modified file 'src/canvas-x11-glx.cpp' --- src/canvas-x11-glx.cpp 2012-03-19 16:55:27 +0000 +++ src/canvas-x11-glx.cpp 2012-05-11 13:53:08 +0000 @@ -24,6 +24,7 @@ #include "options.h" #include +#include static PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT_; static PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESA_; @@ -69,17 +70,12 @@ } void -CanvasX11GLX::get_glvisualinfo(GLVisualInfo &gl_visinfo) +CanvasX11GLX::get_glvisualconfig(GLVisualConfig &visual_config) { if (!ensure_glx_fbconfig()) return; - glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_BUFFER_SIZE, &gl_visinfo.buffer_size); - glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_RED_SIZE, &gl_visinfo.red_size); - glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_GREEN_SIZE, &gl_visinfo.green_size); - glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_BLUE_SIZE, &gl_visinfo.blue_size); - glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_ALPHA_SIZE, &gl_visinfo.alpha_size); - glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_DEPTH_SIZE, &gl_visinfo.depth_size); + get_glvisualconfig_glx(glx_fbconfig_, visual_config); } /******************* @@ -151,11 +147,12 @@ GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - GLX_ALPHA_SIZE, 1, - GLX_DEPTH_SIZE, 1, + GLX_RED_SIZE, visual_config_.red, + GLX_GREEN_SIZE, visual_config_.green, + GLX_BLUE_SIZE, visual_config_.blue, + GLX_ALPHA_SIZE, visual_config_.alpha, + GLX_DEPTH_SIZE, visual_config_.depth, + GLX_BUFFER_SIZE, visual_config_.buffer, GLX_DOUBLEBUFFER, True, None }; @@ -174,10 +171,12 @@ return false; } + std::vector configs(fbc, fbc + num_configs); + Log::debug("Found %d matching FB configs.\n", num_configs); - /* Get the first matching config */ - glx_fbconfig_ = fbc[0]; + /* Select the best matching config */ + glx_fbconfig_ = select_best_config(configs); XFree(fbc); @@ -243,3 +242,44 @@ return true; } +void +CanvasX11GLX::get_glvisualconfig_glx(const GLXFBConfig config, GLVisualConfig &visual_config) +{ + glXGetFBConfigAttrib(xdpy_, config, GLX_BUFFER_SIZE, &visual_config.buffer); + glXGetFBConfigAttrib(xdpy_, config, GLX_RED_SIZE, &visual_config.red); + glXGetFBConfigAttrib(xdpy_, config, GLX_GREEN_SIZE, &visual_config.green); + glXGetFBConfigAttrib(xdpy_, config, GLX_BLUE_SIZE, &visual_config.blue); + glXGetFBConfigAttrib(xdpy_, config, GLX_ALPHA_SIZE, &visual_config.alpha); + glXGetFBConfigAttrib(xdpy_, config, GLX_DEPTH_SIZE, &visual_config.depth); +} + +GLXFBConfig +CanvasX11GLX::select_best_config(std::vector configs) +{ + int best_score(INT_MIN); + GLXFBConfig best_config(0); + + /* + * Go through all the configs and choose the one with the best score, + * i.e., the one better matching the requested config. + */ + for (std::vector::const_iterator iter = configs.begin(); + iter != configs.end(); + iter++) + { + const GLXFBConfig config(*iter); + GLVisualConfig vc; + int score; + + get_glvisualconfig_glx(config, vc); + + score = vc.match_score(visual_config_); + + if (score > best_score) { + best_score = score; + best_config = config; + } + } + + return best_config; +} === modified file 'src/canvas-x11-glx.h' --- src/canvas-x11-glx.h 2012-03-19 16:55:27 +0000 +++ src/canvas-x11-glx.h 2012-05-11 13:53:08 +0000 @@ -27,6 +27,7 @@ #define GLX_GLXEXT_PROTOTYPES #include #include +#include /** * Canvas for rendering to an X11 window using GLX. @@ -43,7 +44,7 @@ bool make_current(); bool reset_context(); void swap_buffers() { glXSwapBuffers(xdpy_, xwin_); } - void get_glvisualinfo(GLVisualInfo &gl_visinfo); + void get_glvisualconfig(GLVisualConfig &visual_config); private: bool check_glx_version(); @@ -51,6 +52,8 @@ bool ensure_glx_fbconfig(); bool ensure_glx_context(); void init_gl_extensions(); + void get_glvisualconfig_glx(GLXFBConfig config, GLVisualConfig &visual_config); + GLXFBConfig select_best_config(std::vector configs); GLXFBConfig glx_fbconfig_; GLXContext glx_context_; === modified file 'src/canvas-x11.cpp' --- src/canvas-x11.cpp 2012-05-07 12:45:34 +0000 +++ src/canvas-x11.cpp 2012-05-11 11:02:37 +0000 @@ -350,8 +350,8 @@ if (gl_color_format_ && gl_depth_format_) return true; - GLVisualInfo gl_visinfo; - get_glvisualinfo(gl_visinfo); + GLVisualConfig vc; + get_glvisualconfig(vc); gl_color_format_ = 0; gl_depth_format_ = 0; @@ -382,41 +382,41 @@ supports_depth32 = true; #endif - if (gl_visinfo.buffer_size == 32) { + if (vc.buffer == 32) { if (supports_rgba8) gl_color_format_ = GL_RGBA8; else gl_color_format_ = GL_RGBA4; } - else if (gl_visinfo.buffer_size == 24) { + else if (vc.buffer == 24) { if (supports_rgb8) gl_color_format_ = GL_RGB8; else gl_color_format_ = GL_RGB565; } - else if (gl_visinfo.buffer_size == 16) { - if (gl_visinfo.red_size == 4 && gl_visinfo.green_size == 4 && - gl_visinfo.blue_size == 4 && gl_visinfo.alpha_size == 4) + else if (vc.buffer == 16) { + if (vc.red == 4 && vc.green == 4 && + vc.blue == 4 && vc.alpha == 4) { gl_color_format_ = GL_RGBA4; } - else if (gl_visinfo.red_size == 5 && gl_visinfo.green_size == 5 && - gl_visinfo.blue_size == 5 && gl_visinfo.alpha_size == 1) + else if (vc.red == 5 && vc.green == 5 && + vc.blue == 5 && vc.alpha == 1) { gl_color_format_ = GL_RGB5_A1; } - else if (gl_visinfo.red_size == 5 && gl_visinfo.green_size == 6 && - gl_visinfo.blue_size == 5 && gl_visinfo.alpha_size == 0) + else if (vc.red == 5 && vc.green == 6 && + vc.blue == 5 && vc.alpha == 0) { gl_color_format_ = GL_RGB565; } } - if (gl_visinfo.depth_size == 32 && supports_depth32) + if (vc.depth == 32 && supports_depth32) gl_depth_format_ = GL_DEPTH_COMPONENT32; - else if (gl_visinfo.depth_size >= 24 && supports_depth24) + else if (vc.depth >= 24 && supports_depth24) gl_depth_format_ = GL_DEPTH_COMPONENT24; - else if (gl_visinfo.depth_size == 16) + else if (vc.depth == 16) gl_depth_format_ = GL_DEPTH_COMPONENT16; Log::debug("Selected Renderbuffer ColorFormat: %s DepthFormat: %s\n", === modified file 'src/canvas-x11.h' --- src/canvas-x11.h 2012-03-20 11:29:09 +0000 +++ src/canvas-x11.h 2012-05-11 11:02:37 +0000 @@ -53,18 +53,6 @@ color_renderbuffer_(0), depth_renderbuffer_(0), fbo_(0) {} /** - * Information about a GL visual. - */ - struct GLVisualInfo { - int buffer_size; - int red_size; - int green_size; - int blue_size; - int alpha_size; - int depth_size; - }; - - /** * Gets the XVisualInfo to use for creating the X window with. * * The caller should XFree() the returned XVisualInfo when done. @@ -107,7 +95,7 @@ * * This method should be implemented in derived classes. */ - virtual void get_glvisualinfo(GLVisualInfo &gl_visinfo) = 0; + virtual void get_glvisualconfig(GLVisualConfig &visual_config) = 0; /** * Whether the current implementation supports GL(ES) 2.0. === modified file 'src/canvas.h' --- src/canvas.h 2012-03-15 12:17:22 +0000 +++ src/canvas.h 2012-05-10 09:03:12 +0000 @@ -27,6 +27,7 @@ #include "gl-headers.h" #include "mat.h" +#include "gl-visual-config.h" #include #include @@ -86,6 +87,7 @@ uint8_t a; }; + /** * Initializes the canvas and makes it the target of GL operations. * @@ -238,6 +240,13 @@ */ void offscreen(bool offscreen) { offscreen_ = offscreen; } + /** + * Sets the preferred visual configuration. + * + * This takes effect after the next init()/reset(). + */ + void visual_config(GLVisualConfig &config) { visual_config_ = config; } + protected: Canvas(int width, int height) : width_(width), height_(height), offscreen_(false) {} @@ -246,6 +255,7 @@ int height_; LibMatrix::mat4 projection_; bool offscreen_; + GLVisualConfig visual_config_; }; #endif === added file 'src/gl-visual-config.cpp' --- src/gl-visual-config.cpp 1970-01-01 00:00:00 +0000 +++ src/gl-visual-config.cpp 2012-05-11 13:49:53 +0000 @@ -0,0 +1,120 @@ +/* + * Copyright © 2012 Linaro Limited + * + * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. + * + * glmark2 is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * glmark2. If not, see . + * + * Authors: + * Alexandros Frantzis + */ +#include "gl-visual-config.h" +#include "util.h" +#include "log.h" + +#include + +GLVisualConfig::GLVisualConfig(const std::string &s) : + red(1), green(1), blue(1), alpha(1), depth(1), buffer(1) +{ + std::vector elems; + + Util::split(s, ':', elems); + + for (std::vector::const_iterator iter = elems.begin(); + iter != elems.end(); + iter++) + { + std::vector opt; + + Util::split(*iter, '=', opt); + if (opt.size() == 2) { + if (opt[0] == "r" || opt[0] == "red") + red = Util::fromString(opt[1]); + else if (opt[0] == "g" || opt[0] == "green") + green = Util::fromString(opt[1]); + else if (opt[0] == "b" || opt[0] == "blue") + blue = Util::fromString(opt[1]); + else if (opt[0] == "a" || opt[0] == "alpha") + alpha = Util::fromString(opt[1]); + else if (opt[0] == "d" || opt[0] == "depth") + depth = Util::fromString(opt[1]); + else if (opt[0] == "buf" || opt[0] == "buffer") + buffer = Util::fromString(opt[1]); + } + else + Log::info("Warning: ignoring invalid option string '%s' " + "in GLVisualConfig description\n", + iter->c_str()); + } +} + +int +GLVisualConfig::match_score(const GLVisualConfig &target) const +{ + int score(0); + + /* + * R,G,B,A integer values are at most 8 bits wide (for current widespread + * hardware), so we need to scale them by 4 to get them in the [0,32] range. + */ + score += score_component(red, target.red, 4); + score += score_component(green, target.green, 4); + score += score_component(blue, target.blue, 4); + score += score_component(alpha, target.alpha, 4); + score += score_component(depth, target.depth, 1); + score += score_component(buffer, target.buffer, 1); + + return score; +} + +int +GLVisualConfig::score_component(int component, int target, int scale) const +{ + /* + * The maximum (positive) score that can be returned is based + * on the maximum bit width of the components. We assume this to + * be 32 bits, which is a reasonable assumption for current platforms. + */ + static const int MAXIMUM_COMPONENT_SCORE = 32; + static const int UNACCEPTABLE_COMPONENT_PENALTY = -1000; + int score(0); + + if ((component > 0 && target == 0) || + (component == 0 && target > 0)) + { + /* + * Penalize components that are not present but have been requested, + * and components that have been excluded but are present. + */ + score = UNACCEPTABLE_COMPONENT_PENALTY; + } + else if (component == target) + { + /* Reward exact matches with the maximum per component score */ + score = MAXIMUM_COMPONENT_SCORE; + } + else + { + /* + * Reward deeper than requested component values, penalize shallower + * than requested component values. Because the ranges of component + * values vary we use a scaling factor to even them out, so that the + * score for all components ranges from [0,MAXIMUM_COMPONENT_SCORE). + */ + score = scale * (component - target); + } + + return score; +} === added file 'src/gl-visual-config.h' --- src/gl-visual-config.h 1970-01-01 00:00:00 +0000 +++ src/gl-visual-config.h 2012-05-11 13:49:53 +0000 @@ -0,0 +1,64 @@ +/* + * Copyright © 2012 Linaro Limited + * + * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. + * + * glmark2 is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * glmark2. If not, see . + * + * Authors: + * Alexandros Frantzis + */ +#ifndef GLMARK2_GL_VISUAL_CONFIG_H_ +#define GLMARK2_GL_VISUAL_CONFIG_H_ + +#include + +/** + * Configuration parameters for a GL visual + */ +class GLVisualConfig +{ +public: + GLVisualConfig(): + red(1), green(1), blue(1), alpha(1), depth(1), buffer(1) {} + GLVisualConfig(int r, int g, int b, int a, int d, int buf): + red(r), green(g), blue(b), alpha(a), depth(d), buffer(buf) {} + GLVisualConfig(const std::string &s); + + /** + * How well a GLVisualConfig matches another target config. + * + * The returned score has no meaning on its own. Its only purpose is + * to allow comparison of how well different configs match a target + * config, with a higher scores denoting a better match. + * + * Also note that this operation is not commutative: + * a.match_score(b) != b.match_score(a) + * + * @return the match score + */ + int match_score(const GLVisualConfig &target) const; + + int red; + int green; + int blue; + int alpha; + int depth; + int buffer; + +private: + int score_component(int component, int target, int scale) const; +}; + +#endif === modified file 'src/main.cpp' --- src/main.cpp 2012-04-27 18:00:45 +0000 +++ src/main.cpp 2012-05-15 08:40:46 +0000 @@ -168,6 +168,8 @@ canvas.offscreen(Options::offscreen); + canvas.visual_config(Options::visual_config); + vector scenes; // Register the scenes, so they can be looked up by name === modified file 'src/options.cpp' --- src/options.cpp 2012-03-20 12:55:49 +0000 +++ src/options.cpp 2012-05-10 09:18:53 +0000 @@ -43,6 +43,7 @@ bool Options::run_forever = false; bool Options::annotate = false; bool Options::offscreen = false; +GLVisualConfig Options::visual_config; static struct option long_options[] = { {"annotate", 0, 0, 0}, @@ -51,6 +52,7 @@ {"validate", 0, 0, 0}, {"frame-end", 1, 0, 0}, {"off-screen", 0, 0, 0}, + {"visual-config", 1, 0, 0}, {"reuse-context", 0, 0, 0}, {"run-forever", 0, 0, 0}, {"size", 1, 0, 0}, @@ -109,7 +111,6 @@ return m; } - void Options::print_help() { @@ -125,6 +126,10 @@ " running the benchmarks\n" " --frame-end METHOD How to end a frame [default,none,swap,finish,readpixels]\n" " --off-screen Render to an off-screen surface\n" + " --visual-config C The visual configuration to use for the rendering\n" + " target: 'red=R:green=G:blue=B:alpha=A:buffer=BUF'.\n" + " The parameters may be defined in any order, and any\n" + " omitted parameters assume a default value of '1'\n" " --reuse-context Use a single context for all scenes\n" " (by default, each scene gets its own context)\n" " -s, --size WxH Size of the output window (default: 800x600)\n" @@ -170,6 +175,8 @@ Options::frame_end = frame_end_from_str(optarg); else if (!strcmp(optname, "off-screen")) Options::offscreen = true; + else if (!strcmp(optname, "visual-config")) + Options::visual_config = GLVisualConfig(optarg); else if (!strcmp(optname, "reuse-context")) Options::reuse_context = true; else if (c == 's' || !strcmp(optname, "size")) === modified file 'src/options.h' --- src/options.h 2012-03-20 12:55:49 +0000 +++ src/options.h 2012-05-10 09:18:53 +0000 @@ -26,6 +26,7 @@ #include #include +#include "gl-visual-config.h" struct Options { enum FrameEnd { @@ -52,6 +53,7 @@ static bool run_forever; static bool annotate; static bool offscreen; + static GLVisualConfig visual_config; }; #endif /* OPTIONS_H_ */