Re: [waffle] [PATCH 0/7] nacl backend implementation

2015-02-04 Thread Tapani Pälli



On 02/03/2015 10:07 PM, Chad Versace wrote:

On 01/30/2015 02:33 AM, Tapani Pälli wrote:

Hi;

As a Finn I interpret silence as 'yes' :)


A safe assumption in many open source cultures :)


So I started to hack on swap completion event support. I believe it
can be useful for other backends also since then application can
throttle rendering and receive information on swaps.

I made early hacky prototype that fixes the issues I've seen with
nacl backend:
http://cgit.freedesktop.org/~tpalli/waffle/log/?h=hacky

I have a few questions on implementation details for the
'waffle_swap_complete'. This is my proposal for the API:

typedef void (*waffle_swapbuffers_cb) (struct waffle_window *);

bool waffle_set_swap_complete_handler(waffle_swapbuffers_cb func);
(would fail if backend does not support this)

Optionally we could put timestamp there also as callback data but I'm
not sure what format is preferred for that. Any ideas here would be
good. I'm not sure the OML triple (ust, msc, sbc) like in
GLX_INTEL_swap_event make sense or should it be something simpler?


We shouldn't return timestamp information. Some Waffle platforms do not
provide that information. And for some that do, like GLX_INTEL_swap_event,
the OML triple is often lie. For example, NVidia hardware doesn't monitor
usr, msc, sbc because it requires an interrupt to detect. I think the same is 
true
for recent Intel GPUs too, but I'm not sure.

For Waffle to return an accurate OML triple, the compositor must provide that
information to Waffle. But, this opens up a can of worms. What exactly indicates
swap buffer completion? When the compositor client's GL command stream has 
completed execution?
When the compositor's GL command stream for compositing the client buffer has 
completed
execution? When the compositor has scheduled a post to display that will present
the client's back buffer? When the display hardware has completed the requested
presentation? Argh!!! How do you choose?!?!


Right, it seems quite a problematic api as a whole.


The sad state of the world is, if you choose one of the above to mean
completion of swap buffers, Waffle will be able to query the chosen
completion timestamps on only a proper subset, possibly empty, of Waffle's
supported platforms. No choice is supported on all display systems.


I agree and simple callback is enough for nacl which seems the only user 
for now.



Then, whenever waffle_wndow_swap_buffers(window) gets called, backend
will call callback if it is set. It should be noted that it can
happen from a separate thread.

How does this sound?


It seems that two solutions are available:

   S1. Provide waffle_set_swap_buffers_callback().

   S2. On Waffle's NaCl backend, implement waffle_swap_buffers() to block
   until the back buffer has been composited onto the web page. (I believe
   this is possible to implement without a worker thread).


I guess it is possible but not without introducing extra 
latency/slowness for the application thread which I was trying to avoid. 
Ideally app could continue doing something else while swap goes on.



Let's analyze both solutions, keeping in mind two obstacles:

   O1. In NaCl, it is illegal to render to the default framebuffer until
PPB_Graphics3D::SwapBuffers invokes its callback.

   O2. If a NaCl app blocks on the main thread, the UI becomes unresponsive.

Waffle's API must protect against O1. Corrupt rendering is unacceptable.

Case !O2
=
Suppose that we don't care about O2. Let the UI hang. Then the simplest
solution is S2. Let waffle_window_swap_buffers() block. Then we don't have
to worry about the semantics of a waffle_window_swap_buffers_callback on
the different platforms.


I will spend some time prototyping this blocking case to have a stronger 
opinion.



Case O2
===
Suppose now that we do care about O2. Perhaps we care because we want to
write an interactive GL testcase. Then Waffle's API must provide enough
machinery to allow the application to avoid blocking on the main thread,
and that machinery should be as simple as possible.

Subcase O2 + S2
---
If we choose solution 2, then the testcase/app will need to delegate
waffle_window_swap_buffers() to a child presentation thread. The app will 
need to
implement its own cross-thread synchronization between the main thread and
the presentation thread.

For a small testcase of demo app, requiring the user to implement this
synchronization feels like overkill. Real NaCl games must use a
separate rendering and presentation threads anyway if they do
non-trivial rendering. However, I don't believe real games are not Waffle's
concern. Waffle is for little apps and testcases.

However, S2 keeps the Waffle API simple and is easy to implement.


I agree simple sounds good. IMO Waffle has a good chance to be a porting 
layer for a bigger application too, overall porting effort feels quite 
small.



Subcase O2 + S1
---
If we choose solution 1, the 

Re: [waffle] [RFC] waffle: support for swap completion callback

2015-02-04 Thread Emil Velikov
On 4 February 2015 at 06:20, Tapani Pälli tapani.pa...@intel.com wrote:


 On 02/03/2015 07:32 PM, Emil Velikov wrote:

 On 2 February 2015 at 13:08, Tapani Pälli tapani.pa...@intel.com wrote:

 Patch introduces a new API that enables application to register
 a callback to be called when swapbuffers has finished. This can be
 used to throttle rendering loop.

 [...]

 @@ -173,6 +174,9 @@ bool
   waffle_is_extension_in_string(const char *extension_string,
 const char *extension_name);

 +bool
 +waffle_register_swap_callback(waffle_swapbuffers_cb func);
 +

 Perhaps inlining the typedef in there, and wrapping it in
 WAFFLE_API_VERSION (alongside the function prototype) ?


 I put it in separate header so that wcore_platform.h would not need to
 include whole waffle.h but if that feels ok then typedef can be moved
 here.

Hmm good point. I would leave the final decision to Chad, but imho
things will be better if we're compacted.

 Fwiw changing the func prototype to something like the following will
 be more consistent, and less likely to abuse.

 bool
 waffle_window_register_swap_callback(struct waffle_window *window,
 waffle_swapbuffers_cb func);


 This means that callback would be window specific. I think this is ok,
 although then user needs to register callback for each window separately and
 window argument could be removed from the actual callback.

True, and I don't think it can be seen as a problem.

 On the topic of the OML triple (ust, msc, sbc), I cannot really
 comment as I've never had the pleasure.

 diff --git a/src/waffle/api/waffle_gl_misc.c
 b/src/waffle/api/waffle_gl_misc.c
 index 138974d..ac155c0 100644
 --- a/src/waffle/api/waffle_gl_misc.c
 +++ b/src/waffle/api/waffle_gl_misc.c
 @@ -108,3 +108,20 @@ waffle_get_proc_address(const char *name)

   return api_platform-vtbl-get_proc_address(api_platform, name);
   }
 +
 +WAFFLE_API bool
 +waffle_register_swap_callback(waffle_swapbuffers_cb func)
 +{
 +const struct api_object *obj_list[] = {
 +(void*) func,
 +};
 +
 +if (!api_check_entry(obj_list, 1))
 +return false;
 +

 With the struct waffle_window * in you can use it so that one does
 not abuse the API too much :)


 I'm now sure what would be the abuse case?

Maybe misuse is a better word - iirc api_check_entry confirms that
all the objects in obj_list are linked/attached to each other.
Although as you brought it up I'm not sure how it works when there is
only a single object.

-Emil
___
waffle mailing list
waffle@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/waffle


Re: [waffle] [PATCH] wflinfo: Fix MSVC compilation error.

2015-02-04 Thread Jose Fonseca

On 30/01/15 22:21, Emil Velikov wrote:

On 30/01/15 20:02, Jose Fonseca wrote:

On 30/01/15 16:25, Emil Velikov wrote:

On 30 January 2015 at 11:07, Jose Fonseca jfons...@vmware.com wrote:

Workaround what seems to be a bug in MSVC parser for C99.

https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.freedesktop.org_archives_waffle_2015-2DJanuary_000975.htmld=AwIBaQc=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw-YihVMNtXt-uEsr=zfmBZnnVGHeYde45pMKNnVyzeaZbdIqVLprmZCM2zzEm=EOTSIhn-7yCkuKuQ-JCDhS7EtrWFaozBDxo228XaWsos=0Bi5_OB7Grl7-w1RO8R0l0YtCyi9IkRu-lB9Jtt7Onoe=


Should have spotted this a Frank sent out the patch. Sorry about this
Jose.
Reviewed-by: Emil Velikov emil.l.veli...@gmail.com

Wondering if we should (as a follow up commit) move the variable
declarations prior to the code to avoid such fun in the future ?


It's hard to say.

It looks like MSVC allows declarations in the middle of blocks, but the
parser gets into a wierd state some times.


 From my earlier experience this issue happens as the variable type is a
typedef or a struct. For simple types such as int, float, etc. I've not
seen such problems. Or was it when the declaration is initialised
(with/wo a designated initializer) ?


I think the surer way long term would be to report the MSVC bug to
Microsoft.  There have been positive experiences in the past [1] [2]


Good point. I'll put it on my list but I don't even have an live/msdn
account :\ I'm not sure when I'll get around to creating one, so if
anyone is interested the following mock-up should be able to visualise
the problem(s).


#include stdio.h
#include stdlib.h

struct foo {
int i;
};

typedef int bar;

int
main(void)
{
struct foo foo1 = { .i = 1 };
printf(foo1 %d\n, foo1.i);
// ^^
// The preprocessor/compiler will throw an error here.

struct foo foo2 = { .i = 2 };
printf(foo2 %d\n, foo2.i);
// ^^
// The preprocessor/compiler will throw an error here.

bar bar1 = 1;
printf(bar1 %d\n, bar1);

return 0;
}


Cheers,
Emil


Thanks for isolating a test case Emil.

I have good news: MSVC 2013 Update 4 seems to have fixed the issue, so 
we don't need to file a bug after all.


Given that waffle requires C99, it basically requires MSVC 2013.  And 
given that MSVC 2013 U4 is a free update it seems acceptable to require 
it too.  (This is what I'm proposing for piglit too BTW)



Jose
___
waffle mailing list
waffle@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/waffle