summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2006-03-15 23:20:20 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2006-03-15 23:20:20 (GMT)
commitf7505e1446686d15cfed313b1d20f9cd0408b5a2 (patch)
tree1030284a9686b21d5aedce00850d7db36423b8e5
parentf7603a010efd417efe3ccb5e5ffd9858c6821147 (diff)
downloadtk-f7505e1446686d15cfed313b1d20f9cd0408b5a2.zip
tk-f7505e1446686d15cfed313b1d20f9cd0408b5a2.tar.gz
tk-f7505e1446686d15cfed313b1d20f9cd0408b5a2.tar.bz2
Squelch [Bug 1409140] by special-case-ing the single-pixel put case.
Also take better advantage of C's casting rules w.r.t. void* and other pointers
-rw-r--r--ChangeLog80
-rw-r--r--generic/tkImgPhoto.c103
2 files changed, 112 insertions, 71 deletions
diff --git a/ChangeLog b/ChangeLog
index 56112e3..c1e594b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2006-03-15 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tkImgPhoto.c (Tk_PhotoPutBlock, Tk_PhotoPutZoomedBlock): Try
+ to squelch performance issue with code that writes to large images by
+ single pixels. Masses of thanks to George Staplin for helping to trace
+ this down to the COMPLEX_ALPHA flag handling code. [Bug 1409140]
+
006-03-13 Don Porter <dgp@users.sourceforge.net>
* tests/scrollbar.test: Corrected several broken calls to [testmetrics]
@@ -7,24 +14,24 @@
* tests/canvPs.test: to stop test suite crash on Mac OSX.
[Bug 1088807]
- * generic/tkCmds.c: Purged remaining references to
- * macosx/tkMacOSXPort.h: errno, and errno.h. Standardized
- * macosx/tkMacOSXWm.c: the logic for using header files from
- * macosx/tkMacOSXWm.h: the compat directory. Thanks Joe
- * unix/tkUnixPort.h: English for the patch. [Patch 1445404]
+ * generic/tkCmds.c: Purged remaining references to errno,
+ * macosx/tkMacOSXPort.h: and errno.h. Standardized the logic
+ * macosx/tkMacOSXWm.c: for using header files from the compat
+ * macosx/tkMacOSXWm.h: directory. Thanks Joe English for the
+ * unix/tkUnixPort.h: patch. [Patch 1445404]
2006-03-08 Don Porter <dgp@users.sourceforge.net>
- * unix/Makefile.in: Update `make dist` to copy the image files
- needed by the test suite into the source distro. This was overlooked
- in the 2005-10-12 commit.
+ * unix/Makefile.in: Update `make dist` to copy the image files needed
+ by the test suite into the source distro. This was overlooked in the
+ 2005-10-12 commit.
* changes: Update in prep. for 8.5a4 release.
2006-03-07 Joe English <jenglish@users.sourceforge.net>
- * unix/tcl.m4: Set SHLIB_LD_FLAGS='${LIBS}' on NetBSD,
- as per the other *BSD variants [Bug 1334613].
+ * unix/tcl.m4: Set SHLIB_LD_FLAGS='${LIBS}' on NetBSD, as per the
+ other *BSD variants [Bug 1334613].
* unix/configure: Regenerated.
2006-03-07 Donal K. Fellows <dkf@users.sf.net>
@@ -52,11 +59,11 @@
2006-02-09 Daniel Steffen <das@users.sourceforge.net>
* generic/tk.decls: fix signature of TkMacOSXInvalClipRgns
- * generic/tkPlatDecls.h: to use Tk_Window instead of internal
- * macosx/tkMacOSXSubwindows.c: type TkWindow (which led to any include
+ * generic/tkPlatDecls.h: to use Tk_Window instead of internal
+ * macosx/tkMacOSXSubwindows.c: type TkWindow (which led to any include
* macosx/tkMacOSXWindowEvent.c: of public header tkMacOSX.h requiring
* macosx/tkMacOSXWm.c: prior include of tkInt.h).
-
+
* generic/tk.h: move TkAqua specific REDO_KEYSYM_LOOKUP define
* macosx/tkMacOSXPort.h: out of tk.h into platform header.
@@ -181,9 +188,9 @@
2005-12-09 Daniel Steffen <das@users.sourceforge.net>
- * generic/tkInt.decls: move all platform test sources from tk lib into
- * generic/tkTest.c: tktest directly, removes requirement to export
- * macosx/tkMacOSXTest.c: TkplatformtestInit from internal stubs table.
+ * generic/tkInt.decls: Move all platform test sources from tk lib into
+ * generic/tkTest.c: tktest directly, removes requirement to export
+ * macosx/tkMacOSXTest.c:TkplatformtestInit from internal stubs table.
* unix/Makefile.in:
* win/Makefile.in:
* win/makefile.vc:
@@ -205,17 +212,17 @@
* win/rc/wish.exe.manifest (removed): and VERSION to be correct.
* unix/Makefile.in: fix dist target for manifest dir change
- * generic/tkTextTag.c (TkTextTagCmd): use correct arraySize for
- peered text widgets in [$text tag names]. [Bug 1375069 1374935]
+ * generic/tkTextTag.c (TkTextTagCmd): use correct arraySize for peered
+ text widgets in [$text tag names]. [Bug 1375069 1374935]
2005-12-08 Daniel Steffen <das@users.sourceforge.net>
- * macosx/tkMacOSXDraw.c: remove inclusion of tclInt.h and use of tcl
- * macosx/tkMacOSXFont.c: internals wherever possible in tk/macosx, the
- * macosx/tkMacOSXInit.c: only remaining tcl internals in TkAqua are
- * macosx/tkMacOSXNotify.c: TclServiceIdle() in tkMacOSXScrlbr.c and
- * macosx/tkMacOSXScrlbr.c: Tcl_Get/SetStartupScript() in tkMacOSXInit.c
- [RFE 1336531].
+ * macosx/tkMacOSXDraw.c: Remove inclusion of tclInt.h and use of tcl
+ * macosx/tkMacOSXFont.c: internals wherever possible in tk/macosx, the
+ * macosx/tkMacOSXInit.c: only remaining tcl internals in TkAqua are
+ * macosx/tkMacOSXNotify.c:TclServiceIdle() in tkMacOSXScrlbr.c and
+ * macosx/tkMacOSXScrlbr.c:Tcl_Get/SetStartupScript() in tkMacOSXInit.c
+ [RFE 1336531].
* macosx/tkMacOSXInt.h: sync comments with core-8-4-branch.
@@ -462,8 +469,8 @@
2005-11-15 Joe English <jenglish@users.sourceforge.net>
- * unix/tkUnixWm.c, tests/unixWm.test, doc/wm.n:
- Support for [wm attributes] on X11 [TIP#231, Patch 1062022].
+ * unix/tkUnixWm.c, tests/unixWm.test, doc/wm.n: Support for [wm
+ attributes] on X11 [TIP#231, Patch 1062022].
2005-11-14 Joe English <jenglish@users.sourceforge.net>
@@ -477,9 +484,9 @@
2005-11-13 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * unix/tkUnixSelect.c (SelCvtToX): Arrange for the parsing code to
- use Tcl's list parsing code, another simplification that enables
- testing of the [Bug 1353414] fix.
+ * unix/tkUnixSelect.c (SelCvtToX): Arrange for the parsing code to use
+ Tcl's list parsing code, another simplification that enables testing
+ of the [Bug 1353414] fix.
* unix/tkUnixSelect.c (SelCvtFromX): Generate string forms of the
advanced selection types in a Tcl_DString. This makes fixing [Bug
@@ -512,20 +519,19 @@
2005-10-18 Don Porter <dgp@users.sourceforge.net>
- * generic/tkMain.c: Rewrote code that sets the ::argv value
- to be sure conversion from the system encoding is complete before
- any processing sensitive to list-special characters is done.
- [Bug 1328926].
+ * generic/tkMain.c: Rewrote code that sets the ::argv value to be sure
+ conversion from the system encoding is complete before any processing
+ sensitive to list-special characters is done. [Bug 1328926].
2005-10-17 Jeff Hobbs <jeffh@ActiveState.com>
- * macosx/tkMacOSXScrlbr.c (UpdateControlValues): check geomMgrPtr
- is valid before checking type
+ * macosx/tkMacOSXScrlbr.c (UpdateControlValues): check geomMgrPtr is
+ valid before checking type
2005-10-15 Jeff Hobbs <jeffh@ActiveState.com>
- * library/menu.tcl (::tk::MenuUnpost): remove leftover ] from
- string equal mods of 2005-07-25. (sowadsky)
+ * library/menu.tcl (::tk::MenuUnpost): remove leftover ] from string
+ equal mods of 2005-07-25. (sowadsky)
2005-10-14 Pat Thoyts <patthoyts@users.sourceforge.net>
diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c
index 2e890d0..62c2192 100644
--- a/generic/tkImgPhoto.c
+++ b/generic/tkImgPhoto.c
@@ -17,7 +17,7 @@
* Department of Computer Science,
* Australian National University.
*
- * RCS: @(#) $Id: tkImgPhoto.c,v 1.60 2005/11/27 02:36:13 das Exp $
+ * RCS: @(#) $Id: tkImgPhoto.c,v 1.61 2006/03/15 23:20:27 dkf Exp $
*/
#include "tkInt.h"
@@ -495,6 +495,7 @@ PhotoFormatThreadExitProc(
*
*----------------------------------------------------------------------
*/
+
void
Tk_CreateOldPhotoImageFormat(
Tk_PhotoImageFormat *formatPtr)
@@ -586,7 +587,7 @@ ImgPhotoCreate(
*/
masterPtr = (PhotoMaster *) ckalloc(sizeof(PhotoMaster));
- memset((void *) masterPtr, 0, sizeof(PhotoMaster));
+ memset(masterPtr, 0, sizeof(PhotoMaster));
masterPtr->tkMaster = master;
masterPtr->interp = interp;
masterPtr->imageCmd = Tcl_CreateObjCommand(interp, name, ImgPhotoCmd,
@@ -783,7 +784,7 @@ ImgPhotoCmd(
*/
index = 2;
- memset((VOID *) &options, 0, sizeof(options));
+ memset(&options, 0, sizeof(options));
options.zoomX = options.zoomY = 1;
options.subsampleX = options.subsampleY = 1;
options.name = NULL;
@@ -889,7 +890,7 @@ ImgPhotoCmd(
Tk_ImageStringWriteProc *stringWriteProc = NULL;
index = 2;
- memset((VOID *) &options, 0, sizeof(options));
+ memset(&options, 0, sizeof(options));
options.name = NULL;
options.format = NULL;
options.fromX = 0;
@@ -986,7 +987,7 @@ ImgPhotoCmd(
result = ((int (*) (Tcl_Interp *interp,
Tcl_Obj *formatString, Tk_PhotoImageBlock *blockPtr,
- VOID *dummy)) stringWriteProc)
+ void *dummy)) stringWriteProc)
(interp, options.format, &block, NULL);
}
if (options.background) {
@@ -1037,7 +1038,7 @@ ImgPhotoCmd(
*/
index = 2;
- memset((VOID *) &options, 0, sizeof(options));
+ memset(&options, 0, sizeof(options));
options.name = NULL;
if (ParseSubcommandOptions(&options, interp, OPT_TO|OPT_FORMAT,
&index, objc, objv) != TCL_OK) {
@@ -1209,7 +1210,7 @@ ImgPhotoCmd(
*/
index = 2;
- memset((VOID *) &options, 0, sizeof(options));
+ memset(&options, 0, sizeof(options));
options.name = NULL;
options.format = NULL;
if (ParseSubcommandOptions(&options, interp,
@@ -1430,20 +1431,24 @@ ImgPhotoCmd(
/*
* Make pixel transparent.
*/
+
TkRegion clearRegion = TkCreateRegion();
TkUnionRectWithRegion(&setBox, clearRegion, clearRegion);
TkSubtractRegion(masterPtr->validRegion, clearRegion,
masterPtr->validRegion);
TkDestroyRegion(clearRegion);
+
/*
* Set the alpha value correctly.
*/
+
pixelPtr[3] = 0;
} else {
/*
* Make pixel opaque.
*/
+
TkUnionRectWithRegion(&setBox, masterPtr->validRegion,
masterPtr->validRegion);
pixelPtr[3] = 255;
@@ -1483,7 +1488,7 @@ ImgPhotoCmd(
*/
index = 2;
- memset((VOID *) &options, 0, sizeof(options));
+ memset(&options, 0, sizeof(options));
options.name = NULL;
options.format = NULL;
if (ParseSubcommandOptions(&options, interp,
@@ -2040,9 +2045,11 @@ ImgPhotoConfigureMaster(
if (chan == NULL) {
goto errorExit;
}
+
/*
* -translation binary also sets -encoding binary
*/
+
if ((Tcl_SetChannelOption(interp, chan,
"-translation", "binary") != TCL_OK) ||
(MatchFileFormat(interp, chan, masterPtr->fileString,
@@ -3061,15 +3068,14 @@ ImgPhotoSetSize(
if ((masterPtr->pix32 != NULL)
&& ((width == masterPtr->width) || (width == validBox.width))) {
if (validBox.y > 0) {
- memset((VOID *) newPix32, 0, (size_t) (validBox.y * pitch));
+ memset(newPix32, 0, (size_t) (validBox.y * pitch));
}
h = validBox.y + validBox.height;
if (h < height) {
- memset((VOID *) (newPix32 + h * pitch), 0,
- (size_t) ((height - h) * pitch));
+ memset(newPix32 + h*pitch, 0, (size_t) ((height - h) * pitch));
}
} else {
- memset((VOID *) newPix32, 0, (size_t) (height * pitch));
+ memset(newPix32, 0, (size_t) (height * pitch));
}
if (masterPtr->pix32 != NULL) {
@@ -3085,8 +3091,7 @@ ImgPhotoSetSize(
*/
offset = validBox.y * pitch;
- memcpy((VOID *) (newPix32 + offset),
- (VOID *) (masterPtr->pix32 + offset),
+ memcpy(newPix32 + offset, masterPtr->pix32 + offset,
(size_t) (validBox.height * pitch));
} else if ((validBox.width > 0) && (validBox.height > 0)) {
@@ -3098,8 +3103,7 @@ ImgPhotoSetSize(
srcPtr = masterPtr->pix32 + (validBox.y * masterPtr->width
+ validBox.x) * 4;
for (h = validBox.height; h > 0; h--) {
- memcpy((VOID *) destPtr, (VOID *) srcPtr,
- (size_t) (validBox.width * 4));
+ memcpy(destPtr, srcPtr, (size_t) (validBox.width * 4));
destPtr += width * 4;
srcPtr += masterPtr->width * 4;
}
@@ -3233,17 +3237,17 @@ ImgPhotoInstanceSetSize(
&& ((instancePtr->width == masterPtr->width)
|| (validBox.width == masterPtr->width))) {
if (validBox.y > 0) {
- memset((VOID *) newError, 0, (size_t)
+ memset(newError, 0, (size_t)
validBox.y * masterPtr->width * 3 * sizeof(schar));
}
h = validBox.y + validBox.height;
if (h < masterPtr->height) {
- memset((VOID *) (newError + h * masterPtr->width * 3), 0,
+ memset(newError + h*masterPtr->width*3, 0,
(size_t) (masterPtr->height - h)
* masterPtr->width * 3 * sizeof(schar));
}
} else {
- memset((VOID *) newError, 0, (size_t)
+ memset(newError, 0, (size_t)
masterPtr->height * masterPtr->width *3*sizeof(schar));
}
} else {
@@ -3258,8 +3262,7 @@ ImgPhotoInstanceSetSize(
if (masterPtr->width == instancePtr->width) {
offset = validBox.y * masterPtr->width * 3;
- memcpy((VOID *) (newError + offset),
- (VOID *) (instancePtr->error + offset),
+ memcpy(newError + offset, instancePtr->error + offset,
(size_t) (validBox.height
* masterPtr->width * 3 * sizeof(schar)));
@@ -3270,7 +3273,7 @@ ImgPhotoInstanceSetSize(
(validBox.y * instancePtr->width + validBox.x) * 3;
for (h = validBox.height; h > 0; --h) {
- memcpy((VOID *) errDestPtr, (VOID *) errSrcPtr,
+ memcpy(errDestPtr, errSrcPtr,
validBox.width * 3 * sizeof(schar));
errDestPtr += masterPtr->width * 3;
errSrcPtr += instancePtr->width * 3;
@@ -3435,7 +3438,7 @@ GetColorTable(
* Look for an existing ColorTable in the hash table.
*/
- memset((VOID *) &id, 0, sizeof(id));
+ memset(&id, 0, sizeof(id));
id.display = instancePtr->display;
id.colormap = instancePtr->colormap;
id.palette = instancePtr->palette;
@@ -3469,7 +3472,7 @@ GetColorTable(
* in imgPhotoColorHash, and can result in core dumps.
*/
- memset((VOID *) &colorPtr->id, 0, sizeof(ColorTableId));
+ memset(&colorPtr->id, 0, sizeof(ColorTableId));
colorPtr->id = id;
Tk_PreserveColormap(colorPtr->id.display, colorPtr->id.colormap);
colorPtr->flags = 0;
@@ -3699,6 +3702,7 @@ AllocateColors(
/*
* Still can't allocate the color.
*/
+
break;
}
}
@@ -4418,8 +4422,7 @@ Tk_PhotoPutBlock(
&& ((height == 1) || ((x == 0) && (width == masterPtr->width)
&& (blockPtr->pitch == pitch)))
&& (compRule == TK_PHOTO_COMPOSITE_SET)) {
- memcpy((VOID *) destLinePtr,
- (VOID *) (blockPtr->pixelPtr + blockPtr->offset[0]),
+ memcpy(destLinePtr, blockPtr->pixelPtr + blockPtr->offset[0],
(size_t) (height * width * 4));
/*
@@ -4449,8 +4452,7 @@ Tk_PhotoPutBlock(
&& (blueOffset == 2) && (alphaOffset == 3)
&& (width <= blockPtr->width)
&& (compRule == TK_PHOTO_COMPOSITE_SET)) {
- memcpy((VOID *) destLinePtr, (VOID *) srcLinePtr,
- (size_t) (width * 4));
+ memcpy(destLinePtr, srcLinePtr, (size_t) (width * 4));
srcLinePtr += blockPtr->pitch;
destLinePtr += pitch;
continue;
@@ -4599,7 +4601,24 @@ Tk_PhotoPutBlock(
*/
if (alphaOffset != 0 || masterPtr->flags & COMPLEX_ALPHA) {
- ToggleComplexAlphaIfNeeded(masterPtr);
+ /*
+ * Note that we skip in the single pixel case if we can. This speeds
+ * up code that builds up large simple-alpha images by single pixels,
+ * which seems to be a common use-case. [Bug 1409140]
+ */
+
+ if (width == 1 && height == 1 && !(masterPtr->flags & COMPLEX_ALPHA)) {
+ unsigned char newAlpha;
+
+ destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
+ newAlpha = destLinePtr[3];
+
+ if (newAlpha > 0 && newAlpha < 255) {
+ masterPtr->flags |= COMPLEX_ALPHA;
+ }
+ } else {
+ ToggleComplexAlphaIfNeeded(masterPtr);
+ }
}
/*
@@ -4842,7 +4861,6 @@ Tk_PhotoPutZoomedBlock(
*/
if (alphaOffset) {
-
if (compRule != TK_PHOTO_COMPOSITE_OVERLAY) {
/*
* Don't need this when using the OVERLAY compositing rule, which
@@ -4861,7 +4879,7 @@ Tk_PhotoPutZoomedBlock(
TkDestroyRegion(workRgn);
}
- TkpBuildRegionFromAlphaData(masterPtr->validRegion, x, y, width, height,
+ TkpBuildRegionFromAlphaData(masterPtr->validRegion, x,y, width,height,
&masterPtr->pix32[(y * masterPtr->width + x) * 4 + 3], 4,
masterPtr->width * 4);
} else {
@@ -4878,7 +4896,24 @@ Tk_PhotoPutZoomedBlock(
*/
if (alphaOffset != 0 || masterPtr->flags & COMPLEX_ALPHA) {
- ToggleComplexAlphaIfNeeded(masterPtr);
+ /*
+ * Note that we skip in the single pixel case if we can. This speeds
+ * up code that builds up large simple-alpha images by single pixels,
+ * which seems to be a common use-case. [Bug 1409140]
+ */
+
+ if (width == 1 && height == 1 && !(masterPtr->flags & COMPLEX_ALPHA)) {
+ unsigned char newAlpha;
+
+ destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
+ newAlpha = destLinePtr[3];
+
+ if (newAlpha > 0 && newAlpha < 255) {
+ masterPtr->flags |= COMPLEX_ALPHA;
+ }
+ } else {
+ ToggleComplexAlphaIfNeeded(masterPtr);
+ }
}
/*
@@ -5360,12 +5395,12 @@ Tk_PhotoBlank(
* arrays for each instance.
*/
- memset((VOID *) masterPtr->pix32, 0,
+ memset(masterPtr->pix32, 0,
(size_t) (masterPtr->width * masterPtr->height * 4));
for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
instancePtr = instancePtr->nextPtr) {
if (instancePtr->error) {
- memset((VOID *) instancePtr->error, 0,
+ memset(instancePtr->error, 0,
(size_t) (masterPtr->width * masterPtr->height
* 3 * sizeof(schar)));
}