Mir

Merge lp:~raof/mir/check-for-surfaceless into lp:mir

Proposed by Chris Halse Rogers
Status: Merged
Approved by: Alan Griffiths
Approved revision: no longer in the source branch.
Merged at revision: 1297
Proposed branch: lp:~raof/mir/check-for-surfaceless
Merge into: lp:mir
Diff against target: 928 lines (+406/-151)
21 files modified
include/platform/mir/graphics/gl_context.h (+2/-2)
include/server/mir/graphics/gl_extensions_base.h (+3/-6)
include/server/mir/graphics/surfaceless_egl_context.h (+11/-10)
include/test/mir_test_doubles/null_gl_context.h (+2/-2)
src/platform/graphics/android/gl_context.cpp (+2/-2)
src/platform/graphics/android/gl_context.h (+2/-2)
src/platform/graphics/mesa/display.cpp (+2/-2)
src/platform/graphics/mesa/display_helpers.cpp (+2/-2)
src/platform/graphics/mesa/display_helpers.h (+2/-2)
src/server/graphics/CMakeLists.txt (+2/-0)
src/server/graphics/gl_extensions_base.cpp (+4/-4)
src/server/graphics/nested/nested_display.cpp (+4/-45)
src/server/graphics/offscreen/CMakeLists.txt (+0/-2)
src/server/graphics/offscreen/display.cpp (+1/-29)
src/server/graphics/offscreen/display.h (+1/-1)
src/server/graphics/offscreen/display_buffer.cpp (+3/-3)
src/server/graphics/offscreen/display_buffer.h (+1/-1)
src/server/graphics/surfaceless_egl_context.cpp (+103/-32)
tests/unit-tests/graphics/CMakeLists.txt (+1/-0)
tests/unit-tests/graphics/test_surfaceless_egl_context.cpp (+254/-0)
tests/unit-tests/scene/test_gl_pixel_buffer.cpp (+4/-4)
To merge this branch: bzr merge lp:~raof/mir/check-for-surfaceless
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Daniel van Vugt Approve
Alexandros Frantzis (community) Abstain
Chris Halse Rogers Approve
Andreas Pokorny (community) Approve
Review via email: mp+198510@code.launchpad.net

Commit message

nested: Check for, and prefer, EGL_KHR_surfaceless_context over dummy pbuffer surfaces

It seems that at least one of our Android stacks doesn't support
EGL_KHR_surfaceless_context, and Mesa doesn't support pbuffer surfaces.

Fixes nested on Mesa (LP: #1260635)

Description of the change

nested: Check for, and prefer, EGL_KHR_surfaceless_context over dummy pbuffer surfaces

It seems that at least one of our Android stacks doesn't support EGL_KHR_surfaceless_context,
and Mesa doesn't support pbuffer surfaces.

Fixes nested on Mesa

To post a comment you must log in.
Revision history for this message
Chris Halse Rogers (raof) wrote :

Note: I'm in the process of testing nested on Android. Although I don't see how this would fail on Android, it'd be courteous to check that nested still works before top approving this :)

review: Needs Information
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Looks good, if you ignore what C++ forces us to do with initializer lists :(

Nit: Missing an underscore:
31 + (khr_surfaceless_context ? " (using EGL_KHR_surfaceless context)\n" :

review: Approve
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

I think

16 + khr_surfaceless_context(strstr(eglQueryString(egl_display, EGL_EXTENSIONS), "EGL_KHR_surfaceless_context") != nullptr)
 wants to be a utility function for querying egl extension existance

You could also turn
20 + egl_surface( .... )

 into
  egl_surface( EGLSurfaceStore::create_dummy_surface(egl_display, egl_config, khr_surfaceless_context) )

and evade control flow in the initializer list.

-> yay and that would be my first launchpad review.

review: Needs Fixing
Revision history for this message
Chris Halse Rogers (raof) wrote :

Ok, confirmed that this doesn't break android. Time to address some reviews!

Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

You might also want to take a look at graphics/offscreen/surfaceless_egl_context.cpp and friends, which already provide the needed functionality.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

looks fine to me

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Chris Halse Rogers (raof) wrote :

Now really tested on Android (I didn't know you could run two different mir_demo_server_shells against the hardware simultaneously!), and with some tests. That pass!

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Verified nesting now works on desktop (LP: #1260635)

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Only minor issues...

1. Typo:
77 + /* We have to explicitly define this, as GLContext has a deleted copy construtor */

2. constness of make_current/release_current; I don't think this is necessary and doesn't look very natural to make such operations const. The ability to make them const is probably only because they're implemented using non-C++ objects (EGL). It seems likely they might have to lose the constness at some point in future following other changes.

3. while (parentheses_dont_match_mir_stye) {
    needs_fixing
   }
I prefer this style, but it's too much of an obvious deviation from the Mir project style.

4. Unreadably long identifiers:
768 +TEST_F(SurfacelessEGLContextTest, RequestsPBufferWhenNoSurfacelessAndAttribsDoesNotContainSurfaceSpecifier)
787 +TEST_F(SurfacelessEGLContextTest, RequestsPBufferWhenNoSurfacelessAndAttribsContainsNonPBufferSurfaceType)
On that theme, so are lines longer than 80 columns.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

578 +mg::SurfacelessEGLContext::SurfacelessEGLContext(

587 +mg::SurfacelessEGLContext::SurfacelessEGLContext(
588 + EGLDisplay egl_display,
589 + EGLint const* attribs,
590 + EGLContext shared_context)

It would be clearer to implement the SurfaceEGLContext(egl_display, shared_context) constructor in terms of the new SurfaceEGLContext(egl_display, attribs, shared_context) constructor, by passing our default config attribs:

SurfacelessEGLContext(EGLDisplay egl_display, EGLContext shared_context)
 : SurfacelessEGLContext(egl_display, default_attribs, shared_context)

429 +mgo::DisplayBuffer::DisplayBuffer(SurfacelessEGLContext &&egl_context,
430 geom::Rectangle const& area)
431 - : egl_context{std::move(egl_context)},
432 + : egl_context{std::forward<SurfacelessEGLContext>(egl_context)},

It's better to accept a move only type (such as SurfacelessEGLContext or std::unique_ptr<>) by value vs rvalue reference: see https://code.launchpad.net/~rocket-scientists/mir/buffer-swapper-multi/+merge/139127/comments/301713 .

Also, with this code, since the egl_context parameter is an rvalue reference, not a universal reference, using std::forward doesn't offer any benefits over using std::move.

613 + move.egl_display = EGL_NO_DISPLAY;

618 + release_current();

A invalidated (i.e. moved) SurfacelessEGLContext object may try to release the EGL context when being destroyed. Although this will have no effect since egl_display == EGL_NO_DISPLAY, I think it would be better to not try at all to avoid error/debug messages from EGL.

review: Needs Fixing
Revision history for this message
Chris Halse Rogers (raof) wrote :

On Mon, 2013-12-16 at 11:40 +0000, Alexandros Frantzis wrote:
> Review: Needs Fixing
>
> 578 +mg::SurfacelessEGLContext::SurfacelessEGLContext(
>
> 587 +mg::SurfacelessEGLContext::SurfacelessEGLContext(
> 588 + EGLDisplay egl_display,
> 589 + EGLint const* attribs,
> 590 + EGLContext shared_context)
>
> It would be clearer to implement the SurfaceEGLContext(egl_display, shared_context) constructor in terms of the new SurfaceEGLContext(egl_display, attribs, shared_context) constructor, by passing our default config attribs:
>
> SurfacelessEGLContext(EGLDisplay egl_display, EGLContext shared_context)
> : SurfacelessEGLContext(egl_display, default_attribs, shared_context)
>

Quite true! Fixed.

> 429 +mgo::DisplayBuffer::DisplayBuffer(SurfacelessEGLContext &&egl_context,
> 430 geom::Rectangle const& area)
> 431 - : egl_context{std::move(egl_context)},
> 432 + : egl_context{std::forward<SurfacelessEGLContext>(egl_context)},
>
> It's better to accept a move only type (such as SurfacelessEGLContext or std::unique_ptr<>) by value vs rvalue reference: see https://code.launchpad.net/~rocket-scientists/mir/buffer-swapper-multi/+merge/139127/comments/301713 .

Done.
>
> 613 + move.egl_display = EGL_NO_DISPLAY;
>
> 618 + release_current();
>
> A invalidated (i.e. moved) SurfacelessEGLContext object may try to release the EGL context when being destroyed. Although this will have no effect since egl_display == EGL_NO_DISPLAY, I think it would be better to not try at all to avoid error/debug messages from EGL.

Oh, right. If there's no current context then it'll attempt to release.
Fixed.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Looks good overall, with the exception of some brace placement style issues in the tests.

Abstaining in order not to block this MP.

review: Abstain
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Still too many "minor issues". See my previous comment. This includes some braces still not fixed.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I'm not going to block on a couple of minor issues, but there are still more than a couple. Fix half-ish and I'm happy :)

3. Braces you missed - bzr diff | egrep '^\+.*[^ ]+ {$'
+EGLint const default_attr[] = {
+namespace {
+ if (found_surface_type) {
+ const EGLint attribs_with_pbuffer[] = {
+ const EGLint attribs_without_surface_type[] = {
+ const EGLint attribs_without_pbuffer[] = {
+ const EGLint attribs_without_surface_type[] = {
+ const EGLint attribs_with_surface_type[] = {

2. I would prefer they're not const.

4. Use your imagination. You know more about the context than I do.

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

OK, enough back and forth.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'include/platform/mir/graphics/gl_context.h'
--- include/platform/mir/graphics/gl_context.h 2013-12-17 18:24:51 +0000
+++ include/platform/mir/graphics/gl_context.h 2013-12-19 09:13:25 +0000
@@ -29,8 +29,8 @@
29public:29public:
30 virtual ~GLContext() = default;30 virtual ~GLContext() = default;
3131
32 virtual void make_current() = 0;32 virtual void make_current() const = 0;
33 virtual void release_current() = 0;33 virtual void release_current() const = 0;
3434
35protected:35protected:
36 GLContext() = default;36 GLContext() = default;
3737
=== renamed file 'src/server/graphics/offscreen/gl_extensions_base.h' => 'include/server/mir/graphics/gl_extensions_base.h'
--- src/server/graphics/offscreen/gl_extensions_base.h 2013-11-12 17:23:53 +0000
+++ include/server/mir/graphics/gl_extensions_base.h 2013-12-19 09:13:25 +0000
@@ -16,15 +16,13 @@
16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */17 */
1818
19#ifndef MIR_GRAPHICS_OFFSCREEN_GL_EXTENSIONS_BASE_H_19#ifndef MIR_GRAPHICS_GL_EXTENSIONS_BASE_H_
20#define MIR_GRAPHICS_OFFSCREEN_GL_EXTENSIONS_BASE_H_20#define MIR_GRAPHICS_GL_EXTENSIONS_BASE_H_
2121
22namespace mir22namespace mir
23{23{
24namespace graphics24namespace graphics
25{25{
26namespace offscreen
27{
2826
29class GLExtensionsBase27class GLExtensionsBase
30{28{
@@ -42,6 +40,5 @@
4240
43}41}
44}42}
45}
4643
47#endif /* MIR_GRAPHICS_OFFSCREEN_GL_EXTENSIONS_BASE_H_ */44#endif /* MIR_GRAPHICS_GL_EXTENSIONS_BASE_H_ */
4845
=== renamed file 'src/server/graphics/offscreen/surfaceless_egl_context.h' => 'include/server/mir/graphics/surfaceless_egl_context.h'
--- src/server/graphics/offscreen/surfaceless_egl_context.h 2013-11-12 17:23:53 +0000
+++ include/server/mir/graphics/surfaceless_egl_context.h 2013-12-19 09:13:25 +0000
@@ -16,10 +16,11 @@
16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */17 */
1818
19#ifndef MIR_GRAPHICS_OFFSCREEN_SURFACELESS_EGL_CONTEXT_H_19#ifndef MIR_GRAPHICS_SURFACELESS_EGL_CONTEXT_H_
20#define MIR_GRAPHICS_OFFSCREEN_SURFACELESS_EGL_CONTEXT_H_20#define MIR_GRAPHICS_SURFACELESS_EGL_CONTEXT_H_
2121
22#include "mir/graphics/egl_resources.h"22#include "mir/graphics/egl_resources.h"
23#include "mir/graphics/gl_context.h"
2324
24#include <EGL/egl.h>25#include <EGL/egl.h>
2526
@@ -27,17 +28,18 @@
27{28{
28namespace graphics29namespace graphics
29{30{
30namespace offscreen
31{
3231
33class SurfacelessEGLContext32class SurfacelessEGLContext : public GLContext
34{33{
35public:34public:
36 SurfacelessEGLContext(EGLDisplay egl_display, EGLContext shared_context);35 SurfacelessEGLContext(EGLDisplay egl_display, EGLContext shared_context);
37 SurfacelessEGLContext(SurfacelessEGLContext&&) = default;36 SurfacelessEGLContext(EGLDisplay egl_display, EGLint const* attribs, EGLContext shared_context);
37 /* We have to explicitly define this, as GLContext has a deleted copy constructor */
38 SurfacelessEGLContext(SurfacelessEGLContext&& move);
39 virtual ~SurfacelessEGLContext() noexcept;
3840
39 void make_current() const;41 void make_current() const override;
40 void release_current() const;42 void release_current() const override;
4143
42 operator EGLContext() const;44 operator EGLContext() const;
4345
@@ -54,6 +56,5 @@
5456
55}57}
56}58}
57}
5859
59#endif /* MIR_GRAPHICS_OFFSCREEN_SURFACELESS_EGL_SURFACE_H_ */60#endif /* MIR_GRAPHICS_SURFACELESS_EGL_SURFACE_H_ */
6061
=== modified file 'include/test/mir_test_doubles/null_gl_context.h'
--- include/test/mir_test_doubles/null_gl_context.h 2013-06-12 10:27:50 +0000
+++ include/test/mir_test_doubles/null_gl_context.h 2013-12-19 09:13:25 +0000
@@ -31,8 +31,8 @@
31class NullGLContext : public graphics::GLContext31class NullGLContext : public graphics::GLContext
32{32{
33public:33public:
34 void make_current() {}34 void make_current() const {}
35 void release_current() {}35 void release_current() const {}
36};36};
3737
38}38}
3939
=== modified file 'src/platform/graphics/android/gl_context.cpp'
--- src/platform/graphics/android/gl_context.cpp 2013-12-17 18:24:51 +0000
+++ src/platform/graphics/android/gl_context.cpp 2013-12-19 09:13:25 +0000
@@ -131,7 +131,7 @@
131{131{
132}132}
133133
134void mga::GLContext::make_current()134void mga::GLContext::make_current() const
135{135{
136 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context) == EGL_FALSE)136 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context) == EGL_FALSE)
137 {137 {
@@ -140,7 +140,7 @@
140 }140 }
141}141}
142142
143void mga::GLContext::release_current()143void mga::GLContext::release_current() const
144{144{
145 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);145 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
146}146}
147147
=== modified file 'src/platform/graphics/android/gl_context.h'
--- src/platform/graphics/android/gl_context.h 2013-12-17 18:24:51 +0000
+++ src/platform/graphics/android/gl_context.h 2013-12-19 09:13:25 +0000
@@ -48,9 +48,9 @@
4848
49 ~GLContext();49 ~GLContext();
5050
51 void make_current();51 void make_current() const override;
52 void swap_buffers();52 void swap_buffers();
53 void release_current();53 void release_current() const override;
5454
55 /* TODO: (kdub) remove these two functions once HWC1.0 construction is sorted out. */55 /* TODO: (kdub) remove these two functions once HWC1.0 construction is sorted out. */
56 EGLDisplay display()56 EGLDisplay display()
5757
=== modified file 'src/platform/graphics/mesa/display.cpp'
--- src/platform/graphics/mesa/display.cpp 2013-12-17 18:24:51 +0000
+++ src/platform/graphics/mesa/display.cpp 2013-12-19 09:13:25 +0000
@@ -58,12 +58,12 @@
58 egl.setup(gbm, shared_context);58 egl.setup(gbm, shared_context);
59 }59 }
6060
61 void make_current()61 void make_current() const override
62 {62 {
63 egl.make_current();63 egl.make_current();
64 }64 }
6565
66 void release_current()66 void release_current() const override
67 {67 {
68 egl.release_current();68 egl.release_current();
69 }69 }
7070
=== modified file 'src/platform/graphics/mesa/display_helpers.cpp'
--- src/platform/graphics/mesa/display_helpers.cpp 2013-12-17 18:24:51 +0000
+++ src/platform/graphics/mesa/display_helpers.cpp 2013-12-19 09:13:25 +0000
@@ -357,13 +357,13 @@
357 return (ret == EGL_TRUE);357 return (ret == EGL_TRUE);
358}358}
359359
360bool mgmh::EGLHelper::make_current()360bool mgmh::EGLHelper::make_current() const
361{361{
362 auto ret = eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);362 auto ret = eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);
363 return (ret == EGL_TRUE);363 return (ret == EGL_TRUE);
364}364}
365365
366bool mgmh::EGLHelper::release_current()366bool mgmh::EGLHelper::release_current() const
367{367{
368 auto ret = eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);368 auto ret = eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
369 return (ret == EGL_TRUE);369 return (ret == EGL_TRUE);
370370
=== modified file 'src/platform/graphics/mesa/display_helpers.h'
--- src/platform/graphics/mesa/display_helpers.h 2013-12-17 18:24:51 +0000
+++ src/platform/graphics/mesa/display_helpers.h 2013-12-19 09:13:25 +0000
@@ -108,8 +108,8 @@
108 EGLContext shared_context);108 EGLContext shared_context);
109109
110 bool swap_buffers();110 bool swap_buffers();
111 bool make_current();111 bool make_current() const;
112 bool release_current();112 bool release_current() const;
113113
114 EGLContext context() { return egl_context; }114 EGLContext context() { return egl_context; }
115115
116116
=== modified file 'src/server/graphics/CMakeLists.txt'
--- src/server/graphics/CMakeLists.txt 2013-12-17 18:24:51 +0000
+++ src/server/graphics/CMakeLists.txt 2013-12-19 09:13:25 +0000
@@ -5,6 +5,8 @@
55
6 default_configuration.cpp6 default_configuration.cpp
7 default_display_configuration_policy.cpp7 default_display_configuration_policy.cpp
8 gl_extensions_base.cpp
9 surfaceless_egl_context.cpp
8)10)
911
10add_subdirectory(nested/)12add_subdirectory(nested/)
1113
=== renamed file 'src/server/graphics/offscreen/gl_extensions_base.cpp' => 'src/server/graphics/gl_extensions_base.cpp'
--- src/server/graphics/offscreen/gl_extensions_base.cpp 2013-11-14 09:45:44 +0000
+++ src/server/graphics/gl_extensions_base.cpp 2013-12-19 09:13:25 +0000
@@ -16,16 +16,16 @@
16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */17 */
1818
19#include "gl_extensions_base.h"19#include "mir/graphics/gl_extensions_base.h"
2020
21#include <boost/throw_exception.hpp>21#include <boost/throw_exception.hpp>
22#include <stdexcept>22#include <stdexcept>
2323
24#include <cstring>24#include <cstring>
2525
26namespace mgo = mir::graphics::offscreen;26namespace mg = mir::graphics;
2727
28mgo::GLExtensionsBase::GLExtensionsBase(char const* extensions)28mg::GLExtensionsBase::GLExtensionsBase(char const* extensions)
29 : extensions{extensions}29 : extensions{extensions}
30{30{
31 if (!extensions)31 if (!extensions)
@@ -35,7 +35,7 @@
35 }35 }
36}36}
3737
38bool mgo::GLExtensionsBase::support(char const* ext) const38bool mg::GLExtensionsBase::support(char const* ext) const
39{39{
40 char const* ext_ptr = extensions;40 char const* ext_ptr = extensions;
41 size_t const len = strlen(ext);41 size_t const len = strlen(ext);
4242
=== modified file 'src/server/graphics/nested/nested_display.cpp'
--- src/server/graphics/nested/nested_display.cpp 2013-12-17 18:24:51 +0000
+++ src/server/graphics/nested/nested_display.cpp 2013-12-19 09:13:25 +0000
@@ -23,6 +23,7 @@
2323
24#include "mir/geometry/rectangle.h"24#include "mir/geometry/rectangle.h"
25#include "mir/graphics/gl_context.h"25#include "mir/graphics/gl_context.h"
26#include "mir/graphics/surfaceless_egl_context.h"
26#include "host_connection.h"27#include "host_connection.h"
2728
28#include <boost/throw_exception.hpp>29#include <boost/throw_exception.hpp>
@@ -275,53 +276,11 @@
275276
276namespace277namespace
277{278{
278EGLint const dummy_pbuffer_attribs[] =
279{
280 EGL_WIDTH, 1,
281 EGL_HEIGHT, 1,
282 EGL_NONE
283};
284}279}
285280
286std::unique_ptr<mg::GLContext> mgn::NestedDisplay::create_gl_context()281std::unique_ptr<mg::GLContext> mgn::NestedDisplay::create_gl_context()
287{282{
288 class NestedGLContext : public mg::GLContext283 return std::unique_ptr<mg::GLContext>{new SurfacelessEGLContext(egl_display,
289 {284 detail::nested_egl_config_attribs,
290 public:285 EGL_NO_CONTEXT)};
291 NestedGLContext(detail::EGLDisplayHandle const& egl_display) :
292 egl_display{egl_display},
293 egl_config{egl_display.choose_config(detail::nested_egl_config_attribs)},
294 egl_context{egl_display, eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, detail::nested_egl_context_attribs)},
295 egl_surface{egl_display, eglCreatePbufferSurface(egl_display, egl_config, dummy_pbuffer_attribs)}
296 {
297 }
298
299 ~NestedGLContext() noexcept
300 {
301 if (eglGetCurrentContext() == egl_context)
302 release_current();
303 }
304
305 void make_current() override
306 {
307 if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context) == EGL_FALSE)
308 {
309 BOOST_THROW_EXCEPTION(
310 std::runtime_error("could not activate dummy surface with eglMakeCurrent\n"));
311 }
312 }
313
314 void release_current() override
315 {
316 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
317 }
318
319 private:
320 EGLDisplay const egl_display;
321 EGLConfig const egl_config;
322 EGLContextStore const egl_context;
323 EGLSurfaceStore const egl_surface;
324 };
325
326 return std::unique_ptr<mg::GLContext>{new NestedGLContext(egl_display)};
327}286}
328287
=== modified file 'src/server/graphics/offscreen/CMakeLists.txt'
--- src/server/graphics/offscreen/CMakeLists.txt 2013-11-12 17:23:53 +0000
+++ src/server/graphics/offscreen/CMakeLists.txt 2013-12-19 09:13:25 +0000
@@ -4,8 +4,6 @@
4 display.cpp4 display.cpp
5 display_configuration.cpp5 display_configuration.cpp
6 display_buffer.cpp6 display_buffer.cpp
7 surfaceless_egl_context.cpp
8 gl_extensions_base.cpp
9)7)
108
11target_link_libraries(9target_link_libraries(
1210
=== modified file 'src/server/graphics/offscreen/display.cpp'
--- src/server/graphics/offscreen/display.cpp 2013-11-18 12:35:14 +0000
+++ src/server/graphics/offscreen/display.cpp 2013-12-19 09:13:25 +0000
@@ -20,7 +20,6 @@
20#include "display_buffer.h"20#include "display_buffer.h"
21#include "mir/graphics/basic_platform.h"21#include "mir/graphics/basic_platform.h"
22#include "mir/graphics/display_configuration_policy.h"22#include "mir/graphics/display_configuration_policy.h"
23#include "mir/graphics/gl_context.h"
24#include "mir/geometry/size.h"23#include "mir/geometry/size.h"
2524
26#include <boost/throw_exception.hpp>25#include <boost/throw_exception.hpp>
@@ -33,33 +32,6 @@
33namespace32namespace
34{33{
3534
36class OffscreenGLContext : public mg::GLContext
37{
38public:
39 OffscreenGLContext(mgo::SurfacelessEGLContext surfaceless_egl_context)
40 : surfaceless_egl_context{std::move(surfaceless_egl_context)}
41 {
42 }
43
44 ~OffscreenGLContext() noexcept
45 {
46 release_current();
47 }
48
49 void make_current()
50 {
51 surfaceless_egl_context.make_current();
52 }
53
54 void release_current()
55 {
56 surfaceless_egl_context.release_current();
57 }
58
59private:
60 mgo::SurfacelessEGLContext const surfaceless_egl_context;
61};
62
63mgo::detail::EGLDisplayHandle35mgo::detail::EGLDisplayHandle
64create_and_initialize_display(mg::BasicPlatform& basic_platform)36create_and_initialize_display(mg::BasicPlatform& basic_platform)
65{37{
@@ -193,5 +165,5 @@
193std::unique_ptr<mg::GLContext> mgo::Display::create_gl_context()165std::unique_ptr<mg::GLContext> mgo::Display::create_gl_context()
194{166{
195 return std::unique_ptr<GLContext>{167 return std::unique_ptr<GLContext>{
196 new OffscreenGLContext{SurfacelessEGLContext{egl_display, egl_context_shared}}};168 new SurfacelessEGLContext{egl_display, egl_context_shared}};
197}169}
198170
=== modified file 'src/server/graphics/offscreen/display.h'
--- src/server/graphics/offscreen/display.h 2013-11-18 17:08:15 +0000
+++ src/server/graphics/offscreen/display.h 2013-12-19 09:13:25 +0000
@@ -21,7 +21,7 @@
2121
22#include "mir/graphics/display.h"22#include "mir/graphics/display.h"
23#include "display_configuration.h"23#include "display_configuration.h"
24#include "surfaceless_egl_context.h"24#include "mir/graphics/surfaceless_egl_context.h"
2525
26#include <mutex>26#include <mutex>
27#include <vector>27#include <vector>
2828
=== modified file 'src/server/graphics/offscreen/display_buffer.cpp'
--- src/server/graphics/offscreen/display_buffer.cpp 2013-12-17 18:24:51 +0000
+++ src/server/graphics/offscreen/display_buffer.cpp 2013-12-19 09:13:25 +0000
@@ -17,7 +17,7 @@
17 */17 */
1818
19#include "display_buffer.h"19#include "display_buffer.h"
20#include "gl_extensions_base.h"20#include "mir/graphics/gl_extensions_base.h"
21#include "mir/raii.h"21#include "mir/raii.h"
2222
23#include <boost/throw_exception.hpp>23#include <boost/throw_exception.hpp>
@@ -33,11 +33,11 @@
33namespace33namespace
34{34{
3535
36class GLExtensions : public mgo::GLExtensionsBase36class GLExtensions : public mg::GLExtensionsBase
37{37{
38public:38public:
39 GLExtensions() :39 GLExtensions() :
40 mgo::GLExtensionsBase{40 mg::GLExtensionsBase{
41 reinterpret_cast<char const*>(glGetString(GL_EXTENSIONS))}41 reinterpret_cast<char const*>(glGetString(GL_EXTENSIONS))}
42 {42 {
43 }43 }
4444
=== modified file 'src/server/graphics/offscreen/display_buffer.h'
--- src/server/graphics/offscreen/display_buffer.h 2013-11-14 09:46:02 +0000
+++ src/server/graphics/offscreen/display_buffer.h 2013-12-19 09:13:25 +0000
@@ -19,7 +19,7 @@
19#ifndef MIR_GRAPHICS_OFFSCREEN_DISPLAY_BUFFER_H_19#ifndef MIR_GRAPHICS_OFFSCREEN_DISPLAY_BUFFER_H_
20#define MIR_GRAPHICS_OFFSCREEN_DISPLAY_BUFFER_H_20#define MIR_GRAPHICS_OFFSCREEN_DISPLAY_BUFFER_H_
2121
22#include "surfaceless_egl_context.h"22#include "mir/graphics/surfaceless_egl_context.h"
2323
24#include "mir/graphics/display_buffer.h"24#include "mir/graphics/display_buffer.h"
25#include "mir/geometry/size.h"25#include "mir/geometry/size.h"
2626
=== renamed file 'src/server/graphics/offscreen/surfaceless_egl_context.cpp' => 'src/server/graphics/surfaceless_egl_context.cpp'
--- src/server/graphics/offscreen/surfaceless_egl_context.cpp 2013-11-18 12:58:38 +0000
+++ src/server/graphics/surfaceless_egl_context.cpp 2013-12-19 09:13:25 +0000
@@ -16,22 +16,23 @@
16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */17 */
1818
19#include "surfaceless_egl_context.h"19#include "mir/graphics/surfaceless_egl_context.h"
20#include "gl_extensions_base.h"20#include "mir/graphics/gl_extensions_base.h"
2121
22#include <boost/throw_exception.hpp>22#include <boost/throw_exception.hpp>
23#include <stdexcept>23#include <stdexcept>
24#include <vector>
2425
25namespace mgo = mir::graphics::offscreen;26namespace mg = mir::graphics;
2627
27namespace28namespace
28{29{
2930
30class EGLExtensions : public mgo::GLExtensionsBase31class EGLExtensions : public mg::GLExtensionsBase
31{32{
32public:33public:
33 EGLExtensions(EGLDisplay egl_display) :34 EGLExtensions(EGLDisplay egl_display) :
34 mgo::GLExtensionsBase{35 mg::GLExtensionsBase{
35 reinterpret_cast<char const*>(eglQueryString(egl_display, EGL_EXTENSIONS))}36 reinterpret_cast<char const*>(eglQueryString(egl_display, EGL_EXTENSIONS))}
36 {37 {
37 }38 }
@@ -44,27 +45,62 @@
44 return extensions.support("EGL_KHR_surfaceless_context");45 return extensions.support("EGL_KHR_surfaceless_context");
45}46}
4647
47EGLConfig choose_config(EGLDisplay egl_display, bool surfaceless)48std::vector<EGLint> ensure_pbuffer_set(EGLint const* attribs)
48{49{
49 EGLint const surface_type = surfaceless ? EGL_DONT_CARE : EGL_PBUFFER_BIT;50 bool has_preferred_surface = false;
5051 std::vector<EGLint> attribs_with_surface_type;
51 EGLint const config_attr[] = {52 int i = 0;
52 EGL_SURFACE_TYPE, surface_type,53
53 EGL_RED_SIZE, 8,54 while (attribs[i] != EGL_NONE)
54 EGL_GREEN_SIZE, 8,55 {
55 EGL_BLUE_SIZE, 8,56 attribs_with_surface_type.push_back(attribs[i]);
56 EGL_ALPHA_SIZE, 0,57 if (attribs[i] == EGL_SURFACE_TYPE)
57 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,58 {
58 EGL_NONE59 has_preferred_surface = true;
59 };60 if (attribs[i+1] == EGL_DONT_CARE)
6061 {
62 /* Need to treat EGL_DONT_CARE specially, as it is defined as all-bits-set */
63 attribs_with_surface_type.push_back(EGL_PBUFFER_BIT);
64 }
65 else
66 {
67 attribs_with_surface_type.push_back(attribs[i+1] | EGL_PBUFFER_BIT);
68 }
69 }
70 else
71 {
72 attribs_with_surface_type.push_back(attribs[i+1]);
73 }
74 i += 2;
75 }
76
77 if (!has_preferred_surface)
78 {
79 attribs_with_surface_type.push_back(EGL_SURFACE_TYPE);
80 attribs_with_surface_type.push_back(EGL_PBUFFER_BIT);
81 }
82
83 attribs_with_surface_type.push_back(EGL_NONE);
84
85 return attribs_with_surface_type;
86}
87
88EGLConfig choose_config(EGLDisplay egl_display, EGLint const* attribs, bool surfaceless)
89{
61 EGLConfig egl_config{0};90 EGLConfig egl_config{0};
62 int num_egl_configs{0};91 int num_egl_configs{0};
6392 std::vector<EGLint> validated_attribs;
64 if (eglChooseConfig(egl_display, config_attr, &egl_config, 1, &num_egl_configs) == EGL_FALSE ||93
94 if (!surfaceless)
95 {
96 validated_attribs = ensure_pbuffer_set(attribs);
97 attribs = validated_attribs.data();
98 }
99
100 if (eglChooseConfig(egl_display, attribs, &egl_config, 1, &num_egl_configs) == EGL_FALSE ||
65 num_egl_configs != 1)101 num_egl_configs != 1)
66 {102 {
67 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to choose ARGB EGL config"));103 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to choose EGL config"));
68 }104 }
69105
70 return egl_config;106 return egl_config;
@@ -88,14 +124,32 @@
88 EGL_NONE124 EGL_NONE
89};125};
90126
91}127EGLint const default_attr[] =
92128{
93mgo::SurfacelessEGLContext::SurfacelessEGLContext(129 EGL_SURFACE_TYPE, EGL_DONT_CARE,
94 EGLDisplay egl_display,130 EGL_RED_SIZE, 8,
95 EGLContext shared_context)131 EGL_GREEN_SIZE, 8,
132 EGL_BLUE_SIZE, 8,
133 EGL_ALPHA_SIZE, 0,
134 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
135 EGL_NONE
136};
137
138
139}
140
141mg::SurfacelessEGLContext::SurfacelessEGLContext(EGLDisplay egl_display, EGLContext shared_context)
142 : SurfacelessEGLContext(egl_display, default_attr, shared_context)
143{
144}
145
146mg::SurfacelessEGLContext::SurfacelessEGLContext(
147 EGLDisplay egl_display,
148 EGLint const* attribs,
149 EGLContext shared_context)
96 : egl_display{egl_display},150 : egl_display{egl_display},
97 surfaceless{supports_surfaceless_context(egl_display)},151 surfaceless{supports_surfaceless_context(egl_display)},
98 egl_config{choose_config(egl_display, surfaceless)},152 egl_config{choose_config(egl_display, attribs, surfaceless)},
99 egl_surface{egl_display,153 egl_surface{egl_display,
100 surfaceless ? EGL_NO_SURFACE : create_surface(egl_display, egl_config),154 surfaceless ? EGL_NO_SURFACE : create_surface(egl_display, egl_config),
101 surfaceless ? EGLSurfaceStore::AllowNoSurface :155 surfaceless ? EGLSurfaceStore::AllowNoSurface :
@@ -107,7 +161,24 @@
107{161{
108}162}
109163
110void mgo::SurfacelessEGLContext::make_current() const164
165mg::SurfacelessEGLContext::SurfacelessEGLContext(SurfacelessEGLContext&& move)
166 : egl_display(move.egl_display),
167 surfaceless(move.surfaceless),
168 egl_config(move.egl_config),
169 egl_surface{std::move(move.egl_surface)},
170 egl_context{std::move(move.egl_context)}
171{
172 move.egl_display = EGL_NO_DISPLAY;
173}
174
175mg::SurfacelessEGLContext::~SurfacelessEGLContext() noexcept
176{
177 release_current();
178}
179
180
181void mg::SurfacelessEGLContext::make_current() const
111{182{
112 if (eglGetCurrentContext() == egl_context)183 if (eglGetCurrentContext() == egl_context)
113 return;184 return;
@@ -120,13 +191,13 @@
120 }191 }
121}192}
122193
123void mgo::SurfacelessEGLContext::release_current() const194void mg::SurfacelessEGLContext::release_current() const
124{195{
125 if (eglGetCurrentContext() == egl_context)196 if (egl_context != EGL_NO_CONTEXT && eglGetCurrentContext() == egl_context)
126 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);197 eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
127}198}
128199
129mgo::SurfacelessEGLContext::operator EGLContext() const200mg::SurfacelessEGLContext::operator EGLContext() const
130{201{
131 return egl_context;202 return egl_context;
132}203}
133204
=== modified file 'tests/unit-tests/graphics/CMakeLists.txt'
--- tests/unit-tests/graphics/CMakeLists.txt 2013-12-17 18:24:51 +0000
+++ tests/unit-tests/graphics/CMakeLists.txt 2013-12-19 09:13:25 +0000
@@ -6,6 +6,7 @@
6 ${CMAKE_CURRENT_SOURCE_DIR}/test_default_display_configuration_policy.cpp6 ${CMAKE_CURRENT_SOURCE_DIR}/test_default_display_configuration_policy.cpp
7 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_id.cpp7 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_id.cpp
8 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_properties.cpp8 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_properties.cpp
9 ${CMAKE_CURRENT_SOURCE_DIR}/test_surfaceless_egl_context.cpp
9)10)
1011
11add_subdirectory(nested/)12add_subdirectory(nested/)
1213
=== added file 'tests/unit-tests/graphics/test_surfaceless_egl_context.cpp'
--- tests/unit-tests/graphics/test_surfaceless_egl_context.cpp 1970-01-01 00:00:00 +0000
+++ tests/unit-tests/graphics/test_surfaceless_egl_context.cpp 2013-12-19 09:13:25 +0000
@@ -0,0 +1,254 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by:
17 * Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
18 */
19
20#include "mir/graphics/surfaceless_egl_context.h"
21#include "mir_test_doubles/mock_egl.h"
22#include <stdexcept>
23#include <list>
24
25#include <gtest/gtest.h>
26#include <gmock/gmock.h>
27
28namespace mg = mir::graphics;
29namespace mtd = mir::test::doubles;
30
31class SurfacelessEGLContextTest : public ::testing::Test
32{
33public:
34 EGLDisplay const fake_display{reinterpret_cast<EGLDisplay>(0xfffaaafa)};
35 EGLSurface const fake_surface{reinterpret_cast<EGLSurface>(0xdeadbeef)};
36 EGLContext const fake_context{reinterpret_cast<EGLContext>(0xfaafbaaf)};
37
38protected:
39 virtual void SetUp()
40 {
41 using namespace testing;
42
43 ON_CALL(mock_egl, eglCreatePbufferSurface(_,_,_))
44 .WillByDefault(Return(fake_surface));
45 ON_CALL(mock_egl, eglCreateContext(_,_,_,_))
46 .WillByDefault(Return(fake_context));
47 ON_CALL(mock_egl, eglGetCurrentContext())
48 .WillByDefault(Return(EGL_NO_CONTEXT));
49 }
50
51 testing::NiceMock<mtd::MockEGL> mock_egl;
52};
53
54namespace
55{
56
57MATCHER(ConfigAttribContainsPBufferFlag, "")
58{
59 EGLint surface_type = 0;
60 bool found_surface_type = false;
61 std::list<std::string> pretty_surface;
62
63 for (int i = 0; arg[i] != EGL_NONE; ++i)
64 {
65 if (arg[i] == EGL_SURFACE_TYPE)
66 {
67 surface_type = arg[i+1];
68 found_surface_type = true;
69 }
70 }
71
72 if (found_surface_type)
73 {
74 if (surface_type == EGL_DONT_CARE)
75 {
76 pretty_surface.push_back("EGL_DONT_CARE");
77 }
78 else
79 {
80 if (surface_type & EGL_MULTISAMPLE_RESOLVE_BOX_BIT)
81 {
82 pretty_surface.push_back("EGL_MULTISAMPLE_RESOLVE_BOX_BIT");
83 }
84 if (surface_type & EGL_PBUFFER_BIT)
85 {
86 pretty_surface.push_back("EGL_PBUFFER_BIT");
87 }
88 if (surface_type & EGL_PIXMAP_BIT)
89 {
90 pretty_surface.push_back("EGL_PIXMAP_BIT");
91 }
92 if (surface_type & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)
93 {
94 pretty_surface.push_back("EGL_SWAP_BEHAVIOR_PRESERVED_BIT");
95 }
96 if (surface_type & EGL_VG_ALPHA_FORMAT_PRE_BIT)
97 {
98 pretty_surface.push_back("EGL_VG_ALPHA_FORMAT_PRE_BIT");
99 }
100 if (surface_type & EGL_VG_COLORSPACE_LINEAR_BIT)
101 {
102 pretty_surface.push_back("EGL_VG_COLORSPACE_LINEAR_BIT");
103 }
104 if (surface_type & EGL_WINDOW_BIT)
105 {
106 pretty_surface.push_back("EGL_WINDOW_BIT");
107 }
108 }
109 std::string pretty_result = pretty_surface.back();
110 pretty_surface.pop_back();
111 for (auto& pretty : pretty_surface)
112 {
113 pretty_result += " | " + pretty;
114 }
115 *result_listener << "surface type is "<< pretty_result;
116 }
117 else
118 {
119 *result_listener << "no surface type set";
120 }
121
122 return found_surface_type &&
123 (surface_type != EGL_DONT_CARE) &&
124 (surface_type & EGL_PBUFFER_BIT);
125}
126
127}
128
129TEST_F(SurfacelessEGLContextTest, UsesPBufferContainingAttribsListByDefault)
130{
131 using namespace testing;
132
133 ON_CALL(mock_egl, eglQueryString(_,_))
134 .WillByDefault(Return(""));
135
136 EXPECT_CALL(mock_egl, eglChooseConfig(_, ConfigAttribContainsPBufferFlag(), _,_,_))
137 .WillOnce(DoAll(SetArgPointee<4>(1), Return(EGL_TRUE)));
138
139 mg::SurfacelessEGLContext ctx_noattrib(fake_display, EGL_NO_CONTEXT);
140}
141
142TEST_F(SurfacelessEGLContextTest, KeepsPBufferInAttribsList)
143{
144 using namespace testing;
145
146 const EGLint attribs_with_pbuffer[] =
147 {
148 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
149 EGL_NONE
150 };
151
152 ON_CALL(mock_egl, eglQueryString(_,_))
153 .WillByDefault(Return(""));
154
155 EXPECT_CALL(mock_egl, eglChooseConfig(_, ConfigAttribContainsPBufferFlag(), _,_,_))
156 .WillOnce(DoAll(SetArgPointee<4>(1), Return(EGL_TRUE)));
157
158 mg::SurfacelessEGLContext ctx_attribs_with_pbuffer(fake_display, attribs_with_pbuffer, EGL_NO_CONTEXT);
159}
160
161TEST_F(SurfacelessEGLContextTest, AddsPBufferToAttribList)
162{
163 using namespace testing;
164
165 const EGLint attribs_without_surface_type[] =
166 {
167 EGL_ALPHA_SIZE, 8,
168 EGL_CLIENT_APIS, EGL_OPENGL_ES2_BIT,
169 EGL_NONE
170 };
171
172 ON_CALL(mock_egl, eglQueryString(_,_))
173 .WillByDefault(Return(""));
174
175 EXPECT_CALL(mock_egl, eglChooseConfig(_, ConfigAttribContainsPBufferFlag(), _,_,_))
176 .WillOnce(DoAll(SetArgPointee<4>(1), Return(EGL_TRUE)));
177
178 mg::SurfacelessEGLContext ctx_attribs_without_surface_type(fake_display, attribs_without_surface_type, EGL_NO_CONTEXT);
179}
180
181TEST_F(SurfacelessEGLContextTest, AddsPBufferWhenNonPBufferSurfaceTypeRequested)
182{
183 using namespace testing;
184
185 const EGLint attribs_without_pbuffer[] =
186 {
187 EGL_SURFACE_TYPE, EGL_DONT_CARE,
188 EGL_ALPHA_SIZE, 8,
189 EGL_CLIENT_APIS, EGL_OPENGL_ES2_BIT,
190 EGL_NONE
191 };
192
193 ON_CALL(mock_egl, eglQueryString(_,_))
194 .WillByDefault(Return(""));
195
196 EXPECT_CALL(mock_egl, eglChooseConfig(_, ConfigAttribContainsPBufferFlag(), _,_,_))
197 .WillOnce(DoAll(SetArgPointee<4>(1), Return(EGL_TRUE)));
198
199 mg::SurfacelessEGLContext ctx_attribs_without_pbuffer(fake_display, attribs_without_pbuffer, EGL_NO_CONTEXT);
200}
201
202TEST_F(SurfacelessEGLContextTest, DoesNotRequestPBufferWithNoAttrib)
203{
204 using namespace testing;
205
206 ON_CALL(mock_egl, eglQueryString(_,_))
207 .WillByDefault(Return("EGL_KHR_surfaceless_context"));
208
209 EXPECT_CALL(mock_egl, eglChooseConfig(_, Not(ConfigAttribContainsPBufferFlag()), _,_,_))
210 .WillOnce(DoAll(SetArgPointee<4>(1), Return(EGL_TRUE)));
211
212 mg::SurfacelessEGLContext ctx_noattrib(fake_display, EGL_NO_CONTEXT);
213}
214
215TEST_F(SurfacelessEGLContextTest, DoesNotAddPBufferToAttribList)
216{
217 using namespace testing;
218
219 const EGLint attribs_without_surface_type[] =
220 {
221 EGL_ALPHA_SIZE, 8,
222 EGL_CLIENT_APIS, EGL_OPENGL_ES2_BIT,
223 EGL_NONE
224 };
225
226 ON_CALL(mock_egl, eglQueryString(_,_))
227 .WillByDefault(Return("EGL_KHR_surfaceless_context"));
228
229 EXPECT_CALL(mock_egl, eglChooseConfig(_, Not(ConfigAttribContainsPBufferFlag()), _,_,_))
230 .WillOnce(DoAll(SetArgPointee<4>(1), Return(EGL_TRUE)));
231
232 mg::SurfacelessEGLContext ctx_attribs_without_surface_type(fake_display, attribs_without_surface_type, EGL_NO_CONTEXT);
233}
234
235TEST_F(SurfacelessEGLContextTest, DoesNotAddPBufferToSurfaceTypeRequest)
236{
237 using namespace testing;
238
239 const EGLint attribs_with_surface_type[] =
240 {
241 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
242 EGL_ALPHA_SIZE, 8,
243 EGL_CLIENT_APIS, EGL_OPENGL_ES2_BIT,
244 EGL_NONE
245 };
246
247 ON_CALL(mock_egl, eglQueryString(_,_))
248 .WillByDefault(Return("EGL_KHR_surfaceless_context"));
249
250 EXPECT_CALL(mock_egl, eglChooseConfig(_, Not(ConfigAttribContainsPBufferFlag()), _,_,_))
251 .WillOnce(DoAll(SetArgPointee<4>(1), Return(EGL_TRUE)));
252
253 mg::SurfacelessEGLContext ctx_attribs_with_surface_type(fake_display, attribs_with_surface_type, EGL_NO_CONTEXT);
254}
0255
=== modified file 'tests/unit-tests/scene/test_gl_pixel_buffer.cpp'
--- tests/unit-tests/scene/test_gl_pixel_buffer.cpp 2013-12-17 18:24:51 +0000
+++ tests/unit-tests/scene/test_gl_pixel_buffer.cpp 2013-12-19 09:13:25 +0000
@@ -38,8 +38,8 @@
38struct MockGLContext : public mg::GLContext38struct MockGLContext : public mg::GLContext
39{39{
40 ~MockGLContext() noexcept {}40 ~MockGLContext() noexcept {}
41 MOCK_METHOD0(make_current, void());41 MOCK_CONST_METHOD0(make_current, void());
42 MOCK_METHOD0(release_current, void());42 MOCK_CONST_METHOD0(release_current, void());
43};43};
4444
45struct WrappingGLContext : public mg::GLContext45struct WrappingGLContext : public mg::GLContext
@@ -49,8 +49,8 @@
49 {49 {
50 }50 }
51 ~WrappingGLContext() noexcept {}51 ~WrappingGLContext() noexcept {}
52 void make_current() { wrapped.make_current(); }52 void make_current() const { wrapped.make_current(); }
53 void release_current() { wrapped.release_current(); }53 void release_current() const { wrapped.release_current(); }
5454
55 mg::GLContext& wrapped;55 mg::GLContext& wrapped;
56};56};

Subscribers

People subscribed via source and target branches