Merge lp:~mc-return/compiz/compiz.merge-fix1169353-screenshot-needs-color-options into lp:compiz/0.9.10

Proposed by MC Return
Status: Merged
Approved by: Sam Spilsbury
Approved revision: 3662
Merged at revision: 3667
Proposed branch: lp:~mc-return/compiz/compiz.merge-fix1169353-screenshot-needs-color-options
Merge into: lp:compiz/0.9.10
Diff against target: 300 lines (+93/-43)
3 files modified
plugins/screenshot/screenshot.xml.in (+30/-5)
plugins/screenshot/src/screenshot.cpp (+62/-38)
plugins/screenshot/src/screenshot.h (+1/-0)
To merge this branch: bzr merge lp:~mc-return/compiz/compiz.merge-fix1169353-screenshot-needs-color-options
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Sam Spilsbury Approve
MC Return Needs Resubmitting
Review via email: mp+159038@code.launchpad.net

Commit message

*Screenshot, xml:

Better plugin summary.
Added option to disable the drawing of the screenshot
selection indicator.
Added options to change color and opacity of the outline
and the inside of the rectangle indicator, default colors
have not been changed.
Other minor improvements.

*Screenshot, code:

Introduced the new variable bool selectionSizeChanged,
which is true if the size of the selection has changed.

We just want to draw the screenshot selection box, if
we are grabbed, the size has changed and the CCSM
option to draw it is enabled.
Do not render anything if indicator is disabled.

Indicator colors are now configurable.
Increased indicator box outline line width to 2.0.

Only damage the full screen once, if the grab gets
terminated, during grab just damage the region painted,
which is the screenshot selection box (LP: #1172234).

*SCreenshot, cleanup:

Minor cleanup in the rendering code.
Removed redundant #ifndef USE_GLES compiler option,
GLES can cope with enabling and disabling GL_BLEND.
Use prefix- instead of postfix increments.
Declaration and assignment of local variables in one line.
Reduced the scope of the variables x1, y1, x2 and y2.
Replaced magic number 65535.0f with const float MaxUShortFloat =
std::numeric_limits <unsigned short>::max ();.
Indentation fixes.
C++ style for comments, added comments.

(LP: #1169353, LP: #1172234)

To post a comment you must log in.
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Looks mostly good, just a few tips:

115 +#ifndef USE_GLES
116 + glEnable (GL_BLEND);
117 +#endif
147 -#ifndef USE_GLES
148 - glEnable (GL_BLEND);
149 -#endif

Its not necessary to move that as it only needs to be enabled when draw commands are sent to the GPU. So it can stay in the same place.

119 + float alpha = ((float) optionGetFillColorAlpha () / 65535.0f);

This can be replaced with

float alpha = optionGetFillColorAlpha () / static_cast <float> (std::numeric_limits <unsigned short>::max ());

Three things to note with that:
 1. In order to get floating point division, you only need to have the denominator be a float and not the numerator.
 2. std::numeric_limits <unsigned short::max () is the preferable way of saying 65536
 3. static_cast should be preferred over c-style casts (eg (Type));

also:

125 + colorData[3] = alpha * 65535.0f;
becomes

colorData[3] = alpha * std::numeric_limits <unsigned short>::max ();

Finally, there are a few formatting changes scattered around here (though not as much as before). Try to split those two up as much as possible, as the areas where formatting changes were made were not really related to what this change is doing. They're fine to keep though, as they're correct.

Revision history for this message
MC Return (mc-return) wrote :

> Looks mostly good, just a few tips:
>
> 115 +#ifndef USE_GLES
> 116 + glEnable (GL_BLEND);
> 117 +#endif
> 147 -#ifndef USE_GLES
> 148 - glEnable (GL_BLEND);
> 149 -#endif
>
> Its not necessary to move that as it only needs to be enabled when draw
> commands are sent to the GPU. So it can stay in the same place.
>

Question: Do we really need those #ifndefs ?
GLES should have no problem with glEnable (GL_BLEND); and glDisable (GL_BLEND);, no ?

> 119 + float alpha = ((float) optionGetFillColorAlpha () /
> 65535.0f);
>
> This can be replaced with
>
> float alpha = optionGetFillColorAlpha () / static_cast <float>
> (std::numeric_limits <unsigned short>::max ());
>
I removed the redundant (float) casts in r3659.

> Three things to note with that:
> 1. In order to get floating point division, you only need to have the
> denominator be a float and not the numerator.
> 2. std::numeric_limits <unsigned short::max () is the preferable way of
> saying 65536
> 3. static_cast should be preferred over c-style casts (eg (Type));
>

2. AFAIK an unsigned short can have a different size, depending on the
hardware.
I am not convinced this is the best way to say 65535...

Maybe we can find another way ? (see the Ezoom MP also)

>
> Finally, there are a few formatting changes scattered around here (though not
> as much as before). Try to split those two up as much as possible, as the
> areas where formatting changes were made were not really related to what this
> change is doing. They're fine to keep though, as they're correct.

Yeah, sorry about that (again) - but it will get better each time we touch a
specific file.
Once most stuff has been cleaned up, it won't get cleaned up again ;)

Revision history for this message
MC Return (mc-return) :
review: Needs Information
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

The ifndefs are not necessary for enabling the blend state. Its a side effect of when Travis had turned on blend full-time, but we decided to revert that change because while it was certainly convenient, it had some performance implications and there are also some situations where blending is not desired.

short unsigned int basically going to be 16 bits on every architecture we care about. If we start caring about really exotic hardware then maybe that will need to change, but I don't imagine its the case now.

65535 is a lot easier to typo if you have it everywhere.

Revision history for this message
MC Return (mc-return) wrote :

Grmpf, during testing I found out that damage handling is also broken, I filed bug #1172234 about it.
This should be pretty easy to fix, so I'll do it here...

I still have a minor blending problem to fix, if you have a tip how to fix the
the-screenshot-selection-overlay-is-visible-on-screenshots-if-fbos-are-enabled
please shout out loud in the meantime... ;)

review: Needs Information
Revision history for this message
MC Return (mc-return) wrote :

Okay, all fixed now, except the
the-screenshot-selection-overlay-is-visible-on-screenshots-if-fbos-are-enabled issue...

The rest works perfectly now - had to fix some additional issues, please see
http://bazaar.launchpad.net/~mc-return/compiz/compiz.merge-fix1169353-screenshot-needs-color-options/revision/3661
for details.

The preview was overdrawing all the time, if no cursor movement was done. <- Fixed now.
The whole screen was damaged, instead of just the selection rectangle. <- Fixed now as well.

review: Needs Resubmitting
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

On Wed, Apr 24, 2013 at 4:03 AM, MC Return <email address hidden> wrote:
> Review: Needs Information
>
> Grmpf, during testing I found out that damage handling is also broken, I filed bug #1172234 about it.
> This should be pretty easy to fix, so I'll do it here...
>
Please do it separately. If there are comments I have about the damage
handling fix they'll also hold up this merge request too.

> I still have a minor blending problem to fix, if you have a tip how to fix the
> the-screenshot-selection-overlay-is-visible-on-screenshots-if-fbos-are-enabled
> please shout out loud in the meantime... ;)

You need to set the read buffer to GL_BACK I think. I'm a bit hesitant
about giving that advice though until we have a proper abstraction
for tracking framebuffer attachment points inside of compiz - querying
OpenGL is sloowwwww.

> --
> https://code.launchpad.net/~mc-return/compiz/compiz.merge-fix1169353-screenshot-needs-color-options/+merge/159038
> Your team Compiz Maintainers is requested to review the proposed merge of lp:~mc-return/compiz/compiz.merge-fix1169353-screenshot-needs-color-options into lp:compiz.

--
Sam Spilsbury

Revision history for this message
MC Return (mc-return) wrote :

> Please do it separately. If there are comments I have about the damage
> handling fix they'll also hold up this merge request too.
>
It is all already done and all fixed, I will explain in detail what I changed
to fix the damage handling, it was just a minor issue:

267 -
268 - cScreen->damageScreen ();
269 }
270 +
271 + cScreen->damageScreen ();

It was damaging the whole screen during a size change instead of just damaging
the screen once the operation was finished (the mouse button is released).

The other thing I fixed in r3661 was a permanent redraw problem, because the
overlay got overdrawn when there was no movement. This is now fixed also.
This was the blending problem I discovered and have written about earlier here:

> > I still have a minor blending problem to fix,

This was fixed by introducing the new variable bool selectionSizeChanged,
which is true if the size of the selection has changed, please see r3661
for details on this:

http://bazaar.launchpad.net/~mc-return/compiz/compiz.merge-fix1169353-screenshot-needs-color-options/revision/3661

>
> You need to set the read buffer to GL_BACK I think. I'm a bit hesitant
> about giving that advice though until we have a proper abstraction
> for tracking framebuffer attachment points inside of compiz - querying
> OpenGL is sloowwwww.
>

I will do some more experiments and try to fix this last issue in another MP.
Thanks a lot for the tip. :)

Revision history for this message
MC Return (mc-return) :
review: Needs Resubmitting
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Hrm, I don't think the way you've fixed this is really correct:

void
ShotScreen::handleMotionEvent (int xRoot,
          int yRoot)
{
    /* update screenshot rectangle size */
    if (mGrabIndex &&
 (mX2 != xRoot || mY2 != yRoot))
    {
 /* the size has changed now */
 selectionSizeChanged = true;

 int x1 = MIN (mX1, mX2) - 1;
 int y1 = MIN (mY1, mY2) - 1;
 int x2 = MAX (mX1, mX2) + 1;
 int y2 = MAX (mY1, mY2) + 1;

 cScreen->damageRegion (CompRegion (x1, y1, x2 - x1, y2 - y1));

 mX2 = xRoot;
 mY2 = yRoot;

 x1 = MIN (mX1, mX2) - 1;
 y1 = MIN (mY1, mY2) - 1;
 x2 = MAX (mX1, mX2) + 1;
 y2 = MAX (mY1, mY2) + 1;

 cScreen->damageRegion (CompRegion (x1, y1, x2 - x1, y2 - y1));
    }

    cScreen->damageScreen ();
}

The whole idea of those two damageRegion () calls is to mark the *old* selection rectangle region as damaged and then mark the new selection region as damaged, so that the damage area covers the selection area.

This change does that *and* damages the whole screen every time there is a motion event, regardless of whether or not screenshot even has an active grab or the mouse cursor position actually changed.

If the damage code isn't working, then you should look into why the current region-based damage isn't working rather than damaging the whole screen every time there is a motion event.

review: Needs Fixing
Revision history for this message
MC Return (mc-return) wrote :

> Hrm, I don't think the way you've fixed this is really correct:
>

> The whole idea of those two damageRegion () calls is to mark the *old*
> selection rectangle region as damaged and then mark the new selection region
> as damaged, so that the damage area covers the selection area.
>
> This change does that *and* damages the whole screen every time there is a
> motion event, regardless of whether or not screenshot even has an active grab
> or the mouse cursor position actually changed.
>
> If the damage code isn't working, then you should look into why the current
> region-based damage isn't working rather than damaging the whole screen every
> time there is a motion event.

You are right -> the fix is not entirely correct. The cScreen->damageScreen ();
call should be removed completely as we do never need to damage more than the
actual selection...

I'll fix that immediately.

Revision history for this message
MC Return (mc-return) wrote :

And the whole damage handling could be improved here, but without
the cScreen->damageScreen (); call it is already acting much more
sane, but it has some room for optimization still (no need to damage
the region twice for example)...

3662. By MC Return

We really never need to damage more than the selected region, removed
call to cScreen->damageScreen (); completely

Revision history for this message
MC Return (mc-return) wrote :

I will create a short video showing how the damaging for screenshot and ezoom now work if you like ?

Show Repaint is *awesome* for debugging this stuff !!!

review: Needs Resubmitting
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Looks good as it is now.

Don't change the current damageRegion code as it stands, its actually correct in its current form. Where you have a rectangle that varies in size, you should always mark the old rectangle as damaged as well as the new one, because you need to redraw the area underneath where the old rectangle was. This handles the case where the overlay-rectangle is getting smaller.

review: Approve
Revision history for this message
MC Return (mc-return) wrote :

> Looks good as it is now.
>

+1

> Don't change the current damageRegion code as it stands, its actually correct
> in its current form. Where you have a rectangle that varies in size, you
> should always mark the old rectangle as damaged as well as the new one,
> because you need to redraw the area underneath where the old rectangle was.
> This handles the case where the overlay-rectangle is getting smaller.

Never stop learning ;)

Now lets move to the freaking final screenshot issue... :)

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/screenshot/screenshot.xml.in'
2--- plugins/screenshot/screenshot.xml.in 2012-10-15 10:31:51 +0000
3+++ plugins/screenshot/screenshot.xml.in 2013-04-24 15:45:35 +0000
4@@ -2,7 +2,7 @@
5 <compiz>
6 <plugin name="screenshot" useBcop="true">
7 <_short>Screenshot</_short>
8- <_long>Screenshot plugin</_long>
9+ <_long>Easily capture parts of your screen and save them as .png image</_long>
10 <category>Extras</category>
11 <deps>
12 <requirement>
13@@ -17,18 +17,43 @@
14 <options>
15 <option name="initiate_button" type="button">
16 <_short>Initiate</_short>
17- <_long>Initiate rectangle screenshot</_long>
18+ <_long>Initiate the capture, release the button to take the shot.</_long>
19 <default>&lt;Super&gt;Button1</default>
20 </option>
21+ <option name="draw_selection_indicator" type="bool">
22+ <_short>Draw Screenshot Selection Indicator</_short>
23+ <_long>Draw a rectangle outline indicating the screenshot selection.</_long>
24+ <default>true</default>
25+ </option>
26+ <option name="selection_outline_color" type="color">
27+ <_short>Selection Indicator Outline Color</_short>
28+ <_long>Color and opacity of the screenshot selection rectangle outline.</_long>
29+ <default>
30+ <red>0x2fff</red>
31+ <green>0x2fff</green>
32+ <blue>0x4fff</blue>
33+ <alpha>0x9f9f</alpha>
34+ </default>
35+ </option>
36+ <option name="selection_fill_color" type="color">
37+ <_short>Selection Indicator Fill Color</_short>
38+ <_long>Fill color and opacity of the screenshot selection rectangle.</_long>
39+ <default>
40+ <red>0x2fff</red>
41+ <green>0x2fff</green>
42+ <blue>0x4fff</blue>
43+ <alpha>0x4fff</alpha>
44+ </default>
45+ </option>
46 <option name="directory" type="string">
47- <_short>Directory</_short>
48- <_long>Put screenshot images in this directory. If empty, the desktop directory will be used.</_long>
49+ <_short>Save Directory</_short>
50+ <_long>Save screenshot images in this directory. If empty, the desktop directory will be used.</_long>
51 <hints>directory;</hints>
52 <default></default>
53 </option>
54 <option name="launch_app" type="string">
55 <_short>Launch Application</_short>
56- <_long>Automatically open screenshot in this application</_long>
57+ <_long>Automatically open the screenshot in this application.</_long>
58 <default></default>
59 </option>
60 </options>
61
62=== modified file 'plugins/screenshot/src/screenshot.cpp'
63--- plugins/screenshot/src/screenshot.cpp 2013-04-13 22:29:01 +0000
64+++ plugins/screenshot/src/screenshot.cpp 2013-04-24 15:45:35 +0000
65@@ -34,8 +34,6 @@
66 #define scandir(a,b,c,d) scandir((a), (b), (c), (int(*)(const void*,const void*))(d));
67 #endif
68
69-
70-
71 COMPIZ_PLUGIN_20090315 (screenshot, ShotPluginVTable)
72
73 bool
74@@ -58,7 +56,7 @@
75 if (state & CompAction::StateInitButton)
76 action->setState (action->state () | CompAction::StateTermButton);
77
78- /* start selection screenshot rectangle */
79+ /* Start selection screenshot rectangle */
80
81 mX1 = mX2 = pointerX;
82 mY1 = mY2 = pointerY;
83@@ -82,7 +80,7 @@
84
85 if (mGrabIndex)
86 {
87- // Enable screen capture
88+ /* Enable screen capture */
89 cScreen->paintSetEnabled (this, true);
90 ::screen->removeGrab (mGrabIndex, 0);
91 mGrabIndex = 0;
92@@ -121,9 +119,9 @@
93 int nDigits = 0;
94
95 for (; number > 0; number /= 10)
96- nDigits++;
97+ ++nDigits;
98
99- // Make sure there are no trailing characters in the name
100+ /* Make sure there are no trailing characters in the name */
101 if ((int) strlen (d->d_name) == 14 + nDigits)
102 return 1;
103 }
104@@ -154,15 +152,13 @@
105
106 if (mGrab)
107 {
108- int x1, x2, y1, y2;
109-
110- x1 = MIN (mX1, mX2);
111- y1 = MIN (mY1, mY2);
112- x2 = MAX (mX1, mX2);
113- y2 = MAX (mY1, mY2);
114-
115 if (!mGrabIndex)
116 {
117+ int x1 = MIN (mX1, mX2);
118+ int y1 = MIN (mY1, mY2);
119+ int x2 = MAX (mX1, mX2);
120+ int y2 = MAX (mY1, mY2);
121+
122 int w = x2 - x1;
123 int h = y2 - y1;
124
125@@ -176,6 +172,7 @@
126 dir = getXDGUserDir (XDGUserDirDesktop);
127
128 buffer = (GLubyte *)malloc (sizeof (GLubyte) * w * h * 4);
129+
130 if (buffer)
131 {
132 struct dirent **namelist;
133@@ -196,7 +193,7 @@
134 "screenshot%d.png",
135 &number);
136
137- number++;
138+ ++number;
139
140 if (n)
141 free (namelist);
142@@ -238,18 +235,36 @@
143 GLMatrix transform (matrix);
144 GLfloat vertexData[12];
145 GLushort colorData[4];
146+ GLushort *color;
147
148 bool status = gScreen->glPaintOutput (attrib, matrix, region, output, mask);
149
150 if (status && mGrab)
151 {
152- int x1 = MIN (mX1, mX2);
153- int y1 = MIN (mY1, mY2);
154- int x2 = MAX (mX1, mX2);
155- int y2 = MAX (mY1, mY2);
156+ /* We just want to draw the screenshot selection box if
157+ * we are grabbed, the size has changed and the CCSM
158+ * option to draw it is enabled. */
159
160- if (mGrabIndex)
161+ if (mGrabIndex &&
162+ selectionSizeChanged &&
163+ optionGetDrawSelectionIndicator ())
164 {
165+ int x1 = MIN (mX1, mX2);
166+ int y1 = MIN (mY1, mY2);
167+ int x2 = MAX (mX1, mX2);
168+ int y2 = MAX (mY1, mY2);
169+
170+ const float MaxUShortFloat = std::numeric_limits <unsigned short>::max ();
171+
172+ /* draw filled rectangle */
173+ float alpha = optionGetSelectionFillColorAlpha () / MaxUShortFloat;
174+ color = optionGetSelectionFillColor ();
175+
176+ colorData[0] = alpha * color[0];
177+ colorData[1] = alpha * color[1];
178+ colorData[2] = alpha * color[2];
179+ colorData[3] = alpha * MaxUShortFloat;
180+
181 vertexData[0] = x1;
182 vertexData[1] = y1;
183 vertexData[2] = 0.0f;
184@@ -263,12 +278,6 @@
185 vertexData[10] = y2;
186 vertexData[11] = 0.0f;
187
188- colorData[0] = 0x2fff;
189- colorData[1] = 0x2fff;
190- colorData[2] = 0x4fff;
191- colorData[3] = 0x4fff;
192-
193-
194 transform.translate (-0.5f, -0.5f, -DEFAULT_Z_CAMERA);
195 transform.scale (1.0f / output->width (),
196 -1.0f / output->height (),
197@@ -277,9 +286,8 @@
198 -output->region ()->extents.y2,
199 0.0f);
200
201-#ifndef USE_GLES
202 glEnable (GL_BLEND);
203-#endif
204+
205 streamingBuffer->begin (GL_TRIANGLE_STRIP);
206
207 streamingBuffer->addColors (1, colorData);
208@@ -288,22 +296,35 @@
209 streamingBuffer->end ();
210 streamingBuffer->render (transform);
211
212- streamingBuffer->begin (GL_LINE_LOOP);
213+ /* draw outline */
214+ alpha = optionGetSelectionOutlineColorAlpha () / MaxUShortFloat;
215+ color = optionGetSelectionOutlineColor ();
216+
217+ colorData[0] = alpha * color[0];
218+ colorData[1] = alpha * color[1];
219+ colorData[2] = alpha * color[2];
220+ colorData[3] = alpha * MaxUShortFloat;
221
222 vertexData[6] = x2;
223 vertexData[7] = y2;
224 vertexData[9] = x2;
225 vertexData[10] = y1;
226- colorData [3] = 0x9fff;
227+
228+ glLineWidth (2.0);
229+
230+ streamingBuffer->begin (GL_LINE_LOOP);
231
232 streamingBuffer->addColors (1, colorData);
233 streamingBuffer->addVertices (4, vertexData);
234
235 streamingBuffer->end ();
236-#ifndef USE_GLES
237+ streamingBuffer->render (transform);
238+
239 glDisable (GL_BLEND);
240-#endif
241- streamingBuffer->render (transform);
242+
243+ /* we finished painting the selection box,
244+ * reset selectionSizeChanged now */
245+ selectionSizeChanged = false;
246 }
247 }
248
249@@ -315,8 +336,12 @@
250 int yRoot)
251 {
252 /* update screenshot rectangle size */
253- if (mGrabIndex)
254+ if (mGrabIndex &&
255+ (mX2 != xRoot || mY2 != yRoot))
256 {
257+ /* the size has changed now */
258+ selectionSizeChanged = true;
259+
260 int x1 = MIN (mX1, mX2) - 1;
261 int y1 = MIN (mY1, mY2) - 1;
262 int x2 = MAX (mX1, mX2) + 1;
263@@ -333,8 +358,6 @@
264 y2 = MAX (mY1, mY2) + 1;
265
266 cScreen->damageRegion (CompRegion (x1, y1, x2 - x1, y2 - y1));
267-
268- cScreen->damageScreen ();
269 }
270 }
271
272@@ -366,12 +389,13 @@
273 cScreen (CompositeScreen::get (screen)),
274 gScreen (GLScreen::get (screen)),
275 mGrabIndex (0),
276- mGrab (false)
277+ mGrab (false),
278+ selectionSizeChanged (false)
279 {
280 optionSetInitiateButtonInitiate (boost::bind (&ShotScreen::initiate, this,
281- _1, _2, _3));
282+ _1, _2, _3));
283 optionSetInitiateButtonTerminate (boost::bind (&ShotScreen::terminate, this,
284- _1, _2, _3));
285+ _1, _2, _3));
286
287 ScreenInterface::setHandler (screen, false);
288 CompositeScreenInterface::setHandler (cScreen, false);
289
290=== modified file 'plugins/screenshot/src/screenshot.h'
291--- plugins/screenshot/src/screenshot.h 2013-04-13 22:29:01 +0000
292+++ plugins/screenshot/src/screenshot.h 2013-04-24 15:45:35 +0000
293@@ -66,6 +66,7 @@
294
295 CompScreen::GrabHandle mGrabIndex;
296 bool mGrab;
297+ bool selectionSizeChanged;
298
299 int mX1, mY1, mX2, mY2;
300 };

Subscribers

People subscribed via source and target branches

to all changes: