--
You received this message because you are subscribed to the Google Groups "Graphics" group.
To unsubscribe from this group and stop receiving emails from it, send an email to graphics+u...@isocpp.org.
To post to this group, send email to grap...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/graphics/.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/graphics/1393790c-ae1d-4248-9a6f-108d9747efc2%40isocpp.org.
VV> > And you don't give any other good reasons for not creating a good
VV> > platform-independent drawing API, whereas there are several obvious
VV> > advantages to doing it.
VV>
VV> I do not see which part of the planned 2-d API is not platform-independent,
VV> and I don't know which parts of it are "not good".
We can go into the latter in details if there is any chance of something
useful coming out of it, but I don't know if it's really worth doing it
now, is it? As a broad hint, I'd say that just about everything font/text-
related in Cairo is, if not "not good", then at least "not great".
VV> > I hope the entire approach can be reconsidered and IMO it would be better
VV> > to not have any standard graphics API than to standardize on Cairo. As great
VV>
VV> The plan of SG13 is not to standardize Cairo. The plan is to standardize an
VV> API that can use Cairo, or GDI+, or CoreGraphics, underneath.
I realize this, thanks. However I also realize -- and thought that so did
everyone else, sorry for not making it explicit -- that standardizing on
Cairo API would make all possible implementations
1. Limited to only the features supported by Cairo.
2. Less than optimally efficient for those not using Cairo itself.
And I think that creating a new API is the only way to avoid these
problems.
My current thinking about this proposal is "well at least there is now a starting point".Here are some remarks/questions:
1. About "Usage of Shared Ownership Semantics":Did you explore the additional possibility of just not implying any kind of copy or sharing semantic at all for these types?
Taking your example:
X x1;
auto x2 = x1; // compilation error: copy is forbidden
Thus letting the user to define when, where and how to share these objects if at any moment it is proven necessary?
I suspect that hiding the sharing without providing a separate type for sharing (like future/shared_future) might give the wrong assumptions to user,
like that he can use these objects from different threads safely with minimal issues.
I feel that if sharing of some of these objects is necessary, it should be the user that setup the sharing mechanism specific to his/her use case and constraints.
That being said, that's just a feeling so I'm wondering.
2. I do agree that starting with Cairo provide a necessary starting point. I do not agree that the current proposal is complete or good enough to
fill the need. One thing that highly bother me is that the result of the mechanical transformation really lack any use of C++ idioms, which
are historically avoided by most graphic apis except the ones from very recent frameworks.
Basically, I feel that from this proposal, there is a need for a lot of manual modifications to match something useful for C++ programmers.
This is not an argument though, I'm still looking at the details to see why I don't feel comfortable with the result of the transformation in details.
3. Am I correct that in the current state of this proposal, the user can draw something in a surface, but can't do anything with that surface afterward?
The only thing I see is "write to png" function but there is no way to access the raw data to exploit the surface content.
Maybe something like write_to_buffer() would help? or provide direct access like a vector.data()?
4. That pose the question of the basic units used in Cairo. I see int double etc. but no definition of what is a pixel.
I suppose that there is a lot of work to do there.
5. I suggest removing "user data", or is there a reason to keep it?
1. About "Usage of Shared Ownership Semantics":Did you explore the additional possibility of just not implying any kind of copy or sharing semantic at all for these types?
Taking your example:
X x1;
auto x2 = x1; // compilation error: copy is forbidden
Thus letting the user to define when, where and how to share these objects if at any moment it is proven necessary?
I suspect that hiding the sharing without providing a separate type for sharing (like future/shared_future) might give the wrong assumptions to user,
like that he can use these objects from different threads safely with minimal issues.
I feel that if sharing of some of these objects is necessary, it should be the user that setup the sharing mechanism specific to his/her use case and constraints.
That being said, that's just a feeling so I'm wondering.I think what you are describing is reference semantics. We do discuss that. The decision to go with shared ownership semantics was the most contentious design decision. The final decision was to stick with shared ownership semantics for the initial publication but to fully expect a vigorous discussion on the topic when we present it in Issaquah. I like shared ownership semantics here and will do my best to make the case that they are the best choice, but I will not be surprised if the consensus is for reference semantics instead. The only thing that would surprise me would be a decision for value semantics because of the problems discussed in the proposal.
Thanks for the feedback, everyone!
Just to add to what Michael has said, the proposal is trying to follow the committee’s guidance from the Chicago meeting summarized in N3791, including first to “start somewhere” with a known starting point to minimize design-by-committee while getting started, and then fix/improve it iteratively as much as needed. And N3888 isn’t “finished” even as a starting point, but it’s to start getting some initial concrete committee feedback at our next meeting; even if the feedback is positive, the best case would be a list of changes to make to the proposal to iterate on in subsequent revisions for future meetings with further changes. It’s early days yet; we’re still working on getting started.
But perhaps most importantly, let me emphasize the two major ways to participate: by giving feedback to help shape and refine existing proposals like N3888, and/or by writing your own competing proposal if you feel a major change or different direction is needed – both are welcome and encouraged.
In WG21 and similar groups, we frequently quote the saying: “Nothing in ISO happens without a proposal.” The committee can’t consider/evaluate general ideas, only actual concrete proposals. So in addition to giving feedback to improve this particular proposal, I would explicitly like to encourage anyone who thinks they know of a different/better approach to write a similar proposal to show their approach in a similar level of detail so we can consider them side by side. Disclaimer: I realize that this is asking for serious work – as with Michael’s proposal, you should realize that developing such a proposal will probably take at least person-weeks of time to come up with initial version to start discussion, with no guarantee that the committee will ever like it, and ultimately at least person-months if eventually successful. Also, it is formally optional but pragmatically highly desirable to support even an initial proposal with a working reference implementation that can be tried and inspected, as I’m glad to see Michael is working on producing.
We value feedback to refine existing proposals, and we’d love to see new and different proposals too. If you are serious about writing an alternative proposal of your own, ping me privately and I’ll be glad to try to offer helpful guidance as I did with Michael. Thanks,
Herb
2. I do agree that starting with Cairo provide a necessary starting point. I do not agree that the current proposal is complete or good enough to
fill the need. One thing that highly bother me is that the result of the mechanical transformation really lack any use of C++ idioms, which
are historically avoided by most graphic apis except the ones from very recent frameworks.
Basically, I feel that from this proposal, there is a need for a lot of manual modifications to match something useful for C++ programmers.
This is not an argument though, I'm still looking at the details to see why I don't feel comfortable with the result of the transformation in details.
I agree that it is not complete. We wanted feedback from the Committee on various issues before we proceeded to add rules that would make more radical changes.
matrix a { 2.0, 0.0, 0.0, 2.0, 0.0, 0.0 };a = { 3.0, 0.0, 0.0, 3.0, 0.0, 0.0 };
constexpr matrix identity_matrix { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }; // <-- part of the APIa = identity_matrix; // usage example
matrix a; // a is identityf(matrix{}); // passing identity to f
matrix make_translation_matrix(double tx, double ty) { return {0.0, 0.0, 0.0, 0.0, tx, ty}; }
distance transform(const distance& d);point transform(const point& p);
--
You received this message because you are subscribed to the Google Groups "Graphics" group.
To unsubscribe from this group and stop receiving emails from it, send an email to graphics+u...@isocpp.org.
To post to this group, send email to grap...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/graphics/.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/graphics/8d7be640-58a4-448d-ba7d-91d6c0f27c6c%40isocpp.org.
You can access it here: http://isocpp.org/blog/2014/01/n3888 .
I used struct for non-PODs in the Technical Specification because that is the style that the Standard uses. I'd much prefer to use class given that that is what the header in the implementation uses for those types. But I stuck to the style of the Standard as best I could because that's what the Committee will expect to see.
Hi Alex, “struct” and “class” have identical meaning for these purposes, and only change the default accessibility of bases and members. It’s a stylistic convention that “struct” be used for aggregates, but only a convention.
Herb
--
You received this message because you are subscribed to the Google Groups "Graphics" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
graphics+u...@isocpp.org.
To post to this group, send email to grap...@isocpp.org.
Visit this group at
http://groups.google.com/a/isocpp.org/group/graphics/.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/graphics/CALX6VwpZxKMwHh0LrB93XBPv9%2BtZaDg6dFUEoM-PcNkFK2XLBA%40mail.gmail.com.
I think what you are describing is reference semantics. We do discuss that.
The decision to go with shared ownership semantics was the most contentious design decision. The final decision was to stick with shared ownership semantics for the initial publication but to fully expect a vigorous discussion on the topic when we present it in Issaquah. I like shared ownership semantics here and will do my best to make the case that they are the best choice, but I will not be surprised if the consensus is for reference semantics instead. The only thing that would surprise me would be a decision for value semantics because of the problems discussed in the proposal.
3. Am I correct that in the current state of this proposal, the user can draw something in a surface, but can't do anything with that surface afterward?
The only thing I see is "write to png" function but there is no way to access the raw data to exploit the surface content.
Maybe something like write_to_buffer() would help? or provide direct access like a vector.data()?You found a bug. Cairo has two functions - cairo_surface_map_to_image and cairo_surface_unmap_image - which should have equivalents in the library but which I overlooked. They will be added.That said, if it is an image_surface, you can access its data using image_surface::get_data and image_surface::set_data. If it is not an image_surface, you can use image_surface(surface&, format, int, int) to create an image surface that matches the surface as closely as possible, create a context for the new image_surface you just created, and then draw the original surface to the new image_surface. The better approach though would be to use image_surface objects from the outset to compose various components of your scene, and then draw them to the display surface using context::set_source_surface, defining a suitable clip region, and then calling context::paint (or using set_source_surface, creating a new path, calling context::rectangle with the appropriate values, then calling context::fill). There are various other ways to do it as well.
In general, directly manipulating a surface's data using CPU-side functions is a really bad idea from a performance point of view. GPUs are massively parallel and bringing them to a halt so that you can start messing with data they own (and the GPU does indeed own the texture data) is going to provide a big perf hit.
4. That pose the question of the basic units used in Cairo. I see int double etc. but no definition of what is a pixel.
I suppose that there is a lot of work to do there.There's not really a lot of work to do there right now. As you said, you saw int and double. This is a simple, 2D drawing API. We don't want users to feel like they need to know or care about what the underlying GPU representation of pixel data is. If you need to drop down to that level of detail, you are probably in the land of platform-specific information and thus in the realm of native handles.
That said, cairo does have a concept of a pixel (in that you can create an image_surface from data, get image surface data, etc.). The "format" enum specifies the pixel formats. See the cairo documentation for cairo_format_t for the meanings of those enumerators.
One of the options we have been discussing is move-only types, and I think they may well turn out to be the right fit here.
Meta: That detail in particular during this exercise has made me really appreciate how much stronger C++11 is in expressing important semantics we couldn’t express directly in C++98 (auto_ptr, anyone?), including for the purpose of wrapping lower-level APIs.
Herb
From: Klaim - Joël Lamotte [mailto:mjk...@gmail.com]
Sent: Tuesday, January 21, 2014 1:15 PM
To: grap...@isocpp.org
Subject: Re: [graphics] Re: N3888 - A Proposal to Add 2D Graphics Rendering and Display to C++
On Tue, Jan 21, 2014 at 7:29 PM, Michael McLaughlin <mike...@gmail.com> wrote:
--
You received this message because you are subscribed to the Google Groups "Graphics" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
graphics+u...@isocpp.org.
To post to this group, send email to grap...@isocpp.org.
Visit this group at
http://groups.google.com/a/isocpp.org/group/graphics/.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/graphics/CAOU91OOeXe5pPrA5g_D0OEdaAP4G4_3nUZiLaLAzmKuGZU8%2BeA%40mail.gmail.com.
I apologize in advance if this is a stupid question, but what sort of licensing issues might this run into? I started to read over the proposal and realized that it would be beneficial to read up on cairo itself. Cairo appears to be licensed under the LGPL or the MPL. As a mechanical transformation, what sort of license would the proposed library have? Would it be considered a derivative work and also be licensed under the LGPL? If one were to do, say, a custom Direct2D/DirectWrite implementation of the new API, would it be considered a derivative and required to be open sourced? Is it possible for someone to understand and use this library without any exposure to cairo? Perhaps I’m just being paranoid here, but, you know, software license terms are something I take seriously and want to avoid even the slightest possibility of violating.
One advantage of a completely new API: this sort of question can be avoided entirely.
From: Michael McLaughlin [mailto:mike...@gmail.com]
Sent: Tuesday, January 21, 2014 9:11 AM
To: grap...@isocpp.org
Subject: Re: [graphics] Re: N3888 - A Proposal to Add 2D Graphics Rendering and Display to C++
This is one of the kinds of feedback that I was hoping for. You've identified a weakness in our Design Decisions sections. When I wrote the part discussing synthesizing a new API, I was unconsciously relying on the reader to be familiar with N3791 - http://isocpp.org/files/papers/n3791.html . This was a mistake on my part and it should have been explicitly cited there and perhaps even briefly summarized. I am not sure if we will publish an update pre-conference (I need to consult my co-authors), but I am going to modify that section to try to address your feedback. So thank you!
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/graphics/CAL_%3DNOo%3Dsa5BtUn9zmST%3Dfa6LYHn4y%3D5G5btRPWDRJcv6xpRZQ%40mail.gmail.com.
I think what you are describing is reference semantics. We do discuss that.Yes and no.The reference semantic you are discussing assumes that the api will impose the use of smart pointersto maintain a shared reference semantic.What I am asking, exactly, is what about move-only types and no assumption about these types being shared at all?The difference is that depending on the use chase, there would be, or not, use of sharing constructs, where needed, and specificto the actual need (for example, one could use a shared pointer that don't have thread safety on copy because the codemanipulating the drawing api will only be running on a specific thread anyway, or other cases that might be unusual).
Said another way: does the sharing-or-not-sharing really have to be part of this api?The decision to go with shared ownership semantics was the most contentious design decision. The final decision was to stick with shared ownership semantics for the initial publication but to fully expect a vigorous discussion on the topic when we present it in Issaquah. I like shared ownership semantics here and will do my best to make the case that they are the best choice, but I will not be surprised if the consensus is for reference semantics instead. The only thing that would surprise me would be a decision for value semantics because of the problems discussed in the proposal.I'm not against shared ownership semantic but I am wondering if it's not a potential issue both in performance and design,where the library is designed for a use case but becomes expensive in another, simply because the sharing costs the same for everyone.
A bit like if we only had boost::shared_ptr smart pointers, no scoped_ptr, no unique_ptr and no other kind of pointers. It don't really fit all the usages.
So do we actually need to pre-define and force the sharing semantic and it's implementation?It's a real question, I mean I don't know the answer at all, in the same way I might have not thought about having shared_future if I was designing the future api.
3. Am I correct that in the current state of this proposal, the user can draw something in a surface, but can't do anything with that surface afterward?
The only thing I see is "write to png" function but there is no way to access the raw data to exploit the surface content.
Maybe something like write_to_buffer() would help? or provide direct access like a vector.data()?You found a bug. Cairo has two functions - cairo_surface_map_to_image and cairo_surface_unmap_image - which should have equivalents in the library but which I overlooked. They will be added.That said, if it is an image_surface, you can access its data using image_surface::get_data and image_surface::set_data. If it is not an image_surface, you can use image_surface(surface&, format, int, int) to create an image surface that matches the surface as closely as possible, create a context for the new image_surface you just created, and then draw the original surface to the new image_surface. The better approach though would be to use image_surface objects from the outset to compose various components of your scene, and then draw them to the display surface using context::set_source_surface, defining a suitable clip region, and then calling context::paint (or using set_source_surface, creating a new path, calling context::rectangle with the appropriate values, then calling context::fill). There are various other ways to do it as well.In general, I was thinking about the systems that will have to actually use the surface. For image_surface, it's ok, it's basically a buffer in the memory accessible to the cpu.
For surface itself, it's less simple. How should a windowing api use a surface?
If my understanding is correct, a windowing api would provide a surface child type or something equivalent, which knows how to report the drawing in the windows.
Is the the way you were imagining the usage?
In general, directly manipulating a surface's data using CPU-side functions is a really bad idea from a performance point of view. GPUs are massively parallel and bringing them to a halt so that you can start messing with data they own (and the GPU does indeed own the texture data) is going to provide a big perf hit.I know about that, but if you want to go in the general case, then we'll explicitely have to separate textures where they are displayed (mesh, screen, memory?), which is why I'm asking
how would other system use the surface.
4. That pose the question of the basic units used in Cairo. I see int double etc. but no definition of what is a pixel.
I suppose that there is a lot of work to do there.There's not really a lot of work to do there right now. As you said, you saw int and double. This is a simple, 2D drawing API. We don't want users to feel like they need to know or care about what the underlying GPU representation of pixel data is. If you need to drop down to that level of detail, you are probably in the land of platform-specific information and thus in the realm of native handles.I strongly disagree.
1. these types are not telling me anything, what is the unit, can I really do all the operations an int can do on that unit without getting unusable values, etc.2. here I have strictly no idea what is a pixel. Is it rgb? cmjn? What's the range of valid values, is it [0,1) ? [0,1]? [0,255]?3. as discussed in another older thread, I see no reason to not use C++14 features that allow us to benefit from types without having any cost at runtime.I guess this part alone would require one or several proposals to get the discussion somewhere.
That said, cairo does have a concept of a pixel (in that you can create an image_surface from data, get image surface data, etc.). The "format" enum specifies the pixel formats. See the cairo documentation for cairo_format_t for the meanings of those enumerators.Could you clarify if the goal is to have an api to draw anything on any kind of surface, or should it be specialized for surfaces immediately visible on a screen and using formats destined to be displayed on that screen?
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/graphics/BLU402-EASDF17D80FC26513A3983FFCDD0A40%40phx.gbl.
No, that's not correct at all - you can derive structs from classes and vice
versa, and the only difference between a struct and a class is the
default access.
To create a context it needs a surface. There are other valid reasons to have access to that surface (e.g. to use it as the source of a surface_pattern that you then draw with using a different context). Move-only types instantly force the API to deal with surfaces through shared_ptr, since otherwise you give up a whole bunch of use cases (in the example above, the first context and the pattern both need to retain that surface; the only solutions I know of to do that are a (horribly dangerous) naked pointer, a shared_ptr, or by giving the surface class shared ownership semantics).
I like shared_ptr. I like that it exists. I like that it's there when needed. I don't like the idea of an API that's littered with shared_ptr parameters because types which should natively have shared ownership semantics instead have move only semantics. Especially since if you mess up with shared_ptr you wind up with a resource that destroys itself while you still think there are outstanding references to it. Shared ownership semantics let you have the nice clean look and feel of value semantics without wasting memory and computing cycles on deep copying GPU resources for no reason and without the risk of early destruction. Yes, patterns that create early destruction are invalid but I see no reason why a beginning programmer should have to try to debug a runtime error that could've been avoided by the library designer.
I'm not against shared ownership semantic but I am wondering if it's not a potential issue both in performance and design,where the library is designed for a use case but becomes expensive in another, simply because the sharing costs the same for everyone.
A bit like if we only had boost::shared_ptr smart pointers, no scoped_ptr, no unique_ptr and no other kind of pointers. It don't really fit all the usages.
So do we actually need to pre-define and force the sharing semantic and it's implementation?It's a real question, I mean I don't know the answer at all, in the same way I might have not thought about having shared_future if I was designing the future api.How is it a performance and design issue? Please describe the use cases where this is a problem. I really want to know because I can't think of any so if there are any I want to be able to address them if possible, and recommend an alternate design if not.
Cairo deals with this with a variety of backends. As does Qt. You seem to be asking me how some generic backend should handle some implementation detail, if I'm understanding you correctly. The answer is that implementations should handle implementation details in the best, most efficient way possible. I am not concerned about the implementation details so long as I know that the things in question are in fact implementable with acceptable performance (I do thanks to cairo, Qt, and other libraries).
I'm sorry but I don't understand what you are asking here. But again it sounds like an implementation detail question and while implementation details are not ignorable since an API that cannot be implemented in a useful way does nobody (except theorists) any good, neither are they of any concern once it's known that the API can be usefully implemented. The existence of cairo attests to this fact, ergo I have not spent time thinking about how various windowing systems might hypothetically implement the API. There are people out there who get paid lots of money to think about that. I am a volunteer. If someone wants to pay me lots of money to think about such things I would be more than happy to hear from them.
I strongly disagree.
1. these types are not telling me anything, what is the unit, can I really do all the operations an int can do on that unit without getting unusable values, etc.2. here I have strictly no idea what is a pixel. Is it rgb? cmjn? What's the range of valid values, is it [0,1) ? [0,1]? [0,255]?3. as discussed in another older thread, I see no reason to not use C++14 features that allow us to benefit from types without having any cost at runtime.I guess this part alone would require one or several proposals to get the discussion somewhere.You are asking questions that are all answered by the cairo API documentation. I told you this in my last reply. You even quoted the sentence where I explain this (just below here). And the proposal states that the semantics are as defined by the cairo API documentation.Image surface formats: http://cairographics.org/manual/cairo-Image-Surfaces.html#cairo-format-t . Values for the solid_color_pattern constructors: http://cairographics.org/manual/cairo-cairo-pattern-t.html#cairo-pattern-create-rgba . I'm sorry but I do not want to waste everyone's time pasting links to every last bit of relevant cairo documentation so you'll need to look this stuff up yourself.
The answer to why there aren't UDLs is the same as the answer I repeatedly gave to Alex's questions: every addition or modification requires one or more additional rules. There are already 7.5 pages of rules. Bonus features like UDLs can come later after the existing rules have been vetted.
The only concrete answer is: We’ve asked ISO, and they will give us direction in the fullness of time. ;) I’ve asked, and it can take time to get an answer.
In general, virtually every standards submission involves some IP, even if it’s just the author’s implicit copyright on his own paper.
In particular, contributions from OSS are reasonably common and so presumably ISO is used to answering these questions.
For those interested in more, see also http://isocpp.org/std, which refers to:
For a general overview of ISO standardization, including the ISO patent and copyright policy, see ISO’s document Participating in International Standardization.
Herb
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/graphics/CAL_%3DNOpqfL8KVqpUFRdF6VmoN_ohnHi0prEiwmzKEbHp9z15zg%40mail.gmail.com.