Merge lp:~kdub/mir/overlay-gl-program into lp:mir
- overlay-gl-program
- Merge into development-branch
Status: | Merged |
---|---|
Approved by: | Alan Griffiths |
Approved revision: | no longer in the source branch. |
Merged at revision: | 1660 |
Proposed branch: | lp:~kdub/mir/overlay-gl-program |
Merge into: | lp:mir |
Diff against target: |
998 lines (+479/-51) 29 files modified
include/platform/mir/graphics/gl_program.h (+17/-8) include/platform/mir/graphics/gl_program_factory.h (+2/-1) include/shared/mir/geometry/point.h (+3/-0) include/shared/mir/geometry/rectangle.h (+2/-0) include/test/mir_test_doubles/mock_display_device.h (+1/-1) include/test/mir_test_doubles/mock_renderable_list_compositor.h (+1/-1) include/test/mir_test_doubles/stub_gl_program.h (+42/-0) include/test/mir_test_doubles/stub_gl_program_factory.h (+6/-0) include/test/mir_test_doubles/stub_renderable.h (+10/-2) include/test/mir_test_doubles/stub_renderable_list_compositor.h (+1/-1) src/platform/graphics/android/CMakeLists.txt (+1/-1) src/platform/graphics/android/display_buffer.cpp (+1/-1) src/platform/graphics/android/display_buffer.h (+2/-2) src/platform/graphics/android/fb_device.cpp (+1/-1) src/platform/graphics/android/hwc_device.cpp (+1/-1) src/platform/graphics/android/hwc_fallback_gl_renderer.cpp (+86/-9) src/platform/graphics/android/hwc_fallback_gl_renderer.h (+15/-7) src/platform/graphics/android/hwc_fb_device.cpp (+1/-1) src/platform/graphics/gl_program.cpp (+3/-3) src/server/compositor/gl_renderer.cpp (+1/-1) src/server/graphics/program_factory.cpp (+9/-1) src/server/graphics/program_factory.h (+2/-0) src/shared/geometry/rectangle.cpp (+10/-0) tests/unit-tests/graphics/android/CMakeLists.txt (+1/-1) tests/unit-tests/graphics/android/test_fb_device.cpp (+1/-1) tests/unit-tests/graphics/android/test_hwc_display.cpp (+2/-0) tests/unit-tests/graphics/android/test_hwc_fallback_gl_renderer.cpp (+254/-6) tests/unit-tests/graphics/android/test_hwc_fb_device.cpp (+1/-1) tests/unit-tests/graphics/android/test_output_builder.cpp (+2/-0) |
To merge this branch: | bzr merge lp:~kdub/mir/overlay-gl-program |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Alan Griffiths | Approve | ||
Cemil Azizoglu (community) | Approve | ||
Alberto Aguirre (community) | Approve | ||
Mir development team | Pending | ||
Review via email: mp+220690@code.launchpad.net |
This proposal supersedes a proposal from 2014-04-24.
Commit message
android: add simple shader program that the android display system will use when the driver rejects the overlays. At the time being, it is just a simple blitter, as we start to support other HWC capabilites like alpha or 90 degree rotation, it will grow, but just a line or two.
Description of the change
android: add simple shader program that the android display system will use when the driver rejects the overlays. At the time being, it is just a simple blitter, as we start to support other HWC capabilites like alpha or 90 degree rotation, it will grow, but just a line or two.
note:
* The HWC is not being used by the platform-
* I mention this somewhat a lot, but one more time won't hurt. We arrange a list of buffers and submit them to hwc's prepare() function. HWC can choose to accept or reject each buffer as a buffer that it can get to the screen in an optimized way. If the buffer is rejected, we're obliged to use OpenGL to render those buffers to a fb target that is also known to hwc. Although it might seem like we could use something other than OpenGL to draw (perhaps), hwc and OpenGL are pretty intrinsically tied together, doing so would cause driver problems.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:1583
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
(1) I think there's a little too much redundancy (and regression) between the existing GLRenderer and OverlayGLProgram. It would be better if we made use of the existing GLRenderer so we didn't have to fix the GL rendering logic twice every time we change it. Plus it makes sense that if overlay fails, then "use the GLRenderer you already know that works".
One thing this proposal regresses on is resize support:
295 +GLfloat const texcoords[]{
296 + 0.0f, 0.0f,
297 + 0.0f, 1.0f,
298 + 1.0f, 0.0f,
299 + 1.0f, 1.0f
300 +};
Fixed texcoords means you're regressing on bug 1259887.
(2) This is misleading:
+void mga::OverlayGLP
"program" has a very specific meaning in OpenGL but you are giving a "GLProgram" class fixed-function GL calls. That makes no sense. But also, see (1)
I suggest these changes would be better deferred until there's a real use case for them, because they only create serious maintenance concerns AFAICS right now. And with some more thought, we should fall back to the GLRenderer (or whatever the default renderer is), instead of writing yet another GL renderer.
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
In fact, bypass does this already. If bypass fails at any stage it falls back to the GLRenderer. Overlays should do that too.
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
There's a lack of role clarity about our various GL classes but I don't mind a little duplication now if it gets factored out later.
OTOH Daniel makes a good point about GL "program".
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
What is being rendered is "overlay rejects" and once rejected by the hwc, there is nothing "overlay" about them. These renderables should no longer be considered overlays, and the code to render them should not be called a name with the word "overlay" in it (unless it's overlay_rejects or smth that makes it clear that they are not overlays) for the sake of clarity. I see that there is code that already made it in, like render_
For these rejects, I think it'd be nice to find a way to fall back to the usual path (I know you had some concerns about it, though). This may be a good time to factor things out of GLRenderer to make it reuseable. But I don't have an issue with a little bit of duplication if we want to wait for "role clarity", as Alan put it.
Gerry Boland (gerboland) wrote : Posted in a previous version of this proposal | # |
> What is being rendered is "overlay rejects" and once rejected by the hwc,
> there is nothing "overlay" about them. These renderables should no longer be
> considered overlays, and the code to render them should not be called a name
> with the word "overlay" in it (unless it's overlay_rejects or smth that makes
> it clear that they are not overlays) for the sake of clarity. I see that there
> is code that already made it in, like render_
> confusing and should be cleaned up in time.
We chose this "list of surfaces to overlay" approach to avoid 2-way communication between the GL renderer (may not be Mir's GLRenderer remember) and the HWC code. This is especially important for case of nested server where a return message of "these surfaces were rejected by the hwc, so do it yourself" would be costly. From the shell point of view, the fire and forget approach is easier.
I also prefer having the simple OverlayGLProgram as the GL fallback, instead of the more resource heavy GLRenderer.
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
> What is being rendered is "overlay rejects" and once rejected by the hwc,
> there is nothing "overlay" about them. These renderables should no longer be
> considered overlays, and the code to render them should not be called a name
> with the word "overlay" in it (unless it's overlay_rejects or smth that makes
> it clear that they are not overlays) for the sake of clarity. I see that there
> is code that already made it in, like render_
> confusing and should be cleaned up in time.
'and once rejected by the hwc, there is nothing "overlay" about them"
From the DefaultDisplayB
There is a subtle, yet distinct difference between a mg::Renderable and an android overlay.
A list of mg::Renderable can do things that a list of hwc_display_
The android code has a fixed function that it is expected to perform as a matter of HWC api.
RenderableList is the list that we can expand to do what we want our most advanced GL compositors to do. Some more concrete examples are that the HWC api expects an orthogonal projection, the RenderableList can use any perspective it wants. The RenderableList could potentially model things like a blur effect (or something) that the hwc would have no idea about. The RenderableList can set arbitrary transforms with arbitrarily tessellated surfaces, android can only support a 90degree rotation., etc.
The android code will take the more universal list and reject that list to the DisplayBufferCo
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
As for the "reuse or not to reuse" I considered this, and decided in favor of adding a very simple program like this.
1) Tying parts of the GLRenderer to the android-specific fallback renderer makes the GLRenderer parts not as malleable; they have to support the hard requirements that the Android fallback needs. I fear that a future bug-fixer or feature-implementer might not realize that changing GLRenderer stuff might break the hard requirements that this GL program has.
2) We might want to do something in the android shader that we doesn't have a concept in GLRenderer, like 'desaturate GPU-renderered regions for debugging purposes"
3) The duplication is really just the most primitive things a shader program can do; we either have 1 shader to rule them all or we have 'duplication' of lines like "gl_FragColor = texture2D(tex, v_texcoord);\n". I'd rather hedge on having different programs fulfilling the role we need them to fulfill as opposed to trying to have one program that we fit in different roles.
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
> (1) I think there's a little too much redundancy (and regression) between the
> existing GLRenderer and OverlayGLProgram. It would be better if we made use of
> the existing GLRenderer so we didn't have to fix the GL rendering logic twice
> every time we change it. Plus it makes sense that if overlay fails, then "use
> the GLRenderer you already know that works".
My concern is that I don't have to fix the Android program any time that renderable expands in a way that causes problems for the requirements that this code needs to support as a matter of the HWC api. I want to let the 'universal, platform-
> One thing this proposal regresses on is resize support:
> 295 +GLfloat const texcoords[]{
> 296 + 0.0f, 0.0f,
> 297 + 0.0f, 1.0f,
> 298 + 1.0f, 0.0f,
> 299 + 1.0f, 1.0f
> 300 +};
> Fixed texcoords means you're regressing on bug 1259887.
Interesting, although its an exercise in the definition of 'regression' to figure out if new code with a new purpose can regress. It also points out another difference in the RenderableList and the hwc_contents_1_t list, which is that the hwc list defines position by the top-left corner, and the Renderable:
>
> (2) This is misleading:
> +void mga::OverlayGLP
> "program" has a very specific meaning in OpenGL but you are giving a
> "GLProgram" class fixed-function GL calls. That makes no sense. But also, see
> (1)
ack, will think of new naming.
>
> I suggest these changes would be better deferred until there's a real use case
> for them, because they only create serious maintenance concerns AFAICS right
> now. And with some more thought, we should fall back to the GLRenderer (or
> whatever the default renderer is), instead of writing yet another GL renderer.
The real use-case right now is the mir_demo_
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
Ok I understand the GLRenderer can get arbitrarily elaborate and it may not be a good idea to use the same objects/shaders to render both. I'm all for KISS! Also, I think you're saying GLRenderer could be replaced but "overlay rendering" (now I'm using the term that I said I didnt like) cannot, and making them share code might cause problems for those that want to replace the GLRenderer. Understood.
You said you'd change the class name above. Could we find a different designation for these surfaces once they 've been rejected as overlays.
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
AFAIS the this fallback renderer is not replaceable. This means that we 'd be requiring GL capable GPU once this code is merged. To me, it's okay, Android has required it for a couple of years now. But since GLRenderer is replaceable, perhaps there was a discussion/
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
> AFAIS the this fallback renderer is not replaceable. This means that we 'd be
> requiring GL capable GPU once this code is merged. To me, it's okay, Android
> has required it for a couple of years now. But since GLRenderer is
> replaceable, perhaps there was a discussion/
> without GL. So I wanted to explicitly state this.
Right, a GL capable gpu, but really just for the android platform. We also have further detanglement to do in mg::DisplayBuffer if we ever get a non-GL/EGL platform.
Still thinking on the naming, but I think its good to make the distinction of 'overlays' just in the android platform, and, within the android platform, to classify by 'overlay' or by 'fallback rendered' based on the result of prepare()
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Can we establish what's wrong with GLRenderer? In theory it's going to be much faster (e.g. has texture caching), less buggy (e.g. the texcoords) and more featured (e.g. has screen rotation) than what's presented here. Using GLRenderer is not only faster, less buggy and more featured, but also halves maintenance effort.
GLRenderer appears to win at every point. So if anyone thinks it's heavy-weight then please point out where and we'll fix it.
Alberto Aguirre (albaguirre) wrote : Posted in a previous version of this proposal | # |
OverlayCompositor and OverlayGLProgram,
maybe
HWCFallbackComp
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
> Can we establish what's wrong with GLRenderer? In theory it's going to be much
> faster (e.g. has texture caching), less buggy (e.g. the texcoords) and more
> featured (e.g. has screen rotation) than what's presented here. Using
> GLRenderer is not only faster, less buggy and more featured, but also halves
> maintenance effort.
>
> GLRenderer appears to win at every point. So if anyone thinks it's heavy-
> weight then please point out where and we'll fix it.
Right, so nothing is wrong with GLRenderer, but we do have difference in what we require the two programs to do. We have marching orders to make GLRenderer+QtSG the next-gen full featured composition system (that is also the USC renderer); something that is much more than the requirements HWC gives us to implement the overlay functionality.
Writing a second program is a bit of a judgement call and the upsides are that the GLRenderer can grow and flex without having to fulfill the "be the full-featured next generation advanced OpenGL compositor" requirement while still having to fulfill the fixed requirements of HWC. GLRenderer can just grow to be the advanced compositor we want it to be. I'd agree with the half the maintenence effort if this was an open-ended program, but its not. This program has a very small fixed set of things it has to do, so the road to the perfect HWC program is short and unambiguous.
GLRenderer still has a fair amount of expansion that we'll build upon, and we'll isolate this fallback path from any changes to that class. (changes that would only hit the android platform as bugs). I'm worried that we'll go to implement something like an animation system (on the desktop) and inadvertently cause rendering problems on android, problems that would only occur in fallback scenarios.
I think a decent compromise is to:
1) maintain the second small program in the android platform, so we can let GLRenderer grow and isolate this platform-specific GL requirement from any changes there.
2) tease out mc::GLRenderer:
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
I'm concerned that we're going to have to fix everything twice. And in fact fix things that aren't yet broken, like resizing and rotation. Delegating blame of such issues to just say it only affects overlays is one thing, but fixing regressions will occupy more time than not having to fix regressions.
Also consider this: Most shells will presumably be built on OpenGL at some level. So unless you always have a fullscreen app open part of the shell will be visible. And if part of the shell is visible then you already have to do some GL rendering on that frame. And if you already have to GLRender on that frame, why not use the GLRenderer that is already going to be used for other elements in that frame anyway?
I share your fears (and some excitement) for the growth of GLRenderer. But we are capable of breaking it up and modularization. Having thought about animation a lot in the past year, if I believed it should be strictly wired into the renderer then I would have proposed it already (the design is mostly done in my head). However I too want to be cautious about how much responsibility the core default GLRenderer has.
On the issue of tessellate(), that's an interesting one. Because tessellate() is a strictly OpenGL-specific operation. Not just in its implementation, but the concept only makes sense to OpenGL in my experience. And having to produce only triangles is unfortunately a requirement only for the ES variation of OpenGL.
Alberto Aguirre (albaguirre) wrote : Posted in a previous version of this proposal | # |
I think I'm convinced that it should be a separate program.
However it should be a very simple fallback - that is no resize support and no handling of screen rotation; I believe what is proposed here satisfies that.
If those features are needed, then it should fallback to the path we currently have (with GLRenderer).
So: hwc->prepare(..)
If all layers accepted - great - nothing else to do.
If some layers got rejected and need screen rotation/resizing - fallback to GLRenderer path - composite all layers with GLRenderer - essentially the path we use currently.
Otherwise fallback so simple hwc fallback GL compositor.
Needs fixing:
OverlayGLProgram - my suggestion is HWCFallbackGLRe
OverlayCompositor - like Cemil says once rejected they are not "overlays" per se. So my suggestions is HWCFallbackComp
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
+1 on the names Alberto is proposing.
I think things will get interesting when YUV support is eventually added. Hopefully display overlay will support the format so hwc will not reject it. But if it does, it's almost certain that resize will be needed - video dimensions almost never match player's viewing area. Also, rotation should be supported IMHO, too.
Why not use the "replaceable renderer"? (I'm not calling it GLRenderer on purpose). It may not be capable of handling YUV due to, perhaps, hardware limitations on the format/
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
So the specific thing that happened to me when I was developing was I was tinkering with the demo shell on the adreno nexus 7, and the driver optimized the render by clipping the pixels outside of the bounding box of the hwc_layer_1_t. (pushed out less pixels) Since the demo shell clears to grey, and the HWC api guarantees a black background, this made the image on the screen cleared to grey within the bounding box, and cleared to black outside the bounding box.
Now, this is 'valid' HWC behavior, as they only have to guarantee what was sent to the driver in prepare() makes it to the screen, but it is not valid OpenGL behavior.
Furthermore, an extra level of insidious-ness about this discrepancy is that only certain devices running under certain modes might step outside of the OpenGL box and rely on the less-universal requirements of HWC to try some optimization.
So, I'm more nervous about situations where doing something reasonable in GLRenderer (like setting a non-black background color) cause rendering glitches on specific devices, running under specific modes, only when the driver chooses to reject the overlay surface.
I'm less nervous about the task of setting up and maintaining a GL shader program that fulfills the requirements of HWC to the letter, and isolates GLRenderer/common gl code from the weirdness of HWC. The program will just do the basic stuff HWC needs (2D positioning, 90 degree rotation, cropping)
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
> +1 on the names Alberto is proposing.
>
> I think things will get interesting when YUV support is eventually added.
> Hopefully display overlay will support the format so hwc will not reject it.
> But if it does, it's almost certain that resize will be needed - video
> dimensions almost never match player's viewing area. Also, rotation should be
> supported IMHO, too.
I'm starting out with just the simple non-scaled, non-rotated, non-alpha blended stuff, and then I'll roll out alpha, and 90deg rotation, etc after some testing focused on those features. But yes, rotation is something that should be supported.
>
> Why not use the "replaceable renderer"? (I'm not calling it GLRenderer on
> purpose). It may not be capable of handling YUV due to, perhaps, hardware
> limitations on the format/
> the specific GPU resource powering the "replaceable renderer". For instance
> for an extremely power efficient device operation, the replaceable renderer
> could be powered by a blitter, only on occasion falling back to 3D GPU. So the
> replaceable renderer could go either way - more fully fledged, or dumber.
> Whereas the hwc fallback renderer always have a very well-defined task to do.
YUV is interesting, and I saw that it got much more public support in HWC 1.3. (previously there were hacks behind the scenes iirc). It might be another place where we might have to mix some 'android-standard' approaches with the 'universal OpenGL' approach. There is a fair amount of plumbing in mir (libmirserver and libmirclient) that we have to do before YUV surfaces can get to the compositor though.
Alberto Aguirre (albaguirre) wrote : Posted in a previous version of this proposal | # |
> I'm starting out with just the simple non-scaled, non-rotated, non-alpha
> blended stuff, and then I'll roll out alpha, and 90deg rotation, etc after
> some testing focused on those features. But yes, rotation is something that
> should be supported.
>
That's my point though, if you punt to the GLRenderer (for ALL layers even if only one is rejected)
then there's no need to implement those features and the HWC Fallback renderer can remain very simple.
Alberto Aguirre (albaguirre) wrote : Posted in a previous version of this proposal | # |
> > I'm starting out with just the simple non-scaled, non-rotated, non-alpha
> > blended stuff, and then I'll roll out alpha, and 90deg rotation, etc after
> > some testing focused on those features. But yes, rotation is something that
> > should be supported.
> >
>
> That's my point though, if you punt to the GLRenderer (for ALL layers even if
> only one is rejected)
> then there's no need to implement those features and the HWC Fallback renderer
> can remain very simple.
I mean punt when layers are rejected and any of the rejected layers needs resizing, rotation etc...
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
so hopefully the naming should be addressed. "OverlayCompositor" was just the name of the test. The class and the test are now "HWCFallbackGLR
Still working on addressing the outstanding points, probably won't get them out the door today(4/30)
Alberto Aguirre (albaguirre) wrote : Posted in a previous version of this proposal | # |
In any case this first simple version looks good to me.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1585
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Even if it is justified in introducing a new code path, I think we can still do a bit better in avoiding the very familiar duplication inside mga::HWCFallbac
The first part of that (which I had hoped to do anyway) is to pass Renderer::render() the full list. Then the various render() functions start to look even more similar. And as such it will become easier to avoid duplicate code.
I'm not quite convinced enough yet. Because I think there is simple work we can do relatively quickly to reduce the duplication (and ideally avoid regressions landing).
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
> Even if it is justified in introducing a new code path, I think we can still
> do a bit better in avoiding the very familiar duplication inside
> mga::HWCFallbac
>
> The first part of that (which I had hoped to do anyway) is to pass
> Renderer::render() the full list. Then the various render() functions start to
> look even more similar. And as such it will become easier to avoid duplicate
> code.
Given my thoughts about the quirks of HWC/OpenGL interplay, some object in the system must be the hardware-specific HWC renderer. It must play by the OpenGL+HWC limitations. There exists some other item in the system that can do full opengl, that the user can override, and can expand in whatever way we see fit. So the unresolved question is "is this second item a private instance of the GLRenderer?"
I would still say there's a good case to have something different:
1) although I have in rev1585:
void mga::HWCFallbac
this really should be render(
1a) A Renderable is a superset of the information that a hwc_layer_1_t is. We could limit the GLRenderer to what the hwc_layer_1_t can do, or we can have the GLRenderer do more than what the hwc requires. It seems better to just let them evolve on their own path, especially as one requirement is platform-specific.
2) The requirement that the rejected overlays should be drawn via OpenGL is a quirk of the Android platform. Having a non-overridable OpenGL+
3) In the same sort of vein, the object that supports this android quirk, and the object that is the platform-
4) Splitting the two also lets us keep the interesting GLRenderer stuff GPL and the simplistic android stuff LGPL. Without getting too a head of myself, this could ease working with vendors when/if we come hwc extension agreements after working with them.
Now, having said all that :) The opposing point about code reuse is valid, and I can share some of the code by teasing it out of GLRenderer. I'm envisioning a smallish LGPL header with ways to do 1) texture caching 2) tessellation 3) texcood c...
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:1585
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
Happy with the names.
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
(1) Still too much redundancy. And I don't think designing in regressions is OK, unless we agree no one is ever going to use the overlays path. We don't have to resolve this by inheriting from or calling GLRenderer necessarily. The various *GLRenderer's could call some common code that contains the shared logic.
(3) This class name is too long and also misleading - SingleVertexSin
(4) Can you tease apart the proposal into smaller chunks? I suspect that might make it easier to manage...
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
2)
Sure, can address the naming. OneVertexShader
1)
I haven't had as much time to work on splitting out the code this week as I'd have liked, but I do plan on reusing some of the various GLRenderer calls. Specifically, the texture caching, and the texcoord calculation. I can get these out the door before this lands so the reuse plan is more visible.
3)
I was thinking that anything less would might be hard to review from "dont see the big picture" argument.
This chunk of code is what I deemed the minimal amount that will get something sensible in this place, and less code would be difficult to figure out what I'm trying to do. Maybe I can break out the changes to the Rectangle eg, top_right(), or the interface changes (which were largely test-driven)
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:1586
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
> I haven't had as much time to work on splitting out the code this week as I'd
> have liked, but I do plan on reusing some of the various GLRenderer calls.
> Specifically, the texture caching, and the texcoord calculation. I can get
> these out the door before this lands so the reuse plan is more visible.
I still want to chew on the naming before mp-ing, but split out the texture caching here: lp:~kdub/mir/reusable-texture-cache. Will get to the texcoord stuff tomorrow, and rebase on those.
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
There's also lp:~kdub/mir/reusable-quad-calculation that this branch can pick up to increase the amount of code reuse between the two programs. Hopefully those two branches address some of the reused code concerns.
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
Since this is now based on two branches resubmitting with a prerequisite branch would still give too big of a diff. Maintaining the merge of the branches here: lp:~kdub/mir/overlay-gl-program-with-reuse , which I will merge into this branch once the prereqs land.
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
diff should reduce once the landing queue clears
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:1606
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:1608
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Oh, good work keeping this branch up to date with the other landings.
I note that the current Approvals however are based on a much older and significantly version. So I think the current Approvals need to be invalidated by resubmitting the proposal.
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
151 + return 7;
Magic?
~~~~
790 +// EXPECT_
Useless code or useless comment - either way it is useless.
Kevin DuBois (kdub) wrote : | # |
@Daniel,
resubmitted.
@Alan,
not a magic number, just a valid number that the stub could return.
comment removed.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1610
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alberto Aguirre (albaguirre) wrote : | # |
~~
151 + return 7;
~~
Perhaps:
int const arbitrary_id = 7;
return arbitrary_id;
Looks good.
PS Jenkins bot (ps-jenkins) : | # |
Preview Diff
1 | === modified file 'include/platform/mir/graphics/gl_program.h' |
2 | --- include/platform/mir/graphics/gl_program.h 2014-05-07 02:56:33 +0000 |
3 | +++ include/platform/mir/graphics/gl_program.h 2014-05-22 16:51:59 +0000 |
4 | @@ -43,17 +43,26 @@ |
5 | class GLProgram |
6 | { |
7 | public: |
8 | - GLProgram( |
9 | + virtual ~GLProgram() = default; |
10 | + virtual operator GLuint() const = 0; |
11 | + |
12 | +protected: |
13 | + GLProgram() = default; |
14 | +private: |
15 | + GLProgram(GLProgram const&) = delete; |
16 | + GLProgram& operator=(GLProgram const&) = delete; |
17 | +}; |
18 | + |
19 | +class SimpleGLProgram : public GLProgram |
20 | +{ |
21 | +public: |
22 | + SimpleGLProgram( |
23 | GLchar const* vertex_shader_src, |
24 | GLchar const* fragment_shader_src); |
25 | - ~GLProgram(); |
26 | - |
27 | - operator GLuint() const; |
28 | - |
29 | + ~SimpleGLProgram(); |
30 | + |
31 | + operator GLuint() const override; |
32 | private: |
33 | - GLProgram(GLProgram const&) = delete; |
34 | - GLProgram& operator=(GLProgram const&) = delete; |
35 | - |
36 | GLShader const vertex_shader; |
37 | GLShader const fragment_shader; |
38 | GLuint const program; |
39 | |
40 | === modified file 'include/platform/mir/graphics/gl_program_factory.h' |
41 | --- include/platform/mir/graphics/gl_program_factory.h 2014-04-22 16:45:27 +0000 |
42 | +++ include/platform/mir/graphics/gl_program_factory.h 2014-05-22 16:51:59 +0000 |
43 | @@ -20,6 +20,7 @@ |
44 | #define MIR_COMPOSITOR_GL_PROGRAM_FACTORY_H_ |
45 | |
46 | #include "mir/graphics/gl_program.h" |
47 | +#include "mir/graphics/gl_texture_cache.h" |
48 | #include <memory> |
49 | |
50 | namespace mir |
51 | @@ -34,7 +35,7 @@ |
52 | |
53 | virtual std::unique_ptr<GLProgram> |
54 | create_gl_program(std::string const&, std::string const&) const = 0; |
55 | - |
56 | + virtual std::unique_ptr<GLTextureCache> create_texture_cache() const = 0; |
57 | protected: |
58 | GLProgramFactory() = default; |
59 | |
60 | |
61 | === modified file 'include/shared/mir/geometry/point.h' |
62 | --- include/shared/mir/geometry/point.h 2014-03-06 06:05:17 +0000 |
63 | +++ include/shared/mir/geometry/point.h 2014-05-22 16:51:59 +0000 |
64 | @@ -50,6 +50,9 @@ |
65 | return lhs.x != rhs.x || lhs.y != rhs.y; |
66 | } |
67 | |
68 | +inline Point operator+(Point lhs, DeltaX rhs) { return{lhs.x + rhs, lhs.y}; } |
69 | +inline Point operator+(Point lhs, DeltaY rhs) { return{lhs.x, lhs.y + rhs}; } |
70 | + |
71 | std::ostream& operator<<(std::ostream& out, Point const& value); |
72 | } |
73 | } |
74 | |
75 | === modified file 'include/shared/mir/geometry/rectangle.h' |
76 | --- include/shared/mir/geometry/rectangle.h 2014-03-06 06:05:17 +0000 |
77 | +++ include/shared/mir/geometry/rectangle.h 2014-05-22 16:51:59 +0000 |
78 | @@ -42,6 +42,8 @@ |
79 | * area, that is, the rectangle is represented as [top_left,bottom_right). |
80 | */ |
81 | Point bottom_right() const; |
82 | + Point top_right() const; |
83 | + Point bottom_left() const; |
84 | bool contains(Point const& p) const; |
85 | |
86 | /** |
87 | |
88 | === modified file 'include/test/mir_test_doubles/mock_display_device.h' |
89 | --- include/test/mir_test_doubles/mock_display_device.h 2014-05-19 02:55:29 +0000 |
90 | +++ include/test/mir_test_doubles/mock_display_device.h 2014-05-22 16:51:59 +0000 |
91 | @@ -22,7 +22,7 @@ |
92 | #include "mir/graphics/buffer.h" |
93 | #include "src/platform/graphics/android/display_device.h" |
94 | #include "src/platform/graphics/android/gl_context.h" |
95 | -#include "src/platform/graphics/android/overlay_gl_compositor.h" |
96 | +#include "src/platform/graphics/android/hwc_fallback_gl_renderer.h" |
97 | #include <gmock/gmock.h> |
98 | |
99 | namespace mir |
100 | |
101 | === modified file 'include/test/mir_test_doubles/mock_renderable_list_compositor.h' |
102 | --- include/test/mir_test_doubles/mock_renderable_list_compositor.h 2014-04-30 18:26:29 +0000 |
103 | +++ include/test/mir_test_doubles/mock_renderable_list_compositor.h 2014-05-22 16:51:59 +0000 |
104 | @@ -19,7 +19,7 @@ |
105 | #ifndef MIR_TEST_DOUBLES_MOCK_RENDERABLE_LIST_COMPOSITOR_H_ |
106 | #define MIR_TEST_DOUBLES_MOCK_RENDERABLE_LIST_COMPOSITOR_H_ |
107 | |
108 | -#include "src/platform/graphics/android/overlay_gl_compositor.h" |
109 | +#include "src/platform/graphics/android/hwc_fallback_gl_renderer.h" |
110 | #include <gmock/gmock.h> |
111 | |
112 | namespace mir |
113 | |
114 | === added file 'include/test/mir_test_doubles/stub_gl_program.h' |
115 | --- include/test/mir_test_doubles/stub_gl_program.h 1970-01-01 00:00:00 +0000 |
116 | +++ include/test/mir_test_doubles/stub_gl_program.h 2014-05-22 16:51:59 +0000 |
117 | @@ -0,0 +1,42 @@ |
118 | +/* |
119 | + * Copyright © 2014 Canonical Ltd. |
120 | + * |
121 | + * This program is free software: you can redistribute it and/or modify it |
122 | + * under the terms of the GNU General Public License version 3, |
123 | + * as published by the Free Software Foundation. |
124 | + * |
125 | + * This program is distributed in the hope that it will be useful, |
126 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
127 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
128 | + * GNU General Public License for more details. |
129 | + * |
130 | + * You should have received a copy of the GNU General Public License |
131 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
132 | + * |
133 | + * Authored by: Kevin DuBois <kevin.dubois@canonical.com> |
134 | + */ |
135 | +#ifndef MIR_TEST_DOUBLES_STUB_GL_PROGRAM_H_ |
136 | +#define MIR_TEST_DOUBLES_STUB_GL_PROGRAM_H_ |
137 | + |
138 | +#include "mir/graphics/gl_program_factory.h" |
139 | + |
140 | +namespace mir |
141 | +{ |
142 | +namespace test |
143 | +{ |
144 | +namespace doubles |
145 | +{ |
146 | + |
147 | +struct StubGLProgram : public graphics::GLProgram |
148 | +{ |
149 | + operator GLuint() const override |
150 | + { |
151 | + return 7; |
152 | + } |
153 | +}; |
154 | + |
155 | +} |
156 | +} |
157 | +} // namespace mir |
158 | + |
159 | +#endif /* MIR_TEST_DOUBLES_STUB_GL_PROGRAM_H_ */ |
160 | |
161 | === modified file 'include/test/mir_test_doubles/stub_gl_program_factory.h' |
162 | --- include/test/mir_test_doubles/stub_gl_program_factory.h 2014-04-24 20:07:20 +0000 |
163 | +++ include/test/mir_test_doubles/stub_gl_program_factory.h 2014-05-22 16:51:59 +0000 |
164 | @@ -19,6 +19,7 @@ |
165 | #define MIR_TEST_DOUBLES_STUB_GL_PROGRAM_FACTORY_H_ |
166 | |
167 | #include "mir/graphics/gl_program_factory.h" |
168 | +#include "stub_gl_program.h" |
169 | |
170 | namespace mir |
171 | { |
172 | @@ -32,6 +33,11 @@ |
173 | public: |
174 | std::unique_ptr<graphics::GLProgram> create_gl_program(std::string const&, std::string const&) const |
175 | { |
176 | + return std::unique_ptr<graphics::GLProgram>(new StubGLProgram); |
177 | + } |
178 | + |
179 | + std::unique_ptr<graphics::GLTextureCache> create_texture_cache() const |
180 | + { |
181 | return nullptr; |
182 | } |
183 | }; |
184 | |
185 | === modified file 'include/test/mir_test_doubles/stub_renderable.h' |
186 | --- include/test/mir_test_doubles/stub_renderable.h 2014-05-07 02:56:33 +0000 |
187 | +++ include/test/mir_test_doubles/stub_renderable.h 2014-05-22 16:51:59 +0000 |
188 | @@ -33,13 +33,20 @@ |
189 | class StubRenderable : public graphics::Renderable |
190 | { |
191 | public: |
192 | + StubRenderable(geometry::Rectangle const& rect) |
193 | + : rect(rect) |
194 | + {} |
195 | + StubRenderable() : |
196 | + StubRenderable({{},{}}) |
197 | + {} |
198 | ID id() const override |
199 | { |
200 | return this; |
201 | } |
202 | std::shared_ptr<graphics::Buffer> buffer() const override |
203 | { |
204 | - return std::make_shared<StubBuffer>(); |
205 | + graphics::BufferProperties prop{rect.size, mir_pixel_format_abgr_8888, graphics::BufferUsage::hardware}; |
206 | + return std::make_shared<StubBuffer>(prop); |
207 | } |
208 | bool alpha_enabled() const |
209 | { |
210 | @@ -47,7 +54,7 @@ |
211 | } |
212 | geometry::Rectangle screen_position() const |
213 | { |
214 | - return {{},{}}; |
215 | + return rect; |
216 | } |
217 | float alpha() const override |
218 | { |
219 | @@ -73,6 +80,7 @@ |
220 | |
221 | private: |
222 | glm::mat4 trans; |
223 | + geometry::Rectangle const rect; |
224 | }; |
225 | |
226 | } |
227 | |
228 | === modified file 'include/test/mir_test_doubles/stub_renderable_list_compositor.h' |
229 | --- include/test/mir_test_doubles/stub_renderable_list_compositor.h 2014-04-30 18:26:29 +0000 |
230 | +++ include/test/mir_test_doubles/stub_renderable_list_compositor.h 2014-05-22 16:51:59 +0000 |
231 | @@ -19,7 +19,7 @@ |
232 | #ifndef MIR_TEST_DOUBLES_STUB_RENDERABLE_LIST_COMPOSITOR_H_ |
233 | #define MIR_TEST_DOUBLES_STUB_RENDERABLE_LIST_COMPOSITOR_H_ |
234 | |
235 | -#include "src/platform/graphics/android/overlay_gl_compositor.h" |
236 | +#include "src/platform/graphics/android/hwc_fallback_gl_renderer.h" |
237 | |
238 | namespace mir |
239 | { |
240 | |
241 | === modified file 'src/platform/graphics/android/CMakeLists.txt' |
242 | --- src/platform/graphics/android/CMakeLists.txt 2014-05-22 11:31:21 +0000 |
243 | +++ src/platform/graphics/android/CMakeLists.txt 2014-05-22 16:51:59 +0000 |
244 | @@ -36,7 +36,7 @@ |
245 | gl_context.cpp |
246 | device_quirks.cpp |
247 | real_hwc_wrapper.cpp |
248 | - overlay_gl_compositor.cpp |
249 | + hwc_fallback_gl_renderer.cpp |
250 | ) |
251 | |
252 | set_target_properties( |
253 | |
254 | === modified file 'src/platform/graphics/android/display_buffer.cpp' |
255 | --- src/platform/graphics/android/display_buffer.cpp 2014-05-22 11:31:21 +0000 |
256 | +++ src/platform/graphics/android/display_buffer.cpp 2014-05-22 16:51:59 +0000 |
257 | @@ -62,7 +62,7 @@ |
258 | display_device{display_device}, |
259 | native_window{native_window}, |
260 | gl_context{shared_gl_context, std::bind(mga::create_window_surface, std::placeholders::_1, std::placeholders::_2, native_window.get())}, |
261 | - overlay_program{program_factory, gl_context}, |
262 | + overlay_program{program_factory, gl_context, geom::Rectangle{{0,0},fb_bundle->fb_size()}}, |
263 | current_configuration{ |
264 | mg::DisplayConfigurationOutputId{1}, |
265 | mg::DisplayConfigurationCardId{0}, |
266 | |
267 | === modified file 'src/platform/graphics/android/display_buffer.h' |
268 | --- src/platform/graphics/android/display_buffer.h 2014-05-22 11:31:21 +0000 |
269 | +++ src/platform/graphics/android/display_buffer.h 2014-05-22 16:51:59 +0000 |
270 | @@ -24,7 +24,7 @@ |
271 | #include "mir/graphics/gl_program_factory.h" |
272 | #include "android_display_configuration.h" |
273 | #include "gl_context.h" |
274 | -#include "overlay_gl_compositor.h" |
275 | +#include "hwc_fallback_gl_renderer.h" |
276 | #include <system/window.h> |
277 | |
278 | namespace mir |
279 | @@ -65,7 +65,7 @@ |
280 | std::shared_ptr<DisplayDevice> const display_device; |
281 | std::shared_ptr<ANativeWindow> const native_window; |
282 | GLContext gl_context; |
283 | - OverlayGLProgram overlay_program; |
284 | + HWCFallbackGLRenderer overlay_program; |
285 | bool prepared; |
286 | DisplayConfigurationOutput current_configuration; |
287 | MirOrientation rotation; |
288 | |
289 | === modified file 'src/platform/graphics/android/fb_device.cpp' |
290 | --- src/platform/graphics/android/fb_device.cpp 2014-05-19 02:55:29 +0000 |
291 | +++ src/platform/graphics/android/fb_device.cpp 2014-05-22 16:51:59 +0000 |
292 | @@ -24,7 +24,7 @@ |
293 | #include "fb_device.h" |
294 | #include "framebuffer_bundle.h" |
295 | #include "buffer.h" |
296 | -#include "overlay_gl_compositor.h" |
297 | +#include "hwc_fallback_gl_renderer.h" |
298 | |
299 | #include <boost/throw_exception.hpp> |
300 | #include <stdexcept> |
301 | |
302 | === modified file 'src/platform/graphics/android/hwc_device.cpp' |
303 | --- src/platform/graphics/android/hwc_device.cpp 2014-05-19 02:55:29 +0000 |
304 | +++ src/platform/graphics/android/hwc_device.cpp 2014-05-22 16:51:59 +0000 |
305 | @@ -24,7 +24,7 @@ |
306 | #include "hwc_wrapper.h" |
307 | #include "framebuffer_bundle.h" |
308 | #include "buffer.h" |
309 | -#include "overlay_gl_compositor.h" |
310 | +#include "hwc_fallback_gl_renderer.h" |
311 | |
312 | namespace mg = mir::graphics; |
313 | namespace mga=mir::graphics::android; |
314 | |
315 | === renamed file 'src/platform/graphics/android/overlay_gl_compositor.cpp' => 'src/platform/graphics/android/hwc_fallback_gl_renderer.cpp' |
316 | --- src/platform/graphics/android/overlay_gl_compositor.cpp 2014-05-19 02:55:29 +0000 |
317 | +++ src/platform/graphics/android/hwc_fallback_gl_renderer.cpp 2014-05-22 16:51:59 +0000 |
318 | @@ -18,36 +18,113 @@ |
319 | |
320 | #include "mir/graphics/gl_program_factory.h" |
321 | #include "mir/graphics/gl_context.h" |
322 | -#include "overlay_gl_compositor.h" |
323 | +#include "mir/graphics/gl_texture.h" |
324 | +#include "mir/graphics/tessellation_helpers.h" |
325 | +#include "hwc_fallback_gl_renderer.h" |
326 | +#include "gl_context.h" |
327 | +#include "buffer.h" |
328 | + |
329 | +#define GLM_FORCE_RADIANS |
330 | +#define GLM_PRECISION_MEDIUMP_FLOAT |
331 | +#include <glm/glm.hpp> |
332 | +#include <glm/gtc/matrix_transform.hpp> |
333 | +#include <glm/gtc/type_ptr.hpp> |
334 | |
335 | namespace mg = mir::graphics; |
336 | namespace mga = mir::graphics::android; |
337 | +namespace geom = mir::geometry; |
338 | + |
339 | namespace |
340 | { |
341 | std::string const vertex_shader |
342 | { |
343 | - "attribute vec4 position;\n" |
344 | + "attribute vec3 position;\n" |
345 | + "attribute vec2 texcoord;\n" |
346 | + "uniform mat4 display_transform;\n" |
347 | + "varying vec2 v_texcoord;\n" |
348 | "void main() {\n" |
349 | - " gl_Position = position;\n" |
350 | + " gl_Position = display_transform * vec4(position, 1.0);\n" |
351 | + " v_texcoord = texcoord;\n" |
352 | "}\n" |
353 | }; |
354 | |
355 | std::string const fragment_shader |
356 | { |
357 | "precision mediump float;\n" |
358 | + "uniform sampler2D tex;\n" |
359 | + "varying vec2 v_texcoord;\n" |
360 | "void main() {\n" |
361 | - " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n" |
362 | + " gl_FragColor = texture2D(tex, v_texcoord);\n" |
363 | "}\n" |
364 | }; |
365 | -} |
366 | -mga::OverlayGLProgram::OverlayGLProgram( |
367 | - GLProgramFactory const& factory, GLContext const& context) |
368 | + |
369 | +void set_display_transform(GLint uniform_loc, geom::Rectangle const& rect) |
370 | +{ |
371 | + glm::mat4 disp_transform(1.0); |
372 | + |
373 | + disp_transform = glm::translate(disp_transform, glm::vec3{-1.0, 1.0, 0.0}); |
374 | + disp_transform = glm::scale( |
375 | + disp_transform, |
376 | + glm::vec3{2.0/rect.size.width.as_float(), |
377 | + -2.0/rect.size.height.as_float(), |
378 | + 1.0}); |
379 | + glUniformMatrix4fv(uniform_loc, 1, GL_FALSE, glm::value_ptr(disp_transform)); |
380 | +} |
381 | +} |
382 | + |
383 | +mga::HWCFallbackGLRenderer::HWCFallbackGLRenderer( |
384 | + GLProgramFactory const& factory, |
385 | + mg::GLContext const& context, |
386 | + geom::Rectangle const& screen_pos) |
387 | { |
388 | context.make_current(); |
389 | - overlay_program = factory.create_gl_program(vertex_shader, fragment_shader); |
390 | + program = factory.create_gl_program(vertex_shader, fragment_shader); |
391 | + texture_cache = factory.create_texture_cache(); |
392 | + |
393 | + glUseProgram(*program); |
394 | + |
395 | + auto display_transform_uniform = glGetUniformLocation(*program, "display_transform"); |
396 | + set_display_transform(display_transform_uniform, screen_pos); |
397 | + |
398 | + position_attr = glGetAttribLocation(*program, "position"); |
399 | + texcoord_attr = glGetAttribLocation(*program, "texcoord"); |
400 | + |
401 | + auto tex_loc = glGetUniformLocation(*program, "tex"); |
402 | + glUniform1i(tex_loc, 0); |
403 | + |
404 | + glBindBuffer(GL_ARRAY_BUFFER, 0); |
405 | + |
406 | + glUseProgram(0); |
407 | context.release_current(); |
408 | } |
409 | |
410 | -void mga::OverlayGLProgram::render(RenderableList const&, SwappingGLContext const&) const |
411 | +void mga::HWCFallbackGLRenderer::render( |
412 | + RenderableList const& renderlist, SwappingGLContext const& context) const |
413 | { |
414 | + glUseProgram(*program); |
415 | + |
416 | + glClearColor(0.0, 0.0, 0.0, 1.0); |
417 | + glClear(GL_COLOR_BUFFER_BIT); |
418 | + |
419 | + glEnableVertexAttribArray(position_attr); |
420 | + glEnableVertexAttribArray(texcoord_attr); |
421 | + |
422 | + for(auto const& renderable : renderlist) |
423 | + { |
424 | + auto const primitive = mg::tessellate_renderable_into_rectangle(*renderable); |
425 | + glVertexAttribPointer(position_attr, 3, GL_FLOAT, GL_FALSE, sizeof(mg::GLVertex), |
426 | + &primitive.vertices[0].position); |
427 | + //TODO: (kdub) scaling or pi/2 rotation eventually. for now, all quads get same texcoords |
428 | + glVertexAttribPointer(texcoord_attr, 2, GL_FLOAT, GL_FALSE, sizeof(mg::GLVertex), |
429 | + &primitive.vertices[0].texcoord); |
430 | + |
431 | + texture_cache->load(*renderable)->bind(); |
432 | + glDrawArrays(primitive.type, 0, primitive.vertices.size()); |
433 | + } |
434 | + |
435 | + glDisableVertexAttribArray(texcoord_attr); |
436 | + glDisableVertexAttribArray(position_attr); |
437 | + context.swap_buffers(); |
438 | + texture_cache->drop_unused(); |
439 | + glUseProgram(0); |
440 | } |
441 | |
442 | === renamed file 'src/platform/graphics/android/overlay_gl_compositor.h' => 'src/platform/graphics/android/hwc_fallback_gl_renderer.h' |
443 | --- src/platform/graphics/android/overlay_gl_compositor.h 2014-05-19 02:55:29 +0000 |
444 | +++ src/platform/graphics/android/hwc_fallback_gl_renderer.h 2014-05-22 16:51:59 +0000 |
445 | @@ -16,11 +16,12 @@ |
446 | * Authored by: Kevin DuBois <kevin.dubois@canonical.com> |
447 | */ |
448 | |
449 | -#ifndef MIR_GRAPHICS_ANDROID_OVERLAY_GL_PROGRAM_H_ |
450 | -#define MIR_GRAPHICS_ANDROID_OVERLAY_GL_PROGRAM_H_ |
451 | - |
452 | +#ifndef MIR_GRAPHICS_ANDROID_HWC_FALLBACK_GL_RENDERER_H_ |
453 | +#define MIR_GRAPHICS_ANDROID_HWC_FALLBACK_GL_RENDERER_H_ |
454 | +#include "mir/geometry/rectangle.h" |
455 | #include "mir/graphics/gl_program.h" |
456 | #include "mir/graphics/renderable.h" |
457 | +#include "mir/graphics/gl_texture_cache.h" |
458 | #include <memory> |
459 | |
460 | namespace mir |
461 | @@ -46,18 +47,25 @@ |
462 | RenderableListCompositor& operator=(RenderableListCompositor const&) = delete; |
463 | }; |
464 | |
465 | -class OverlayGLProgram : public RenderableListCompositor |
466 | +class HWCFallbackGLRenderer : public RenderableListCompositor |
467 | { |
468 | public: |
469 | - OverlayGLProgram(GLProgramFactory const& program_factory, graphics::GLContext const& gl_context); |
470 | + HWCFallbackGLRenderer( |
471 | + GLProgramFactory const& program_factory, |
472 | + graphics::GLContext const& gl_context, |
473 | + geometry::Rectangle const& screen_position); |
474 | |
475 | void render(RenderableList const&, SwappingGLContext const&) const; |
476 | private: |
477 | - std::unique_ptr<graphics::GLProgram> overlay_program; |
478 | + std::unique_ptr<graphics::GLProgram> program; |
479 | + std::unique_ptr<graphics::GLTextureCache> texture_cache; |
480 | + |
481 | + GLint position_attr; |
482 | + GLint texcoord_attr; |
483 | }; |
484 | |
485 | } |
486 | } |
487 | } |
488 | |
489 | -#endif /* MIR_GRAPHICS_ANDROID_OVERLAY_GL_PROGRAM_H_ */ |
490 | +#endif /* MIR_GRAPHICS_ANDROID_HWC_FALLBACK_GL_RENDERER_H_ */ |
491 | |
492 | === modified file 'src/platform/graphics/android/hwc_fb_device.cpp' |
493 | --- src/platform/graphics/android/hwc_fb_device.cpp 2014-05-19 02:55:29 +0000 |
494 | +++ src/platform/graphics/android/hwc_fb_device.cpp 2014-05-22 16:51:59 +0000 |
495 | @@ -22,7 +22,7 @@ |
496 | #include "framebuffer_bundle.h" |
497 | #include "android_format_conversion-inl.h" |
498 | #include "hwc_wrapper.h" |
499 | -#include "overlay_gl_compositor.h" |
500 | +#include "hwc_fallback_gl_renderer.h" |
501 | #include "mir/graphics/buffer.h" |
502 | #include "mir/graphics/android/native_buffer.h" |
503 | #include "gl_context.h" |
504 | |
505 | === modified file 'src/platform/graphics/gl_program.cpp' |
506 | --- src/platform/graphics/gl_program.cpp 2014-05-22 11:31:21 +0000 |
507 | +++ src/platform/graphics/gl_program.cpp 2014-05-22 16:51:59 +0000 |
508 | @@ -76,7 +76,7 @@ |
509 | return shader; |
510 | } |
511 | |
512 | -mg::GLProgram::GLProgram( |
513 | +mg::SimpleGLProgram::SimpleGLProgram( |
514 | GLchar const* vertex_shader_src, |
515 | GLchar const* fragment_shader_src) |
516 | : vertex_shader(vertex_shader_src, GL_VERTEX_SHADER), |
517 | @@ -98,12 +98,12 @@ |
518 | } |
519 | } |
520 | |
521 | -mg::GLProgram::~GLProgram() |
522 | +mg::SimpleGLProgram::~SimpleGLProgram() |
523 | { |
524 | glDeleteProgram(program); |
525 | } |
526 | |
527 | -mg::GLProgram::operator GLuint() const |
528 | +mg::SimpleGLProgram::operator GLuint() const |
529 | { |
530 | return program; |
531 | } |
532 | |
533 | === modified file 'src/server/compositor/gl_renderer.cpp' |
534 | --- src/server/compositor/gl_renderer.cpp 2014-05-22 11:31:21 +0000 |
535 | +++ src/server/compositor/gl_renderer.cpp 2014-05-22 16:51:59 +0000 |
536 | @@ -149,7 +149,7 @@ |
537 | tessellate(primitives, renderable); |
538 | |
539 | auto surface_tex = texture_cache->load(renderable); |
540 | - |
541 | + |
542 | for (auto const& p : primitives) |
543 | { |
544 | // Note a primitive tex_id of zero means use the surface texture, |
545 | |
546 | === modified file 'src/server/graphics/program_factory.cpp' |
547 | --- src/server/graphics/program_factory.cpp 2014-04-16 19:00:03 +0000 |
548 | +++ src/server/graphics/program_factory.cpp 2014-05-22 16:51:59 +0000 |
549 | @@ -19,6 +19,7 @@ |
550 | |
551 | #include "program_factory.h" |
552 | #include "mir/graphics/gl_program.h" |
553 | +#include "mir/compositor/recently_used_cache.h" |
554 | |
555 | namespace mg = mir::graphics; |
556 | |
557 | @@ -28,5 +29,12 @@ |
558 | std::string const& fragment_shader) const |
559 | { |
560 | std::lock_guard<decltype(mutex)> lock(mutex); |
561 | - return std::unique_ptr<mg::GLProgram>(new GLProgram(vertex_shader.c_str(), fragment_shader.c_str())); |
562 | + return std::unique_ptr<mg::GLProgram>( |
563 | + new SimpleGLProgram(vertex_shader.c_str(), fragment_shader.c_str())); |
564 | +} |
565 | + |
566 | +std::unique_ptr<mg::GLTextureCache> mg::ProgramFactory::create_texture_cache() const |
567 | +{ |
568 | + return std::unique_ptr<mg::GLTextureCache>( |
569 | + new mir::compositor::RecentlyUsedCache()); |
570 | } |
571 | |
572 | === modified file 'src/server/graphics/program_factory.h' |
573 | --- src/server/graphics/program_factory.h 2014-04-16 19:00:03 +0000 |
574 | +++ src/server/graphics/program_factory.h 2014-05-22 16:51:59 +0000 |
575 | @@ -21,6 +21,7 @@ |
576 | |
577 | #include "mir/graphics/gl_program_factory.h" |
578 | #include "mir/graphics/gl_program.h" |
579 | +#include "mir/graphics/gl_texture_cache.h" |
580 | #include <mutex> |
581 | |
582 | namespace mir |
583 | @@ -31,6 +32,7 @@ |
584 | { |
585 | public: |
586 | std::unique_ptr<GLProgram> create_gl_program(std::string const&, std::string const&) const override; |
587 | + std::unique_ptr<GLTextureCache> create_texture_cache() const; |
588 | |
589 | private: |
590 | /* |
591 | |
592 | === modified file 'src/shared/geometry/rectangle.cpp' |
593 | --- src/shared/geometry/rectangle.cpp 2013-10-15 08:53:10 +0000 |
594 | +++ src/shared/geometry/rectangle.cpp 2014-05-22 16:51:59 +0000 |
595 | @@ -28,6 +28,16 @@ |
596 | top_left.y.as_int() + size.height.as_int()}; |
597 | } |
598 | |
599 | +geom::Point geom::Rectangle::top_right() const |
600 | +{ |
601 | + return top_left + DeltaX{size.width.as_int()}; |
602 | +} |
603 | + |
604 | +geom::Point geom::Rectangle::bottom_left() const |
605 | +{ |
606 | + return top_left + DeltaY{size.height.as_int()}; |
607 | +} |
608 | + |
609 | bool geom::Rectangle::contains(Rectangle const& r) const |
610 | { |
611 | return r.top_left.x >= top_left.x && |
612 | |
613 | === modified file 'tests/unit-tests/graphics/android/CMakeLists.txt' |
614 | --- tests/unit-tests/graphics/android/CMakeLists.txt 2014-05-22 11:31:21 +0000 |
615 | +++ tests/unit-tests/graphics/android/CMakeLists.txt 2014-05-22 16:51:59 +0000 |
616 | @@ -27,7 +27,7 @@ |
617 | ${CMAKE_CURRENT_SOURCE_DIR}/test_output_builder.cpp |
618 | ${CMAKE_CURRENT_SOURCE_DIR}/test_device_detection.cpp |
619 | ${CMAKE_CURRENT_SOURCE_DIR}/test_hwc_wrapper.cpp |
620 | - ${CMAKE_CURRENT_SOURCE_DIR}/test_overlay_compositor.cpp |
621 | + ${CMAKE_CURRENT_SOURCE_DIR}/test_hwc_fallback_gl_renderer.cpp |
622 | ) |
623 | |
624 | set(UNIT_TEST_SOURCES ${UNIT_TEST_SOURCES} PARENT_SCOPE) |
625 | |
626 | === modified file 'tests/unit-tests/graphics/android/test_fb_device.cpp' |
627 | --- tests/unit-tests/graphics/android/test_fb_device.cpp 2014-05-21 17:18:51 +0000 |
628 | +++ tests/unit-tests/graphics/android/test_fb_device.cpp 2014-05-22 16:51:59 +0000 |
629 | @@ -19,7 +19,7 @@ |
630 | #include "mir_test_doubles/mock_fb_hal_device.h" |
631 | #include "mir_test_doubles/mock_buffer.h" |
632 | #include "src/platform/graphics/android/fb_device.h" |
633 | -#include "src/platform/graphics/android/overlay_gl_compositor.h" |
634 | +#include "src/platform/graphics/android/hwc_fallback_gl_renderer.h" |
635 | #include "mir_test_doubles/mock_framebuffer_bundle.h" |
636 | #include "mir_test_doubles/mock_android_hw.h" |
637 | #include "mir_test_doubles/mock_egl.h" |
638 | |
639 | === modified file 'tests/unit-tests/graphics/android/test_hwc_display.cpp' |
640 | --- tests/unit-tests/graphics/android/test_hwc_display.cpp 2014-05-22 11:31:21 +0000 |
641 | +++ tests/unit-tests/graphics/android/test_hwc_display.cpp 2014-05-22 16:51:59 +0000 |
642 | @@ -24,6 +24,7 @@ |
643 | #include "mir_test_doubles/mock_display_report.h" |
644 | #include "mir_test_doubles/stub_renderable.h" |
645 | #include "mir_test_doubles/mock_egl.h" |
646 | +#include "mir_test_doubles/mock_gl.h" |
647 | #include "mir/graphics/android/mir_native_window.h" |
648 | #include "mir_test_doubles/stub_driver_interpreter.h" |
649 | #include "mir_test_doubles/stub_display_buffer.h" |
650 | @@ -103,6 +104,7 @@ |
651 | } |
652 | |
653 | testing::NiceMock<mtd::MockEGL> mock_egl; |
654 | + testing::NiceMock<mtd::MockGL> mock_gl; |
655 | mtd::StubGLProgramFactory stub_program_factory; |
656 | |
657 | int visual_id; |
658 | |
659 | === renamed file 'tests/unit-tests/graphics/android/test_overlay_compositor.cpp' => 'tests/unit-tests/graphics/android/test_hwc_fallback_gl_renderer.cpp' |
660 | --- tests/unit-tests/graphics/android/test_overlay_compositor.cpp 2014-04-24 20:07:20 +0000 |
661 | +++ tests/unit-tests/graphics/android/test_hwc_fallback_gl_renderer.cpp 2014-05-22 16:51:59 +0000 |
662 | @@ -16,18 +16,30 @@ |
663 | * Authored by: Kevin DuBois <kevin.dubois@canonical.com> |
664 | */ |
665 | |
666 | -#include "src/platform/graphics/android/overlay_gl_compositor.h" |
667 | +#include "src/platform/graphics/android/hwc_fallback_gl_renderer.h" |
668 | #include "mir/graphics/gl_context.h" |
669 | #include "mir/graphics/gl_program_factory.h" |
670 | +#include "mir/graphics/gl_primitive.h" |
671 | +#include "mir/graphics/gl_texture.h" |
672 | #include "mir_test_doubles/mock_gl.h" |
673 | +#include "mir_test_doubles/mock_egl.h" |
674 | +#include "mir_test_doubles/stub_renderable.h" |
675 | +#include "mir_test_doubles/mock_swapping_gl_context.h" |
676 | +#include "mir_test_doubles/stub_gl_program.h" |
677 | #include <gtest/gtest.h> |
678 | #include <mir_test/gmock_fixes.h> |
679 | |
680 | +#define GLM_FORCE_RADIANS |
681 | +#define GLM_PRECISION_MEDIUMP_FLOAT |
682 | +#include <glm/glm.hpp> |
683 | +#include <glm/gtc/matrix_transform.hpp> |
684 | +#include <glm/gtc/type_ptr.hpp> |
685 | + |
686 | namespace mg=mir::graphics; |
687 | namespace mga=mir::graphics::android; |
688 | namespace mt=mir::test; |
689 | namespace mtd=mir::test::doubles; |
690 | - |
691 | +namespace geom=mir::geometry; |
692 | namespace |
693 | { |
694 | |
695 | @@ -36,6 +48,7 @@ |
696 | public: |
697 | MOCK_CONST_METHOD2(create_gl_program, |
698 | std::unique_ptr<mg::GLProgram>(std::string const&, std::string const&)); |
699 | + MOCK_CONST_METHOD0(create_texture_cache, std::unique_ptr<mg::GLTextureCache>()); |
700 | }; |
701 | |
702 | class MockContext : public mg::GLContext |
703 | @@ -45,23 +58,258 @@ |
704 | MOCK_CONST_METHOD0(release_current, void()); |
705 | }; |
706 | |
707 | -class OverlayCompositor : public ::testing::Test |
708 | +struct MockTextureCache : public mg::GLTextureCache |
709 | +{ |
710 | + MockTextureCache() |
711 | + { |
712 | + ON_CALL(*this, load(testing::_)) |
713 | + .WillByDefault(testing::Return(std::make_shared<mg::GLTexture>())); |
714 | + } |
715 | + MOCK_METHOD1(load, std::shared_ptr<mg::GLTexture>(mg::Renderable const&)); |
716 | + MOCK_METHOD0(invalidate, void()); |
717 | + MOCK_METHOD0(drop_unused, void()); |
718 | +}; |
719 | + |
720 | +class StubTextureCache : public mg::GLTextureCache |
721 | +{ |
722 | + std::shared_ptr<mg::GLTexture> load(mg::Renderable const&) |
723 | + { |
724 | + return std::make_shared<mg::GLTexture>(); |
725 | + } |
726 | + void invalidate() |
727 | + { |
728 | + } |
729 | + void drop_unused() |
730 | + { |
731 | + } |
732 | +}; |
733 | + |
734 | +class HWCFallbackGLRenderer : public ::testing::Test |
735 | { |
736 | public: |
737 | + HWCFallbackGLRenderer() |
738 | + { |
739 | + using namespace testing; |
740 | + ON_CALL(mock_gl_program_factory,create_gl_program(_,_)) |
741 | + .WillByDefault(Invoke([](std::string const, std::string const) |
742 | + { return std::unique_ptr<mg::GLProgram>(new mtd::StubGLProgram); })); |
743 | + ON_CALL(mock_gl_program_factory,create_texture_cache()) |
744 | + .WillByDefault(Invoke([]() |
745 | + { return std::unique_ptr<mg::GLTextureCache>(new StubTextureCache); })); |
746 | + |
747 | + ON_CALL(mock_gl, glGetShaderiv(_,_,_)) |
748 | + .WillByDefault(SetArgPointee<2>(GL_TRUE)); |
749 | + ON_CALL(mock_gl, glGetProgramiv(_,_,_)) |
750 | + .WillByDefault(SetArgPointee<2>(GL_TRUE)); |
751 | + ON_CALL(mock_gl, glGetUniformLocation(_, StrEq("display_transform"))) |
752 | + .WillByDefault(Return(display_transform_uniform_loc)); |
753 | + ON_CALL(mock_gl, glGetUniformLocation(_, StrEq("tex"))) |
754 | + .WillByDefault(Return(tex_uniform_loc)); |
755 | + ON_CALL(mock_gl, glGetAttribLocation(_, StrEq("position"))) |
756 | + .WillByDefault(Return(position_attr_loc)); |
757 | + ON_CALL(mock_gl, glGetAttribLocation(_, StrEq("texcoord"))) |
758 | + .WillByDefault(Return(texcoord_attr_loc)); |
759 | + ON_CALL(mock_gl, glGenTextures(1,_)) |
760 | + .WillByDefault(SetArgPointee<1>(texid)); |
761 | + } |
762 | + |
763 | + GLint const display_transform_uniform_loc{1}; |
764 | + GLint const position_attr_loc{2}; |
765 | + GLint const texcoord_attr_loc{3}; |
766 | + GLint const tex_uniform_loc{4}; |
767 | + GLint const texid{5}; |
768 | + size_t const stride{sizeof(mg::GLVertex)}; |
769 | + |
770 | testing::NiceMock<MockGLProgramFactory> mock_gl_program_factory; |
771 | testing::NiceMock<MockContext> mock_context; |
772 | testing::NiceMock<mtd::MockGL> mock_gl; |
773 | + testing::NiceMock<mtd::MockEGL> mock_egl; |
774 | + geom::Rectangle dummy_screen_pos{geom::Point{0,0}, geom::Size{500,400}}; |
775 | }; |
776 | - |
777 | } |
778 | |
779 | -TEST_F(OverlayCompositor, compiles_in_constructor) |
780 | +TEST_F(HWCFallbackGLRenderer, compiles_and_sets_up_gl_program) |
781 | { |
782 | using namespace testing; |
783 | InSequence seq; |
784 | EXPECT_CALL(mock_context, make_current()); |
785 | EXPECT_CALL(mock_gl_program_factory, create_gl_program(_,_)); |
786 | + EXPECT_CALL(mock_gl, glUseProgram(_)); |
787 | + EXPECT_CALL(mock_gl, glGetUniformLocation(_, StrEq("display_transform"))); |
788 | + EXPECT_CALL(mock_gl, glGetAttribLocation(_, StrEq("position"))); |
789 | + EXPECT_CALL(mock_gl, glGetAttribLocation(_, StrEq("texcoord"))); |
790 | + EXPECT_CALL(mock_gl, glGetUniformLocation(_, StrEq("tex"))); |
791 | + EXPECT_CALL(mock_gl, glUniform1i(tex_uniform_loc, 0)); |
792 | + EXPECT_CALL(mock_gl, glUseProgram(0)); |
793 | EXPECT_CALL(mock_context, release_current()); |
794 | |
795 | - mga::OverlayGLProgram glprogram(mock_gl_program_factory, mock_context); |
796 | + mga::HWCFallbackGLRenderer glprogram(mock_gl_program_factory, mock_context, dummy_screen_pos); |
797 | +} |
798 | + |
799 | +MATCHER_P(Matches4x4Matrix, value, "matches expected 4x4 matrix") |
800 | +{ |
801 | + for(auto i=0; i < 16; i++) |
802 | + EXPECT_THAT(arg[i], testing::FloatEq(value[i])); |
803 | + return !(::testing::Test::HasFailure()); |
804 | +} |
805 | + |
806 | +TEST_F(HWCFallbackGLRenderer, sets_up_orthographic_matrix_based_on_screen_size) |
807 | +{ |
808 | + using namespace testing; |
809 | + geom::Size sz{800,600}; |
810 | + geom::Point pt{100,200}; |
811 | + geom::Rectangle screen_pos{pt, sz}; |
812 | + float inv_w = 2.0/sz.width.as_int(); |
813 | + float inv_h = 2.0/sz.height.as_int() * -1.0; |
814 | + |
815 | + float expected_matrix[]{ |
816 | + inv_w, 0.0 , 0.0, 0.0, |
817 | + 0.0 , inv_h , 0.0, 0.0, |
818 | + 0.0 , 0.0 , 1.0, 0.0, |
819 | + -1.0 , 1.0 , 0.0, 1.0 |
820 | + }; |
821 | + |
822 | + EXPECT_CALL(mock_gl, glUniformMatrix4fv( |
823 | + display_transform_uniform_loc, 1, GL_FALSE, Matches4x4Matrix(expected_matrix))); |
824 | + |
825 | + mga::HWCFallbackGLRenderer glprogram(mock_gl_program_factory, mock_context, screen_pos); |
826 | +} |
827 | + |
828 | +struct Vertex |
829 | +{ |
830 | + float x; |
831 | + float y; |
832 | +}; |
833 | + |
834 | +Vertex to_vertex(geom::Point const& pos) |
835 | +{ |
836 | + return { |
837 | + static_cast<float>(pos.x.as_int()), |
838 | + static_cast<float>(pos.y.as_int()) |
839 | + }; |
840 | +} |
841 | + |
842 | +MATCHER_P2(MatchesVertices, vertices, stride, "matches vertices") |
843 | +{ |
844 | + auto arg_vertices = static_cast<char const*>(arg); |
845 | + for(auto const& vert : vertices) |
846 | + { |
847 | + GLfloat *f = (GLfloat*) arg_vertices; |
848 | + EXPECT_THAT(f[0], testing::FloatEq(vert.x)); |
849 | + EXPECT_THAT(f[1], testing::FloatEq(vert.y)); |
850 | + arg_vertices+=stride; |
851 | + } |
852 | + return !(::testing::Test::HasFailure()); |
853 | +} |
854 | + |
855 | +TEST_F(HWCFallbackGLRenderer, computes_vertex_coordinates_correctly) |
856 | +{ |
857 | + using namespace testing; |
858 | + NiceMock<mtd::MockSwappingGLContext> mock_context_s; |
859 | + geom::Rectangle rect1{{100,200},{50, 60}}; |
860 | + geom::Rectangle rect2{{150,250},{150, 90}}; |
861 | + |
862 | + mg::RenderableList renderlist{ |
863 | + std::make_shared<mtd::StubRenderable>(rect1), |
864 | + std::make_shared<mtd::StubRenderable>(rect2) |
865 | + }; |
866 | + |
867 | + std::vector<Vertex> expected_vertices1 { |
868 | + to_vertex(rect1.top_left), |
869 | + to_vertex(rect1.bottom_left()), |
870 | + to_vertex(rect1.top_right()), |
871 | + to_vertex(rect1.bottom_right()), |
872 | + }; |
873 | + std::vector<Vertex> expected_vertices2 { |
874 | + to_vertex(rect2.top_left), |
875 | + to_vertex(rect2.bottom_left()), |
876 | + to_vertex(rect2.top_right()), |
877 | + to_vertex(rect2.bottom_right()), |
878 | + }; |
879 | + |
880 | + InSequence seq; |
881 | + EXPECT_CALL(mock_gl, glVertexAttribPointer( |
882 | + position_attr_loc, 3, GL_FLOAT, GL_FALSE, stride, MatchesVertices(expected_vertices1, stride))); |
883 | + EXPECT_CALL(mock_gl, glVertexAttribPointer(_,_,_,_,_,_)) |
884 | + .Times(1); |
885 | + EXPECT_CALL(mock_gl, glVertexAttribPointer( |
886 | + position_attr_loc, 3, GL_FLOAT, GL_FALSE, stride, MatchesVertices(expected_vertices2, stride))); |
887 | + EXPECT_CALL(mock_gl, glVertexAttribPointer(_,_,_,_,_,_)) |
888 | + .Times(1); |
889 | + |
890 | + mga::HWCFallbackGLRenderer glprogram(mock_gl_program_factory, mock_context, dummy_screen_pos); |
891 | + glprogram.render(renderlist, mock_context_s); |
892 | +} |
893 | + |
894 | +TEST_F(HWCFallbackGLRenderer, computes_texture_coordinates_correctly) |
895 | +{ |
896 | + using namespace testing; |
897 | + NiceMock<mtd::MockSwappingGLContext> mock_context_s; |
898 | + geom::Rectangle rect1{{100,200},{50, 60}}; |
899 | + geom::Rectangle rect2{{150,250},{150, 90}}; |
900 | + |
901 | + mg::RenderableList renderlist{ |
902 | + std::make_shared<mtd::StubRenderable>(rect1), |
903 | + std::make_shared<mtd::StubRenderable>(rect2) |
904 | + }; |
905 | + |
906 | + std::vector<Vertex> expected_texcoord { |
907 | + {0.0f, 0.0f}, |
908 | + {0.0f, 1.0f}, |
909 | + {1.0f, 0.0f}, |
910 | + {1.0f, 1.0f} |
911 | + }; |
912 | + |
913 | + EXPECT_CALL(mock_gl, glVertexAttribPointer(_,_,_,_,_,_)).Times(AnyNumber()); |
914 | + EXPECT_CALL(mock_gl, glVertexAttribPointer( |
915 | + texcoord_attr_loc, 2, GL_FLOAT, GL_FALSE, stride, MatchesVertices(expected_texcoord, stride))) |
916 | + .Times(2); |
917 | + |
918 | + mga::HWCFallbackGLRenderer glprogram(mock_gl_program_factory, mock_context, dummy_screen_pos); |
919 | + glprogram.render(renderlist, mock_context_s); |
920 | +} |
921 | + |
922 | +TEST_F(HWCFallbackGLRenderer, executes_render_in_sequence) |
923 | +{ |
924 | + using namespace testing; |
925 | + NiceMock<mtd::MockSwappingGLContext> mock_context_s; |
926 | + auto renderable1 = std::make_shared<mtd::StubRenderable>(); |
927 | + auto renderable2 = std::make_shared<mtd::StubRenderable>(); |
928 | + mg::RenderableList renderlist{ renderable1, renderable2 }; |
929 | + |
930 | + std::unique_ptr<MockTextureCache> mock_texture_cache(new MockTextureCache); |
931 | + { |
932 | + InSequence seq; |
933 | + EXPECT_CALL(*mock_texture_cache, load(Ref(*renderable1))); |
934 | + EXPECT_CALL(*mock_texture_cache, load(Ref(*renderable2))); |
935 | + EXPECT_CALL(*mock_texture_cache, drop_unused()); |
936 | + } |
937 | + ON_CALL(mock_gl_program_factory,create_texture_cache()) |
938 | + .WillByDefault(Invoke([&](){ |
939 | + return std::move(mock_texture_cache); |
940 | + })); |
941 | + |
942 | + mga::HWCFallbackGLRenderer glprogram(mock_gl_program_factory, mock_context, dummy_screen_pos); |
943 | + |
944 | + InSequence seq; |
945 | + EXPECT_CALL(mock_gl, glUseProgram(_)); |
946 | + EXPECT_CALL(mock_gl, glClearColor(FloatEq(0.0), FloatEq(0.0), FloatEq(0.0), FloatEq(1.0))); |
947 | + EXPECT_CALL(mock_gl, glClear(GL_COLOR_BUFFER_BIT)); |
948 | + EXPECT_CALL(mock_gl, glEnableVertexAttribArray(position_attr_loc)); |
949 | + EXPECT_CALL(mock_gl, glEnableVertexAttribArray(texcoord_attr_loc)); |
950 | + |
951 | + EXPECT_CALL(mock_gl, glVertexAttribPointer(position_attr_loc, 3, GL_FLOAT, GL_FALSE, _, _)); |
952 | + EXPECT_CALL(mock_gl, glVertexAttribPointer(texcoord_attr_loc, 2, GL_FLOAT, GL_FALSE, _, _)); |
953 | + EXPECT_CALL(mock_gl, glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); |
954 | + |
955 | + EXPECT_CALL(mock_gl, glVertexAttribPointer(position_attr_loc, 3, GL_FLOAT, GL_FALSE, _, _)); |
956 | + EXPECT_CALL(mock_gl, glVertexAttribPointer(texcoord_attr_loc, 2, GL_FLOAT, GL_FALSE, _, _)); |
957 | + EXPECT_CALL(mock_gl, glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); |
958 | + |
959 | + EXPECT_CALL(mock_gl, glDisableVertexAttribArray(texcoord_attr_loc)); |
960 | + EXPECT_CALL(mock_gl, glDisableVertexAttribArray(position_attr_loc)); |
961 | + EXPECT_CALL(mock_context_s, swap_buffers()); |
962 | + EXPECT_CALL(mock_gl, glUseProgram(0)); |
963 | + |
964 | + glprogram.render(renderlist, mock_context_s); |
965 | } |
966 | |
967 | === modified file 'tests/unit-tests/graphics/android/test_hwc_fb_device.cpp' |
968 | --- tests/unit-tests/graphics/android/test_hwc_fb_device.cpp 2014-05-21 17:18:51 +0000 |
969 | +++ tests/unit-tests/graphics/android/test_hwc_fb_device.cpp 2014-05-22 16:51:59 +0000 |
970 | @@ -30,7 +30,7 @@ |
971 | #include "mir_test_doubles/mock_hwc_device_wrapper.h" |
972 | #include "mir_test_doubles/stub_renderable_list_compositor.h" |
973 | #include "mir_test_doubles/mock_renderable_list_compositor.h" |
974 | -#include "src/platform/graphics/android/overlay_gl_compositor.h" |
975 | +#include "src/platform/graphics/android/hwc_fallback_gl_renderer.h" |
976 | #include "hwc_struct_helpers.h" |
977 | #include <gtest/gtest.h> |
978 | #include <stdexcept> |
979 | |
980 | === modified file 'tests/unit-tests/graphics/android/test_output_builder.cpp' |
981 | --- tests/unit-tests/graphics/android/test_output_builder.cpp 2014-05-07 02:56:33 +0000 |
982 | +++ tests/unit-tests/graphics/android/test_output_builder.cpp 2014-05-22 16:51:59 +0000 |
983 | @@ -28,6 +28,7 @@ |
984 | #include "mir_test_doubles/mock_android_hw.h" |
985 | #include "mir_test_doubles/mock_fb_hal_device.h" |
986 | #include "mir_test_doubles/mock_egl.h" |
987 | +#include "mir_test_doubles/mock_gl.h" |
988 | #include "mir_test_doubles/mock_android_native_buffer.h" |
989 | #include "mir_test_doubles/stub_gl_config.h" |
990 | #include "mir_test_doubles/stub_gl_program_factory.h" |
991 | @@ -98,6 +99,7 @@ |
992 | } |
993 | |
994 | testing::NiceMock<mtd::MockEGL> mock_egl; |
995 | + testing::NiceMock<mtd::MockGL> mock_gl; |
996 | testing::NiceMock<mtd::HardwareAccessMock> hw_access_mock; |
997 | testing::NiceMock<mtd::MockFBHalDevice> fb_hal_mock; |
998 | std::shared_ptr<MockResourceFactory> mock_resource_factory; |
FAILED: Continuous integration, rev:1582 jenkins. qa.ubuntu. com/job/ mir-team- mir-development -branch- ci/1403/ jenkins. qa.ubuntu. com/job/ mir-android- trusty- i386-build/ 1707 jenkins. qa.ubuntu. com/job/ mir-clang- trusty- amd64-build/ 1705 jenkins. qa.ubuntu. com/job/ mir-mediumtests -trusty- touch/1280/ console jenkins. qa.ubuntu. com/job/ mir-team- mir-development -branch- trusty- amd64-ci/ 1135 jenkins. qa.ubuntu. com/job/ mir-team- mir-development -branch- trusty- amd64-ci/ 1135/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ mir-team- mir-development -branch- trusty- armhf-ci/ 1140/console jenkins. qa.ubuntu. com/job/ mir-mediumtests -builder- trusty- armhf/1283/ console
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/mir- team-mir- development- branch- ci/1403/ rebuild
http://