Tk Source Code

View Ticket
Login
Ticket UUID: ddeef0e0690f2721bdb7492698cf93b2bdf5035a
Title: Some canvImg tests fail on macOS
Type: Bug Version: core-8-6-branch
Submitter: fvogel Created on: 2018-04-30 12:24:25
Subsystem: 05. Canvas Items Assigned To: fvogel
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2018-05-13 17:37:20
Resolution: Fixed Closed By: fvogel
    Closed on: 2018-05-13 17:37:20
Description:

Some canvImg tests fail on macOS, namely canvImg-4.2, canvImg-10.1, canvImg-11.1 and canvImg-11.3

Investigation seems to show that all these tests appear to fail for the same reason: the drawable coordinates are not the same on macOS as they are for the pixmap on the other platforms.

In more details:

- The result that is tested in the above tests is a debug output from tkTest.c

- For all failing tests the four first figures in the results are always the expected ones. Only the last two, which are the drawableX, drawableY are incorrect on macOS only

- The problem actually happens just when creating an image item in the canvas, before running the 'changed' command (note: this command is a test command only, crafted in tkTest.c specifically to allow calling Tk_ImageChanged() from the scripting level)

- MacOS is the only platform that defines TK_NO_DOUBLE_BUFFERING. This is what creates the difference with the other platforms.

At this point I think that either:

A. There is a bug in TkpClipDrawableToRect() (this function is only defined on macOS)

or

B. Everything is working (the rendering is fully OK, and so on) and the tests are failing because they are checking an implementation detail that does not matter and is subtly different on the supported platforms. In this case we should stop checking for these implementation details, namely the drawable coordinates.

User Comments: fvogel added on 2018-05-13 17:37:20:
Merged to core-8-6-branch and trunk.

fvogel added on 2018-04-30 18:51:22:

Fixed in [47aadbfe0c] in accordance with the discussion below.


fvogel added on 2018-04-30 18:43:33:
Yes I'm in agreement. I'll just remove those two figures from the expected results. Thanks for your feedback!

marc_culler (claiming to be Marc Culler) added on 2018-04-30 17:59:06:

I believe I have a concise explanation for why the coordinates are different, depending on whether double buffering is used:

* When double-buffering is used the image is being drawn into a pixmap buffer cut out of the screen. In this case the coordinates are relative to the pixmap origin.

* When double buffering is not used the image is being drawn directly onto the screen. In this case the coordinates are relative to the screen origin.

Certainly these would not be expected to be the same, so it doesn't make sense to use them in a test.

To make the test meaningful it should instead be reporting coordinates relative to the window with borders and padding accounted for. But I think it would be simplest, and acceptable, to just not print drawableX and drawableY and compare the other 4 numbers in the test.


marc_culler (claiming to be Marc Culler) added on 2018-04-30 16:35:43:

Here are some observations.

* The Mac window manager does double buffering automatically, so there is no need for Tk to do additional double buffering.

* On the Mac, there are clipping regions associated to windows and subwindows which are meant to allow the subwindows to be drawn in any order. The rectangles corresponding to "higher" subwindows are clipped out of the "lower" subwindows. TkpClipDrawableToRect intersects the clipping region with another rectangle to make the drawing region even smaller. The call in DrawCanvas is just clipping to the bounding rectangle of the canvas. It may be unnecessary but the point is that it should not change any data that Tk can see. It should only change data that is private to the Mac window manager.
By the way, the call in the code that you highlight in your artifact is strangely obtuse. For example, on line 2569 the x coordinate is set to
screenX1 - canvasPtr->xOrigin.
But if you look at how screenX1 was computed above you see that
screenX1 - canvasPtr->xOrigin == canvasPtr->inset
which actually makes sense as the x coordinate of a corner of the clipping rectangle for the canvas. I have no idea why canvasPtr->inset was not used directly.

* If you look at the code for the double-buffered displays you see that the pixmap which is being cut out of the screen for the double buffering has a 30 pixel margin around the actual rectangle of the canvas. This is meant to compensate for some weirdness of the X server on DECstations. But that 30 is the same 30 that is appearing in the "correct" result for test image-1.7. So this argues for your possibility B.

* The differences in the coordinates are not accounted for by the 30 pixel margin, but I believe that the other thing contributing to the differences may be the position of the test window on the screen. I am not certain of that. But I am definitely leaning toward possibility B as the correct explanation.


fvogel added on 2018-04-30 12:31:49:

Same issue for tests in image.test on macOS:

==== image-1.7 Tk_ImageCmd procedure, "create" option FAILED
==== Contents of test case:

    image create test myimage -variable x
    .c create image 100 50 -image myimage
    .c create image 100 150 -image myimage
    update
    set x {}
    image create test myimage -variable x
    update
    return $x

---- Result was:
{myimage free} {myimage free} {myimage delete} {myimage get} {myimage get} {myimage display 0 0 30 15 85 43} {myimage display 0 0 30 15 85 143}
---- Result should have been (exact matching):
{myimage free} {myimage free} {myimage delete} {myimage get} {myimage get} {myimage display 0 0 30 15 30 30} {myimage display 0 0 30 15 30 130}
==== image-1.7 FAILED



==== image-1.8 Tk_ImageCmd procedure, "create" option FAILED
==== Contents of test case:

    image create test myimage -variable x
    .c create image 100 50 -image myimage
    .c create image 100 150 -image myimage
    image delete myimage
    update
    set x {}
    image create test myimage -variable x
    update
    return $x

---- Result was:
{myimage get} {myimage get} {myimage display 0 0 30 15 85 43} {myimage display 0 0 30 15 85 143}
---- Result should have been (exact matching):
{myimage get} {myimage get} {myimage display 0 0 30 15 30 30} {myimage display 0 0 30 15 30 130}
==== image-1.8 FAILED



==== image-9.1 Tk_ImageChanged procedure FAILED
==== Contents of test case:

    image create test foo -variable x
    .c create image 50 50 -image foo
    update
    set x {}
    foo changed 5 6 7 8 30 15
    update
    return $x

---- Result was:
{foo display 5 6 7 8 40 49}
---- Result should have been (exact matching):
{foo display 5 6 7 8 30 30}
==== image-9.1 FAILED



==== image-9.2 Tk_ImageChanged procedure FAILED
==== Contents of test case:

    image create test foo -variable x
    .c create image 50 50 -image foo
    .c create image 90 100 -image foo
    update
    set x {}
    foo changed 5 6 7 8 30 15
    update
    return $x

---- Result was:
{foo display 5 6 25 9 40 49} {foo display 0 0 12 14 75 93}
---- Result should have been (exact matching):
{foo display 5 6 25 9 30 30} {foo display 0 0 12 14 65 74}
==== image-9.2 FAILED



==== image-11.1 Tk_FreeImage procedure FAILED
==== Contents of test case:

    image create test foo -variable x
    .c create image 50 50 -image foo -tags i1
    .c create image 90 100 -image foo -tags i2
    pack forget .c
    update
    set x {}
    .c delete i1
    pack .c
    update
    list [imageNames] $x

---- Result was:
foo {{foo free} {foo display 0 0 30 15 75 93}}
---- Result should have been (exact matching):
foo {{foo free} {foo display 0 0 30 15 103 121}}
==== image-11.1 FAILED


fvogel added on 2018-04-30 12:30:42:

Full log of failures in canvImg on macOS:

==== canvImg-4.2 ConfiugreImage procedure FAILED
==== Contents of test case:

	image create test foo -variable x
    image create test foo2 -variable y
    foo2 changed 0 0 0 0 80 60
    .c create image 50 100 -image foo -tags i1 -anchor nw
    update
    set x {}
    set y {}
    .c itemconfigure i1 -image foo2
    update
    list $x $y [.c bbox i1]

---- Result was:
{{foo free}} {{foo2 get} {foo2 display 0 0 80 60 50 100}} {50 100 130 160}
---- Result should have been (exact matching):
{{foo free}} {{foo2 get} {foo2 display 0 0 80 60 30 30}} {50 100 130 160}
==== canvImg-4.2 FAILED



==== canvImg-10.1 TranslateImage procedure FAILED
==== Contents of test case:

	image create test foo -variable x
    .c create image 50 100 -image foo -tags image -anchor nw
    update
    set x {}
    foo changed 2 4 6 8 30 15
    update
    return $x

---- Result was:
{foo display 2 4 6 8 52 104}
---- Result should have been (exact matching):
{foo display 2 4 6 8 30 30}
==== canvImg-10.1 FAILED



==== canvImg-11.1 TranslateImage procedure FAILED
==== Contents of test case:

	image create test foo -variable x
    .c create image 50 100 -image foo -tags image -anchor nw
    update
    set x {}
    foo changed 2 4 6 8 40 50
    update
    return $x

---- Result was:
{foo display 0 0 40 50 50 100}
---- Result should have been (exact matching):
{foo display 0 0 40 50 30 30}
==== canvImg-11.1 FAILED



==== canvImg-11.3 ImageChangedProc procedure FAILED
==== Contents of test case:

    image create test foo -variable x
	image create test foo2 -variable y
    foo changed 0 0 0 0 40 50
    foo2 changed 0 0 0 0 80 60

    .c create image 50 100 -image foo -tags image -anchor nw
    .c create image 70 110 -image foo2 -anchor nw
    update
    set y {}
    image create test foo -variable x
    update
    return $y

---- Result was:
{foo2 display 0 0 20 40 70 110}
---- Result should have been (exact matching):
{foo2 display 0 0 20 40 50 40}
==== canvImg-11.3 FAILED