From lana.steuck at oracle.com Thu Jul 1 00:11:36 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Thu, 01 Jul 2010 00:11:36 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d: 8 new changesets Message-ID: <20100701001136.7348747670@hg.openjdk.java.net> Changeset: 5bbc7438b333 Author: mikejwre Date: 2010-06-10 13:58 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/rev/5bbc7438b333 Added tag jdk7-b97 for changeset 5e197c942c6e ! .hgtags Changeset: 39d81b90b100 Author: prr Date: 2010-06-16 09:41 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/rev/39d81b90b100 6961079: Build JDK7 for 64 bit Windows using free Windows 7.1 SDK 64 bit compilers Reviewed-by: ohair, jcoomes ! README-builds.html Changeset: 6cea9984d73d Author: mikejwre Date: 2010-06-16 15:48 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/rev/6cea9984d73d Merge Changeset: e7f18db469a3 Author: mikejwre Date: 2010-06-17 16:27 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/rev/e7f18db469a3 Added tag jdk7-b98 for changeset 6cea9984d73d ! .hgtags Changeset: dc900d5a8e2f Author: mikejwre Date: 2010-06-24 20:02 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/rev/dc900d5a8e2f Added tag jdk7-b99 for changeset e7f18db469a3 ! .hgtags Changeset: 47f6b7db1882 Author: ohair Date: 2010-06-21 11:00 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/rev/47f6b7db1882 6960853: Cleanup makefiles, remove unused vars etc. 6959596: Windows fastdebug build broken 6960335: Add top level 'make test' rule that uses test/Makefile, runs all test batches Reviewed-by: alanb ! Makefile ! make/Defs-internal.gmk ! make/jprt.gmk ! make/sanity-rules.gmk ! test/Makefile Changeset: 3b147bf5a0e9 Author: lana Date: 2010-06-21 22:06 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/rev/3b147bf5a0e9 Merge Changeset: b218a53ec7d3 Author: lana Date: 2010-06-29 22:31 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/rev/b218a53ec7d3 Merge From lana.steuck at oracle.com Thu Jul 1 00:11:41 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Thu, 01 Jul 2010 00:11:41 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/corba: 7 new changesets Message-ID: <20100701001149.253E247671@hg.openjdk.java.net> Changeset: 3b99409057e4 Author: mikejwre Date: 2010-06-10 13:58 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/corba/rev/3b99409057e4 Added tag jdk7-b97 for changeset 4ec9d59374ca ! .hgtags Changeset: 95db968660e7 Author: mikejwre Date: 2010-06-17 16:27 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/corba/rev/95db968660e7 Added tag jdk7-b98 for changeset 3b99409057e4 ! .hgtags Changeset: ad2aa1f66abf Author: mikejwre Date: 2010-06-24 20:02 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/corba/rev/ad2aa1f66abf Added tag jdk7-b99 for changeset 95db968660e7 ! .hgtags Changeset: 032585ad970d Author: jjg Date: 2010-06-14 11:28 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/corba/rev/032585ad970d 6960831: fix CORBA build warnings Reviewed-by: darcy ! src/share/classes/com/sun/corba/se/impl/orbutil/CorbaResourceUtil.java ! src/share/classes/com/sun/corba/se/impl/orbutil/ObjectUtility.java ! src/share/classes/com/sun/corba/se/impl/presentation/rmi/ExceptionHandlerImpl.java ! src/share/classes/org/omg/CORBA/ORB.java ! src/share/classes/sun/corba/Bridge.java Changeset: 8f0a1a30461d Author: lana Date: 2010-06-16 13:41 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/corba/rev/8f0a1a30461d Merge Changeset: 8eeca6e452de Author: lana Date: 2010-06-21 22:06 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/corba/rev/8eeca6e452de Merge Changeset: a56d734a1e97 Author: lana Date: 2010-06-29 22:31 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/corba/rev/a56d734a1e97 Merge From lana.steuck at oracle.com Thu Jul 1 00:14:45 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Thu, 01 Jul 2010 00:14:45 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/hotspot: 42 new changesets Message-ID: <20100701001610.4B4E347672@hg.openjdk.java.net> Changeset: b0e7cd862748 Author: mikejwre Date: 2010-06-10 13:58 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/b0e7cd862748 Added tag jdk7-b97 for changeset 5f42499e57ad ! .hgtags Changeset: 70191885f707 Author: prr Date: 2010-06-16 09:42 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/70191885f707 6961079: Build JDK7 for 64 bit Windows using free Windows 7.1 SDK 64 bit compilers Reviewed-by: ohair, jcoomes ! make/windows/makefiles/defs.make Changeset: 8a045b3f5c13 Author: mikejwre Date: 2010-06-16 15:48 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/8a045b3f5c13 Merge Changeset: 695c43156a9a Author: mikejwre Date: 2010-06-17 16:27 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/695c43156a9a Added tag jdk7-b98 for changeset 8a045b3f5c13 ! .hgtags Changeset: e40a3601bc1f Author: kamg Date: 2010-05-19 10:19 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/e40a3601bc1f 6911922: JVM must throw VerifyError for jsr or jsr_w opcodes in class file v.51+ 6693236: A class file whose version number is greater than to 50.0 must be verified using the typechecker Summary: Disable failover verification for classfiles >= v51 Reviewed-by: never, acorn, dholmes ! src/share/vm/classfile/verifier.cpp Changeset: 3548f3198dca Author: dcubed Date: 2010-05-26 14:16 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/3548f3198dca Merge Changeset: dfe27f03244a Author: trims Date: 2010-06-01 11:48 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/dfe27f03244a Merge ! src/share/vm/classfile/verifier.cpp Changeset: 1a5913bf5e19 Author: twisti Date: 2010-05-20 06:34 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob Summary: This moves the oops from Codeblob to nmethod. Reviewed-by: kvn, never ! agent/src/share/classes/sun/jvm/hotspot/code/CodeBlob.java ! agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java ! agent/src/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java ! src/cpu/sparc/vm/nativeInst_sparc.cpp ! src/os/solaris/dtrace/generateJvmOffsets.cpp ! src/os/solaris/dtrace/libjvm_db.c ! src/share/vm/asm/codeBuffer.hpp ! src/share/vm/code/codeBlob.cpp ! src/share/vm/code/codeBlob.hpp ! src/share/vm/code/codeCache.cpp ! src/share/vm/code/compiledIC.cpp ! src/share/vm/code/nmethod.cpp ! src/share/vm/code/nmethod.hpp ! src/share/vm/code/oopRecorder.cpp ! src/share/vm/code/oopRecorder.hpp ! src/share/vm/code/relocInfo.cpp ! src/share/vm/code/relocInfo.hpp ! src/share/vm/memory/iterator.cpp ! src/share/vm/runtime/sharedRuntime.cpp ! src/share/vm/runtime/vmStructs.cpp Changeset: 61b2245abf36 Author: twisti Date: 2010-05-21 02:59 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/61b2245abf36 6930772: JSR 292 needs to support SPARC C1 Summary: C1 for SPARC needs to support JSR 292. Reviewed-by: never, jrose ! src/cpu/sparc/vm/assembler_sparc.hpp ! src/cpu/sparc/vm/c1_FrameMap_sparc.cpp ! src/cpu/sparc/vm/c1_FrameMap_sparc.hpp ! src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp ! src/cpu/sparc/vm/c1_Runtime1_sparc.cpp ! src/cpu/sparc/vm/frame_sparc.cpp ! src/cpu/sparc/vm/methodHandles_sparc.cpp ! src/cpu/sparc/vm/register_definitions_sparc.cpp ! src/cpu/sparc/vm/sharedRuntime_sparc.cpp ! src/cpu/sparc/vm/stubGenerator_sparc.cpp ! src/cpu/sparc/vm/stubRoutines_sparc.hpp ! src/cpu/x86/vm/assembler_x86.hpp ! src/cpu/x86/vm/c1_FrameMap_x86.cpp ! src/cpu/x86/vm/c1_FrameMap_x86.hpp ! src/cpu/x86/vm/c1_LIRAssembler_x86.cpp ! src/cpu/x86/vm/c1_Runtime1_x86.cpp ! src/cpu/x86/vm/register_definitions_x86.cpp ! src/share/vm/c1/c1_FrameMap.hpp ! src/share/vm/c1/c1_IR.cpp ! src/share/vm/c1/c1_IR.hpp ! src/share/vm/c1/c1_LIR.cpp ! src/share/vm/c1/c1_LIR.hpp ! src/share/vm/c1/c1_LIRAssembler.cpp ! src/share/vm/c1/c1_LIRAssembler.hpp ! src/share/vm/c1/c1_LIRGenerator.cpp ! src/share/vm/ci/ciMethod.cpp ! src/share/vm/opto/bytecodeInfo.cpp ! src/share/vm/runtime/sharedRuntime.cpp Changeset: ab102d5d923e Author: jrose Date: 2010-05-23 01:38 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/ab102d5d923e 6939207: refactor constant pool index processing Summary: Factored cleanup of instruction decode which prepares for enhanced ldc semantics. Reviewed-by: twisti ! src/cpu/sparc/vm/interp_masm_sparc.cpp ! src/cpu/sparc/vm/interp_masm_sparc.hpp ! src/cpu/sparc/vm/templateInterpreter_sparc.cpp ! src/cpu/sparc/vm/templateTable_sparc.cpp ! src/cpu/x86/vm/interp_masm_x86_32.cpp ! src/cpu/x86/vm/interp_masm_x86_32.hpp ! src/cpu/x86/vm/interp_masm_x86_64.cpp ! src/cpu/x86/vm/interp_masm_x86_64.hpp ! src/cpu/x86/vm/templateInterpreter_x86_32.cpp ! src/cpu/x86/vm/templateInterpreter_x86_64.cpp ! src/cpu/x86/vm/templateTable_x86_32.cpp ! src/cpu/x86/vm/templateTable_x86_64.cpp ! src/share/vm/c1/c1_GraphBuilder.cpp ! src/share/vm/ci/ciStreams.cpp ! src/share/vm/ci/ciStreams.hpp ! src/share/vm/ci/ciTypeFlow.cpp ! src/share/vm/classfile/verifier.cpp ! src/share/vm/includeDB_core ! src/share/vm/interpreter/bytecode.cpp ! src/share/vm/interpreter/bytecode.hpp ! src/share/vm/interpreter/bytecodeStream.cpp ! src/share/vm/interpreter/bytecodeStream.hpp ! src/share/vm/interpreter/bytecodeTracer.cpp ! src/share/vm/interpreter/bytecodes.cpp ! src/share/vm/interpreter/bytecodes.hpp ! src/share/vm/interpreter/interpreter.cpp ! src/share/vm/interpreter/interpreterRuntime.cpp ! src/share/vm/interpreter/interpreterRuntime.hpp ! src/share/vm/interpreter/rewriter.cpp ! src/share/vm/interpreter/rewriter.hpp ! src/share/vm/interpreter/templateTable.cpp ! src/share/vm/interpreter/templateTable.hpp ! src/share/vm/oops/constantPoolOop.cpp ! src/share/vm/oops/constantPoolOop.hpp ! src/share/vm/oops/generateOopMap.cpp ! src/share/vm/opto/bytecodeInfo.cpp ! src/share/vm/opto/parse2.cpp ! src/share/vm/prims/jvmtiClassFileReconstituter.cpp ! src/share/vm/prims/methodComparator.cpp ! src/share/vm/prims/methodHandleWalk.cpp Changeset: 9f669cf29cb0 Author: jrose Date: 2010-05-24 14:15 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/9f669cf29cb0 Merge ! src/cpu/sparc/vm/assembler_sparc.hpp Changeset: 110501f54a99 Author: twisti Date: 2010-05-25 02:38 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/110501f54a99 6934104: JSR 292 needs to support SPARC C2 Summary: C2 for SPARC needs to support JSR 292. Reviewed-by: kvn, never ! src/cpu/sparc/vm/runtime_sparc.cpp ! src/cpu/sparc/vm/sparc.ad ! src/cpu/x86/vm/runtime_x86_32.cpp ! src/cpu/x86/vm/sharedRuntime_x86_64.cpp ! src/cpu/x86/vm/x86_32.ad ! src/cpu/x86/vm/x86_64.ad Changeset: 1747f04ad0c4 Author: never Date: 2010-05-24 13:53 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/1747f04ad0c4 6490487: java support on 64 bit solaris x86 machines is broken. Reviewed-by: kvn, kamg ! make/solaris/makefiles/defs.make Changeset: f9a202dd8899 Author: never Date: 2010-05-25 13:18 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/f9a202dd8899 Merge Changeset: de91a2f25c7e Author: jrose Date: 2010-05-27 09:54 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/de91a2f25c7e 6956164: nightly regressions from 6939207 Summary: Fix errors in 6939207. Reviewed-by: kvn ! src/share/vm/classfile/verifier.cpp ! src/share/vm/classfile/verifier.hpp ! src/share/vm/interpreter/bytecodeStream.hpp ! src/share/vm/interpreter/bytecodes.cpp ! src/share/vm/interpreter/bytecodes.hpp Changeset: 2d127394260e Author: kvn Date: 2010-05-27 18:01 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/2d127394260e 6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb Summary: Added new product ObjectAlignmentInBytes flag to control object alignment. Reviewed-by: twisti, ysr, iveresov ! agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java ! agent/src/share/classes/sun/jvm/hotspot/oops/Oop.java ! agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java ! src/cpu/sparc/vm/copy_sparc.hpp ! src/cpu/sparc/vm/sparc.ad ! src/cpu/x86/vm/assembler_x86.cpp ! src/cpu/x86/vm/x86_64.ad ! src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp ! src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp ! src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp ! src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp ! src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp ! src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp ! src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp ! src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp ! src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp ! src/share/vm/gc_interface/collectedHeap.cpp ! src/share/vm/memory/space.cpp ! src/share/vm/memory/threadLocalAllocBuffer.inline.hpp ! src/share/vm/memory/universe.cpp ! src/share/vm/oops/arrayOop.hpp ! src/share/vm/oops/oop.hpp ! src/share/vm/oops/oop.inline.hpp ! src/share/vm/runtime/arguments.cpp ! src/share/vm/runtime/globals.hpp ! src/share/vm/runtime/vmStructs.cpp ! src/share/vm/utilities/copy.hpp ! src/share/vm/utilities/globalDefinitions.cpp ! src/share/vm/utilities/globalDefinitions.hpp Changeset: 87fc6aca31ab Author: iveresov Date: 2010-05-27 22:01 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/87fc6aca31ab 6955349: C1: Make G1 barriers work with x64 Summary: This fixes G1 barriers in c1 on x64. Reviewed-by: never ! src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp ! src/cpu/x86/vm/c1_LIRAssembler_x86.cpp ! src/cpu/x86/vm/c1_LIRGenerator_x86.cpp ! src/cpu/x86/vm/c1_Runtime1_x86.cpp ! src/share/vm/c1/c1_LIR.hpp ! src/share/vm/c1/c1_LIRGenerator.cpp Changeset: beb77f0d41b3 Author: jrose Date: 2010-05-28 16:23 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/beb77f0d41b3 6957004: MethodComparator uses the wrong CP index accessor Summary: Change two uses of get_index_u2 to get_index_u2_cpcache; also tweak some debugging print functions Reviewed-by: kvn ! src/share/vm/oops/constantPoolKlass.cpp ! src/share/vm/oops/methodKlass.cpp ! src/share/vm/prims/methodComparator.cpp Changeset: 1eb493f33423 Author: jrose Date: 2010-05-29 19:22 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/1eb493f33423 6957080: MethodComparator needs stress testing Summary: Add a stress-test flag for running MethodComparator over many inputs. Fix bugs that crop up. Reviewed-by: kvn ! src/share/vm/includeDB_core ! src/share/vm/interpreter/bytecode.cpp ! src/share/vm/interpreter/rewriter.cpp ! src/share/vm/prims/methodComparator.cpp ! src/share/vm/runtime/globals.hpp Changeset: 3657cb01ffc5 Author: kvn Date: 2010-06-02 09:49 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/3657cb01ffc5 6954029: Improve implicit null check generation with compressed oops Summary: Hoist DecodeN instruction above null check Reviewed-by: never, twisti ! src/cpu/sparc/vm/sparc.ad ! src/cpu/sparc/vm/vm_version_sparc.cpp ! src/cpu/x86/vm/x86_32.ad ! src/cpu/x86/vm/x86_64.ad ! src/share/vm/opto/compile.cpp ! src/share/vm/opto/connode.cpp ! src/share/vm/opto/lcm.cpp ! src/share/vm/opto/matcher.cpp ! src/share/vm/opto/matcher.hpp Changeset: 4a2e260bb13a Author: kvn Date: 2010-06-02 12:02 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/4a2e260bb13a 6957882: nsk/sajdi tests failed with NullPointerException Summary: VM.getObjectAlignmentInBytes() accesses intxType before it is created. Reviewed-by: never ! agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Changeset: 852d0157c696 Author: never Date: 2010-06-02 14:23 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/852d0157c696 6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint Reviewed-by: kvn, dcubed ! src/share/vm/code/nmethod.cpp ! src/share/vm/prims/jvmtiExport.cpp ! src/share/vm/prims/jvmtiExport.hpp Changeset: ca3dceda776c Author: never Date: 2010-06-02 20:15 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/ca3dceda776c 6930994: Code cache is full warning should be visible in product Reviewed-by: kvn, twisti, ysr ! src/share/vm/compiler/compileBroker.cpp Changeset: e9ff18c4ace7 Author: jrose Date: 2010-06-02 22:45 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/e9ff18c4ace7 Merge ! agent/src/share/classes/sun/jvm/hotspot/code/CodeBlob.java ! agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java ! agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java ! agent/src/share/classes/sun/jvm/hotspot/oops/Oop.java ! agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java ! agent/src/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java ! make/solaris/makefiles/defs.make ! src/cpu/sparc/vm/assembler_sparc.hpp ! src/cpu/sparc/vm/c1_FrameMap_sparc.cpp ! src/cpu/sparc/vm/c1_FrameMap_sparc.hpp ! src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp ! src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp ! src/cpu/sparc/vm/c1_Runtime1_sparc.cpp ! src/cpu/sparc/vm/copy_sparc.hpp ! src/cpu/sparc/vm/frame_sparc.cpp ! src/cpu/sparc/vm/interp_masm_sparc.cpp ! src/cpu/sparc/vm/interp_masm_sparc.hpp ! src/cpu/sparc/vm/methodHandles_sparc.cpp ! src/cpu/sparc/vm/nativeInst_sparc.cpp ! src/cpu/sparc/vm/register_definitions_sparc.cpp ! src/cpu/sparc/vm/runtime_sparc.cpp ! src/cpu/sparc/vm/sharedRuntime_sparc.cpp ! src/cpu/sparc/vm/sparc.ad ! src/cpu/sparc/vm/stubGenerator_sparc.cpp ! src/cpu/sparc/vm/stubRoutines_sparc.hpp ! src/cpu/sparc/vm/templateInterpreter_sparc.cpp ! src/cpu/sparc/vm/templateTable_sparc.cpp ! src/cpu/sparc/vm/vm_version_sparc.cpp ! src/cpu/x86/vm/assembler_x86.cpp ! src/cpu/x86/vm/assembler_x86.hpp ! src/cpu/x86/vm/c1_FrameMap_x86.cpp ! src/cpu/x86/vm/c1_FrameMap_x86.hpp ! src/cpu/x86/vm/c1_LIRAssembler_x86.cpp ! src/cpu/x86/vm/c1_LIRGenerator_x86.cpp ! src/cpu/x86/vm/c1_Runtime1_x86.cpp ! src/cpu/x86/vm/interp_masm_x86_32.cpp ! src/cpu/x86/vm/interp_masm_x86_32.hpp ! src/cpu/x86/vm/interp_masm_x86_64.cpp ! src/cpu/x86/vm/interp_masm_x86_64.hpp ! src/cpu/x86/vm/register_definitions_x86.cpp ! src/cpu/x86/vm/runtime_x86_32.cpp ! src/cpu/x86/vm/sharedRuntime_x86_64.cpp ! src/cpu/x86/vm/templateInterpreter_x86_32.cpp ! src/cpu/x86/vm/templateInterpreter_x86_64.cpp ! src/cpu/x86/vm/templateTable_x86_32.cpp ! src/cpu/x86/vm/templateTable_x86_64.cpp ! src/cpu/x86/vm/x86_32.ad ! src/cpu/x86/vm/x86_64.ad ! src/os/solaris/dtrace/generateJvmOffsets.cpp ! src/os/solaris/dtrace/libjvm_db.c ! src/share/vm/asm/codeBuffer.hpp ! src/share/vm/c1/c1_FrameMap.hpp ! src/share/vm/c1/c1_GraphBuilder.cpp ! src/share/vm/c1/c1_IR.cpp ! src/share/vm/c1/c1_IR.hpp ! src/share/vm/c1/c1_LIR.cpp ! src/share/vm/c1/c1_LIR.hpp ! src/share/vm/c1/c1_LIRAssembler.cpp ! src/share/vm/c1/c1_LIRAssembler.hpp ! src/share/vm/c1/c1_LIRGenerator.cpp ! src/share/vm/ci/ciMethod.cpp ! src/share/vm/ci/ciStreams.cpp ! src/share/vm/ci/ciStreams.hpp ! src/share/vm/ci/ciTypeFlow.cpp ! src/share/vm/classfile/verifier.cpp ! src/share/vm/classfile/verifier.hpp ! src/share/vm/code/codeBlob.cpp ! src/share/vm/code/codeBlob.hpp ! src/share/vm/code/codeCache.cpp ! src/share/vm/code/compiledIC.cpp ! src/share/vm/code/nmethod.cpp ! src/share/vm/code/nmethod.hpp ! src/share/vm/code/oopRecorder.cpp ! src/share/vm/code/oopRecorder.hpp ! src/share/vm/code/relocInfo.cpp ! src/share/vm/code/relocInfo.hpp ! src/share/vm/compiler/compileBroker.cpp ! src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp ! src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp ! src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp ! src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp ! src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp ! src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp ! src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp ! src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp ! src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp ! src/share/vm/gc_interface/collectedHeap.cpp ! src/share/vm/includeDB_core ! src/share/vm/interpreter/bytecode.cpp ! src/share/vm/interpreter/bytecode.hpp ! src/share/vm/interpreter/bytecodeStream.cpp ! src/share/vm/interpreter/bytecodeStream.hpp ! src/share/vm/interpreter/bytecodeTracer.cpp ! src/share/vm/interpreter/bytecodes.cpp ! src/share/vm/interpreter/bytecodes.hpp ! src/share/vm/interpreter/interpreter.cpp ! src/share/vm/interpreter/interpreterRuntime.cpp ! src/share/vm/interpreter/interpreterRuntime.hpp ! src/share/vm/interpreter/rewriter.cpp ! src/share/vm/interpreter/rewriter.hpp ! src/share/vm/interpreter/templateTable.cpp ! src/share/vm/interpreter/templateTable.hpp ! src/share/vm/memory/iterator.cpp ! src/share/vm/memory/space.cpp ! src/share/vm/memory/threadLocalAllocBuffer.inline.hpp ! src/share/vm/memory/universe.cpp ! src/share/vm/oops/arrayOop.hpp ! src/share/vm/oops/constantPoolKlass.cpp ! src/share/vm/oops/constantPoolOop.cpp ! src/share/vm/oops/constantPoolOop.hpp ! src/share/vm/oops/generateOopMap.cpp ! src/share/vm/oops/methodKlass.cpp ! src/share/vm/oops/oop.hpp ! src/share/vm/oops/oop.inline.hpp ! src/share/vm/opto/bytecodeInfo.cpp ! src/share/vm/opto/compile.cpp ! src/share/vm/opto/connode.cpp ! src/share/vm/opto/lcm.cpp ! src/share/vm/opto/matcher.cpp ! src/share/vm/opto/matcher.hpp ! src/share/vm/opto/parse2.cpp ! src/share/vm/prims/jvmtiClassFileReconstituter.cpp ! src/share/vm/prims/jvmtiExport.cpp ! src/share/vm/prims/jvmtiExport.hpp ! src/share/vm/prims/methodComparator.cpp ! src/share/vm/prims/methodHandleWalk.cpp ! src/share/vm/runtime/arguments.cpp ! src/share/vm/runtime/globals.hpp ! src/share/vm/runtime/sharedRuntime.cpp ! src/share/vm/runtime/vmStructs.cpp ! src/share/vm/utilities/copy.hpp ! src/share/vm/utilities/globalDefinitions.cpp ! src/share/vm/utilities/globalDefinitions.hpp Changeset: f56e28f22410 Author: trims Date: 2010-06-03 18:18 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/f56e28f22410 6958458: Bump the HS19 build number to 03 Summary: Update the HS19 build number to 03 Reviewed-by: jcoomes ! make/hotspot_version Changeset: 606df121c181 Author: trims Date: 2010-06-04 11:54 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/606df121c181 Merge Changeset: c69846936352 Author: trims Date: 2010-06-17 23:59 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/c69846936352 Merge Changeset: 02e771df338e Author: kvn Date: 2010-06-03 14:20 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/02e771df338e 6958254: -XX:+VerifyOops is broken on x86 Summary: save and restore r10 in verify_oop(). Reviewed-by: never ! src/cpu/x86/vm/assembler_x86.cpp ! src/cpu/x86/vm/stubGenerator_x86_64.cpp Changeset: b812ff5abc73 Author: iveresov Date: 2010-06-04 11:18 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/b812ff5abc73 6958292: C1: Enable parallel compilation Summary: Enable parallel compilation in C1 Reviewed-by: never, kvn ! src/cpu/sparc/vm/c1_FrameMap_sparc.cpp ! src/cpu/x86/vm/c1_FrameMap_x86.cpp ! src/share/vm/c1/c1_Canonicalizer.cpp ! src/share/vm/c1/c1_Compilation.cpp ! src/share/vm/c1/c1_Compilation.hpp ! src/share/vm/c1/c1_Compiler.cpp ! src/share/vm/c1/c1_Compiler.hpp ! src/share/vm/c1/c1_FrameMap.cpp ! src/share/vm/c1/c1_FrameMap.hpp ! src/share/vm/c1/c1_GraphBuilder.cpp ! src/share/vm/c1/c1_GraphBuilder.hpp ! src/share/vm/c1/c1_IR.cpp ! src/share/vm/c1/c1_IR.hpp ! src/share/vm/c1/c1_Instruction.cpp ! src/share/vm/c1/c1_Instruction.hpp ! src/share/vm/c1/c1_LIRGenerator.cpp ! src/share/vm/c1/c1_LinearScan.cpp ! src/share/vm/c1/c1_LinearScan.hpp ! src/share/vm/c1/c1_Optimizer.cpp ! src/share/vm/c1/c1_Runtime1.cpp ! src/share/vm/c1/c1_Runtime1.hpp ! src/share/vm/c1/c1_ValueStack.cpp ! src/share/vm/c1/c1_ValueStack.hpp ! src/share/vm/c1/c1_ValueType.cpp ! src/share/vm/c1/c1_ValueType.hpp ! src/share/vm/includeDB_compiler1 ! src/share/vm/runtime/mutexLocker.cpp ! src/share/vm/runtime/mutexLocker.hpp ! src/share/vm/runtime/thread.cpp ! src/share/vm/runtime/thread.hpp Changeset: 49fac4acd688 Author: never Date: 2010-06-07 14:17 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/49fac4acd688 6958485: fix for 6879921 was insufficient Reviewed-by: kvn ! src/share/vm/opto/superword.cpp + test/compiler/6958485/Test.java Changeset: 086d73ccd6c0 Author: kamg Date: 2010-05-27 17:06 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/086d73ccd6c0 6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases Summary: Check NameAndType_info signatures aggressively, even when unreferenced Reviewed-by: coleenp, acorn, never ! src/share/vm/classfile/classFileParser.cpp ! src/share/vm/classfile/classFileParser.hpp Changeset: b96a3e44582f Author: acorn Date: 2010-06-03 13:21 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/b96a3e44582f 6852873: Reduce safepoint cleanup time Summary: New optional flags to reduce inflated monitor cleanup times Reviewed-by: chrisphi, dice ! src/share/vm/runtime/globals.hpp ! src/share/vm/runtime/synchronizer.cpp ! src/share/vm/runtime/synchronizer.hpp ! src/share/vm/runtime/thread.cpp ! src/share/vm/runtime/thread.hpp Changeset: be0d50d3de2a Author: acorn Date: 2010-06-03 13:34 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/be0d50d3de2a Merge Changeset: 3a9de63b2209 Author: coleenp Date: 2010-06-04 17:44 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/3a9de63b2209 Merge ! src/share/vm/classfile/classFileParser.cpp ! src/share/vm/classfile/classFileParser.hpp ! src/share/vm/runtime/globals.hpp ! src/share/vm/runtime/synchronizer.cpp ! src/share/vm/runtime/synchronizer.hpp ! src/share/vm/runtime/thread.cpp ! src/share/vm/runtime/thread.hpp Changeset: b17deadc902e Author: coleenp Date: 2010-06-09 13:53 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/b17deadc902e Merge ! src/share/vm/runtime/thread.cpp ! src/share/vm/runtime/thread.hpp Changeset: f16f1d7893de Author: johnc Date: 2010-05-24 17:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/f16f1d7893de 6941378: G1: change default value of G1UseFixedWindowMMUTracker to true Summary: Rather than changing the default value of the G1UseFixedWindowMMUTracker, the flag and associated guarantee have been removed. Reviewed-by: jcoomes, tonyp, ysr ! src/share/vm/gc_implementation/g1/g1MMUTracker.cpp ! src/share/vm/gc_implementation/g1/g1_globals.hpp Changeset: 5b77884bd4b7 Author: jcoomes Date: 2010-05-27 13:09 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/5b77884bd4b7 6956472: test/runtime/6888954/vmerrors.sh uses ksh-specific syntax Reviewed-by: jmelvin, kvn ! test/runtime/6888954/vmerrors.sh Changeset: 2458a1f25356 Author: johnc Date: 2010-06-07 17:46 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/2458a1f25356 6953058: G1: A bigapp crashes with SIGSEGV in compiled code Summary: In C2's G1 post write barrier, the loads of the buffer and index fields from the DirtyCardQueue structure may be moved across a safepoint. Use the current value of "control" in the C2 IR to limit how far these loads can move. Reviewed-by: never, iveresov, kvn ! src/share/vm/opto/graphKit.cpp Changeset: b9bc732be7c0 Author: jmasa Date: 2010-06-10 08:27 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/b9bc732be7c0 Merge ! src/share/vm/gc_implementation/g1/g1MMUTracker.cpp ! src/share/vm/gc_implementation/g1/g1_globals.hpp ! src/share/vm/opto/graphKit.cpp Changeset: e848dd13e1b6 Author: trims Date: 2010-06-18 00:09 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/e848dd13e1b6 Merge Changeset: 6a236384a379 Author: trims Date: 2010-06-18 00:19 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/6a236384a379 Merge Changeset: b34c75c0b6b8 Author: mikejwre Date: 2010-06-24 20:03 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/b34c75c0b6b8 Added tag jdk7-b99 for changeset 6a236384a379 ! .hgtags From lana.steuck at oracle.com Thu Jul 1 00:19:22 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Thu, 01 Jul 2010 00:19:22 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/jaxp: 7 new changesets Message-ID: <20100701001922.95F5A47673@hg.openjdk.java.net> Changeset: d4adf4f2d14c Author: mikejwre Date: 2010-06-10 13:59 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxp/rev/d4adf4f2d14c Added tag jdk7-b97 for changeset ca01ec32561f ! .hgtags Changeset: 7ef8469021fb Author: mikejwre Date: 2010-06-17 16:28 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxp/rev/7ef8469021fb Added tag jdk7-b98 for changeset d4adf4f2d14c ! .hgtags Changeset: 69a11eec2789 Author: mikejwre Date: 2010-06-24 20:03 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxp/rev/69a11eec2789 Added tag jdk7-b99 for changeset 7ef8469021fb ! .hgtags Changeset: 214f47923c24 Author: ohair Date: 2010-06-17 10:43 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxp/rev/214f47923c24 6955301: Update names and references to rebranded drop bundles (jaxp, jaxws, jaf) Reviewed-by: darcy ! jaxp.properties Changeset: 961ad5ff3b19 Author: ohair Date: 2010-06-17 10:50 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxp/rev/961ad5ff3b19 6955292: Workaround ant 1.7.1 package-info.java issue in ant scripts 6960333: Add make level ALLOW_DOWNLOADS=true option 6940241: Change jaxp/jaxws so that the http downloads are not done by default Reviewed-by: darcy ! build-defs.xml ! build-drop-template.xml ! build.properties ! build.xml ! make/Makefile Changeset: 478835e100cd Author: lana Date: 2010-06-21 22:07 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxp/rev/478835e100cd Merge Changeset: d524be5ef62e Author: lana Date: 2010-06-29 22:31 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxp/rev/d524be5ef62e Merge From lana.steuck at oracle.com Thu Jul 1 00:19:27 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Thu, 01 Jul 2010 00:19:27 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/jaxws: 7 new changesets Message-ID: <20100701001927.3D22E47674@hg.openjdk.java.net> Changeset: 457109807109 Author: mikejwre Date: 2010-06-10 13:59 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxws/rev/457109807109 Added tag jdk7-b97 for changeset dac23846092a ! .hgtags Changeset: 818366ce23d8 Author: mikejwre Date: 2010-06-17 16:28 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxws/rev/818366ce23d8 Added tag jdk7-b98 for changeset 457109807109 ! .hgtags Changeset: 5bca7bc114a0 Author: mikejwre Date: 2010-06-24 20:03 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxws/rev/5bca7bc114a0 Added tag jdk7-b99 for changeset 818366ce23d8 ! .hgtags Changeset: 38fd32b8e990 Author: ohair Date: 2010-06-17 17:18 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxws/rev/38fd32b8e990 6869741: Integrate JAX-WS 2.2 and JAXB 2.2 in JDK 7 Reviewed-by: darcy, ramap ! jaxws.properties Changeset: 48872561d4b1 Author: ohair Date: 2010-06-17 17:19 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxws/rev/48872561d4b1 6955292: Workaround ant 1.7.1 package-info.java issue in ant scripts 6940241: Change jaxp/jaxws so that the http downloads are not done by default 6960333: Add make level ALLOW_DOWNLOADS=true option Reviewed-by: darcy, ramap ! build-defs.xml ! build-drop-template.xml ! build.properties ! build.xml ! make/Makefile Changeset: db63f482182d Author: lana Date: 2010-06-21 22:07 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxws/rev/db63f482182d Merge Changeset: bd26d0ce0c3c Author: lana Date: 2010-06-29 22:31 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxws/rev/bd26d0ce0c3c Merge From lana.steuck at oracle.com Thu Jul 1 00:21:05 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Thu, 01 Jul 2010 00:21:05 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/jdk: 75 new changesets Message-ID: <20100701003337.4BC6647675@hg.openjdk.java.net> Changeset: 6568c84116bb Author: mikejwre Date: 2010-06-10 13:59 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/6568c84116bb Added tag jdk7-b97 for changeset b1903d7528d3 ! .hgtags Changeset: 57293ed264c4 Author: prr Date: 2010-06-14 10:37 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/57293ed264c4 6961061: make/tools/freetypecheck doesn't build with VS2010 : breaks openjdk builds Reviewed-by: ohair ! make/tools/freetypecheck/freetypecheck.c Changeset: 6cc8d40d94e7 Author: prr Date: 2010-06-16 09:42 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/6cc8d40d94e7 6961079: Build JDK7 for 64 bit Windows using free Windows 7.1 SDK 64 bit compilers Reviewed-by: ohair, jcoomes ! make/common/shared/Defs-windows.gmk Changeset: 82593186fa54 Author: mikejwre Date: 2010-06-16 15:49 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/82593186fa54 Merge Changeset: 9c0586509d75 Author: mikejwre Date: 2010-06-17 16:28 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/9c0586509d75 Added tag jdk7-b98 for changeset 82593186fa54 ! .hgtags Changeset: 0cd764a1c809 Author: jrose Date: 2010-04-30 23:48 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/0cd764a1c809 6939134: JSR 292 adjustments to method handle invocation Summary: split MethodHandle.invoke into invokeExact and invokeGeneric; also clean up JVM-to-Java interfaces Reviewed-by: twisti ! src/share/classes/java/dyn/CallSite.java ! src/share/classes/java/dyn/InvokeDynamic.java ! src/share/classes/java/dyn/InvokeDynamicBootstrapError.java ! src/share/classes/java/dyn/JavaMethodHandle.java ! src/share/classes/java/dyn/Linkage.java ! src/share/classes/java/dyn/LinkagePermission.java ! src/share/classes/java/dyn/MethodHandle.java ! src/share/classes/java/dyn/MethodHandles.java ! src/share/classes/java/dyn/MethodType.java ! src/share/classes/java/dyn/NoAccessException.java ! src/share/classes/java/dyn/package-info.java ! src/share/classes/sun/dyn/AdapterMethodHandle.java ! src/share/classes/sun/dyn/BoundMethodHandle.java ! src/share/classes/sun/dyn/CallSiteImpl.java ! src/share/classes/sun/dyn/FilterGeneric.java ! src/share/classes/sun/dyn/FilterOneArgument.java ! src/share/classes/sun/dyn/FromGeneric.java ! src/share/classes/sun/dyn/MemberName.java ! src/share/classes/sun/dyn/MethodHandleImpl.java ! src/share/classes/sun/dyn/MethodHandleNatives.java ! src/share/classes/sun/dyn/MethodTypeImpl.java ! src/share/classes/sun/dyn/SpreadGeneric.java ! src/share/classes/sun/dyn/ToGeneric.java ! src/share/classes/sun/dyn/package-info.java ! src/share/classes/sun/dyn/util/ValueConversions.java ! src/share/classes/sun/dyn/util/VerifyAccess.java ! test/java/dyn/MethodHandlesTest.java Changeset: 4a28a204b726 Author: jrose Date: 2010-05-03 23:32 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/4a28a204b726 6939196: method handle signatures off the boot class path get linkage errors Summary: Remove workaround from MethodHandleImpl lookup code; add JUnit regression test to MethodHandlesTest. Reviewed-by: twisti ! src/share/classes/sun/dyn/MethodHandleImpl.java ! test/java/dyn/MethodHandlesTest.java Changeset: 3cf85945abef Author: jrose Date: 2010-05-13 20:01 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/3cf85945abef Merge Changeset: d742045bd30b Author: jrose Date: 2010-06-18 15:23 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/d742045bd30b Merge ! src/share/classes/java/dyn/CallSite.java ! src/share/classes/java/dyn/InvokeDynamic.java ! src/share/classes/java/dyn/InvokeDynamicBootstrapError.java ! src/share/classes/java/dyn/JavaMethodHandle.java ! src/share/classes/java/dyn/Linkage.java ! src/share/classes/java/dyn/LinkagePermission.java ! src/share/classes/java/dyn/MethodHandle.java ! src/share/classes/java/dyn/MethodHandles.java ! src/share/classes/java/dyn/MethodType.java ! src/share/classes/java/dyn/NoAccessException.java ! src/share/classes/java/dyn/package-info.java ! src/share/classes/sun/dyn/AdapterMethodHandle.java ! src/share/classes/sun/dyn/BoundMethodHandle.java ! src/share/classes/sun/dyn/CallSiteImpl.java ! src/share/classes/sun/dyn/FilterGeneric.java ! src/share/classes/sun/dyn/FilterOneArgument.java ! src/share/classes/sun/dyn/FromGeneric.java ! src/share/classes/sun/dyn/MemberName.java ! src/share/classes/sun/dyn/MethodHandleImpl.java ! src/share/classes/sun/dyn/MethodHandleNatives.java ! src/share/classes/sun/dyn/MethodTypeImpl.java ! src/share/classes/sun/dyn/SpreadGeneric.java ! src/share/classes/sun/dyn/ToGeneric.java ! src/share/classes/sun/dyn/package-info.java ! src/share/classes/sun/dyn/util/ValueConversions.java ! src/share/classes/sun/dyn/util/VerifyAccess.java ! test/java/dyn/MethodHandlesTest.java Changeset: 3d944ecfa470 Author: jrose Date: 2010-06-08 23:08 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/3d944ecfa470 6939203: JSR 292 needs method handle constants Summary: Add new CP types CONSTANT_MethodHandle, CONSTANT_MethodType to verifier; put in runtime support upcall. Reviewed-by: twisti ! src/share/classes/java/dyn/MethodHandles.java ! src/share/classes/sun/dyn/MethodHandleNatives.java ! src/share/javavm/export/classfile_constants.h ! src/share/native/common/check_code.c ! test/java/dyn/MethodHandlesTest.java Changeset: 2587c9f0b60d Author: jrose Date: 2010-06-19 01:14 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/2587c9f0b60d Merge ! src/share/classes/java/dyn/MethodHandles.java ! src/share/classes/sun/dyn/MethodHandleNatives.java ! src/share/javavm/export/classfile_constants.h ! src/share/native/common/check_code.c ! test/java/dyn/MethodHandlesTest.java Changeset: 3956cdee6712 Author: mikejwre Date: 2010-06-24 20:03 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/3956cdee6712 Added tag jdk7-b99 for changeset 2587c9f0b60d ! .hgtags Changeset: 31d25fccdf1c Author: lana Date: 2010-06-21 22:04 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/31d25fccdf1c Merge Changeset: c02096d7b70e Author: anthony Date: 2010-06-16 11:26 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/c02096d7b70e 6959787: java/awt/FileDialog/FilenameFilterTest/FilenameFilterTest.html failed on 7b94 Summary: Add a delay to the test to make sure the filename filters are called. Reviewed-by: dcherepanov, art ! test/java/awt/FileDialog/FilenameFilterTest/FilenameFilterTest.java Changeset: fa06ad055c43 Author: coffeys Date: 2010-06-16 16:15 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/fa06ad055c43 6860491: WRAP_TIME_MILLIS incorrectly set Summary: Alter WRAP_TIME_MILLIS to be unsigned Reviewed-by: yan ! src/solaris/classes/sun/awt/X11/XToolkit.java Changeset: 8722b75c9ccd Author: anthony Date: 2010-06-18 17:09 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/8722b75c9ccd 6959165: JVM crash during execution FileDialogBufferOverflowTest.html Summary: Add proper synchronization Reviewed-by: art, dcherepanov ! src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c Changeset: 05eb107d6891 Author: anthony Date: 2010-06-18 17:13 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/05eb107d6891 6961754: JCK tests CvsEventTest0001 and CvsEventTest0002 fail under FF 3.5 on OEL 5 Summary: Check the return value of XlibUtil.translateCoordinates() for null Reviewed-by: art, dcherepanov ! src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java ! src/solaris/classes/sun/awt/X11/XToolkit.java Changeset: ae16c200341a Author: lana Date: 2010-06-21 22:05 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/ae16c200341a Merge Changeset: ad5f65797249 Author: rupashka Date: 2010-06-02 11:59 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/ad5f65797249 6857057: api/javax_swing/text/GlyphView/index.html#Methods test fails Reviewed-by: peterz ! src/share/classes/javax/swing/text/Utilities.java ! src/share/classes/javax/swing/text/WrappedPlainView.java + test/javax/swing/text/WrappedPlainView/6857057/StubBranchElement.java + test/javax/swing/text/WrappedPlainView/6857057/StubLeafElement.java + test/javax/swing/text/WrappedPlainView/6857057/bug6857057.java Changeset: dc14ee238fe3 Author: rupashka Date: 2010-06-02 12:53 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/dc14ee238fe3 6636983: Japanese text does not display correctly in a JEditorPane Reviewed-by: peterz ! src/share/classes/javax/swing/text/DefaultStyledDocument.java ! src/share/classes/javax/swing/text/GlyphView.java ! src/share/classes/javax/swing/text/html/HTMLDocument.java ! src/share/classes/sun/swing/SwingUtilities2.java + test/javax/swing/text/DefaultStyledDocument/6636983/bug6636983.java Changeset: d1c875d94263 Author: lana Date: 2010-06-10 14:18 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/d1c875d94263 Merge - src/share/classes/sun/security/tools/PolicyTool.java Changeset: 7a3d8fc0d2cd Author: malenkov Date: 2010-06-15 17:39 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/7a3d8fc0d2cd 5066685: BorderFactory lacks SoftBevelBorder support Reviewed-by: alexp ! src/share/classes/javax/swing/BorderFactory.java Changeset: cf13f6389bdd Author: alexp Date: 2010-06-15 19:05 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/cf13f6389bdd 6788484: NPE in DefaultTableCellHeaderRenderer.getColumnSortOrder() with null table Reviewed-by: rupashka ! src/share/classes/sun/swing/table/DefaultTableCellHeaderRenderer.java + test/javax/swing/JTable/6788484/bug6788484.java Changeset: 5e4969391538 Author: alexp Date: 2010-06-15 19:10 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/5e4969391538 6735259: NPE at WindowsComboBoxUI$XPComboBoxButton.getState(WindowsComboBoxUI.java:408) Reviewed-by: rupashka ! src/share/classes/com/sun/java/swing/plaf/windows/WindowsComboBoxUI.java Changeset: cd565c554dc6 Author: alexp Date: 2010-06-15 21:28 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/cd565c554dc6 6771547: SynthParser throws StringIndexOutOfBoundsException parsing custom ColorTypes Reviewed-by: rupashka ! src/share/classes/javax/swing/plaf/synth/SynthParser.java + test/javax/swing/plaf/synth/6771547/SynthTest.java + test/javax/swing/plaf/synth/6771547/synthconfig.xml Changeset: 4d93c409ce87 Author: alexp Date: 2010-06-15 21:32 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/4d93c409ce87 6739756: JToolBar leaves space for non-visible items under Nimbus L&F Reviewed-by: peterz ! src/share/classes/javax/swing/plaf/synth/SynthToolBarUI.java + test/javax/swing/plaf/synth/SynthToolBarUI/6739756/bug6739756.java Changeset: aaa62c1f221e Author: lana Date: 2010-06-21 22:06 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/aaa62c1f221e Merge Changeset: 17870c6c1d4e Author: alanb Date: 2010-06-02 09:29 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/17870c6c1d4e 6950927: Testcase failure sun/management/jmxremote/bootstrap/JvmstatCountersTest.java Reviewed-by: dholmes, dcubed ! src/solaris/classes/sun/tools/attach/LinuxVirtualMachine.java ! src/solaris/classes/sun/tools/attach/SolarisVirtualMachine.java Changeset: 6e57723b3519 Author: alanb Date: 2010-06-02 09:35 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/6e57723b3519 Merge Changeset: 1db252f307b6 Author: martin Date: 2010-06-02 17:53 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/1db252f307b6 6955840: ThreadLocalRandom bug - overriden setSeed(long) method is not invoked for java.util.Random(long) Summary: Allow setSeed only during construction Reviewed-by: dl, dholmes ! src/share/classes/java/util/concurrent/ThreadLocalRandom.java Changeset: ea8c57ec8409 Author: weijun Date: 2010-06-04 19:28 +0800 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/ea8c57ec8409 6951366: kerberos login failure on win2008 with AD set to win2000 compat mode Reviewed-by: valeriep, xuelei ! src/share/classes/sun/security/krb5/Credentials.java ! src/share/classes/sun/security/krb5/EncryptionKey.java ! src/share/classes/sun/security/krb5/KrbAsReq.java ! src/windows/classes/sun/security/krb5/internal/tools/Kinit.java ! test/sun/security/krb5/auto/Context.java ! test/sun/security/krb5/auto/KDC.java + test/sun/security/krb5/auto/W83.java Changeset: 489c1720757b Author: chegar Date: 2010-06-08 10:46 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/489c1720757b 6957375: java/net/ResponseCache getResponseCode and ResponseCacheTest fail after rebranding Reviewed-by: ohair, wetmore, alanb ! test/java/net/ResponseCache/file1.cache Changeset: a21e3a29ca9d Author: darcy Date: 2010-06-08 18:52 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/a21e3a29ca9d 6935997: Please add a nested throwable constructor to AssertionError Reviewed-by: martin, forax, wetmore ! src/share/classes/java/lang/AssertionError.java ! src/share/classes/java/security/Security.java Changeset: af68ad345389 Author: alanb Date: 2010-06-09 18:51 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/af68ad345389 6935563: (dc) Improve connection reset/port unreachable handling [win] Reviewed-by: chegar ! src/windows/native/sun/nio/ch/DatagramChannelImpl.c ! src/windows/native/sun/nio/ch/Net.c + test/java/nio/channels/DatagramChannel/SelectWhenRefused.java Changeset: 1474dfa499e3 Author: mchung Date: 2010-06-10 14:14 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/1474dfa499e3 6959965: jstat: Add new -classload option to print class loading statistics Summary: Add a new jstat -classload option Reviewed-by: alanb ! make/sun/tools/Makefile ! src/share/classes/sun/tools/jstat/Arguments.java ! src/share/classes/sun/tools/jstat/OptionFinder.java ! src/share/classes/sun/tools/jstat/OptionLister.java ! src/share/classes/sun/tools/jstat/resources/jstat_options + src/share/classes/sun/tools/jstat/resources/jstat_unsupported_options + test/sun/tools/jstat/classloadOutput1.awk + test/sun/tools/jstat/jstatClassloadOutput1.sh ! test/sun/tools/jstat/jstatOptions1.sh + test/sun/tools/jstat/options2.out Changeset: af827b7eb81d Author: mchung Date: 2010-06-10 14:21 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/af827b7eb81d Merge Changeset: f7a69b261b1d Author: martin Date: 2010-06-10 15:54 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/f7a69b261b1d 6960394: Stop linking with -lnsl on Linux Summary: Define LIBNSL (like LIBSOCKET), non-empty only on Solaris Reviewed-by: ohair ! make/common/Defs-linux.gmk ! make/common/Defs-solaris.gmk ! make/java/hpi/hpi_common.gmk ! make/java/java/Makefile ! make/java/java_hprof_demo/Makefile ! make/java/net/Makefile ! make/jpda/transport/socket/Makefile ! make/mkdemo/jvmti/hprof/Makefile ! src/share/demo/jvmti/hprof/sample.makefile.txt Changeset: aa8effe6bb54 Author: martin Date: 2010-06-10 15:55 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/aa8effe6bb54 6959259: Minor improvements to static Random field caching Summary: Cache fields in locals; small javadoc clarifications Reviewed-by: emcmanus, dholmes, forax, dl ! src/share/classes/java/lang/Math.java ! src/share/classes/java/lang/StrictMath.java ! src/share/classes/java/util/Collections.java Changeset: b1ec20722051 Author: weijun Date: 2010-06-11 11:38 +0800 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/b1ec20722051 6958869: regression: PKIXValidator fails when multiple trust anchors have same dn Reviewed-by: xuelei, wetmore, mullan ! src/share/classes/sun/security/validator/PKIXValidator.java ! test/sun/security/validator/CertReplace.java ! test/sun/security/validator/certreplace.sh + test/sun/security/validator/samedn.sh Changeset: 06699a990ac7 Author: alanb Date: 2010-06-11 14:31 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/06699a990ac7 6934585: TEST_BUG: java/nio/channels/AsynchronousSocketChannel/Basic.java Reviewed-by: chegar ! test/ProblemList.txt ! test/java/nio/channels/AsynchronousSocketChannel/Basic.java Changeset: 7079585d6e0e Author: alanb Date: 2010-06-11 14:47 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/7079585d6e0e 6938230: (so) SocketAdaptor.close() does not translate IOException resulting in Error Reviewed-by: chegar ! src/share/classes/sun/nio/ch/ServerSocketAdaptor.java ! src/share/classes/sun/nio/ch/SocketAdaptor.java Changeset: c849dc20dc85 Author: andrew Date: 2010-06-12 01:32 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/c849dc20dc85 6959197: When building with JAVAC_MAX_WARNINGS=true, the build fails in sun/nio/cs due to the use of -Werror Summary: Remove unneeded casts, add generic types and make better use of static data Reviewed-by: sherman ! make/sun/nio/cs/Makefile ! src/share/classes/sun/io/ByteToCharISO2022.java ! src/share/classes/sun/io/ByteToCharISO2022JP.java ! src/share/classes/sun/io/ByteToCharJISAutoDetect.java ! src/share/classes/sun/io/CharToBytePCK.java ! src/share/classes/sun/nio/cs/ext/DoubleByte.java ! src/share/classes/sun/nio/cs/ext/EUC_JP.java ! src/share/classes/sun/nio/cs/ext/EUC_JP_LINUX.java ! src/share/classes/sun/nio/cs/ext/EUC_JP_Open.java ! src/share/classes/sun/nio/cs/ext/EUC_TW.java ! src/share/classes/sun/nio/cs/ext/GB18030.java ! src/share/classes/sun/nio/cs/ext/HKSCS.java ! src/share/classes/sun/nio/cs/ext/ISO2022.java ! src/share/classes/sun/nio/cs/ext/JISAutoDetect.java ! src/share/classes/sun/nio/cs/ext/PCK.java ! src/share/classes/sun/nio/cs/ext/SJIS.java ! src/solaris/classes/sun/nio/cs/ext/COMPOUND_TEXT_Encoder.java ! src/solaris/classes/sun/nio/cs/ext/CompoundTextSupport.java Changeset: 422531c98ba5 Author: martin Date: 2010-06-11 18:55 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/422531c98ba5 6944584: Improvements to subprocess handling on Unix Summary: use thread pool for reaper thread; move most I/O operations out of reaper thread Reviewed-by: michaelm, hiroshi ! src/share/classes/java/lang/ProcessBuilder.java ! src/solaris/classes/java/lang/UNIXProcess.java.linux ! test/java/lang/ProcessBuilder/Basic.java Changeset: 5a61a4f65c9c Author: martin Date: 2010-06-13 17:19 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/5a61a4f65c9c 6960898: Regression due to src/share/classes/java/lang/ProcessBuilder.java changes Summary: Use Null{In,Out}putStream.INSTANCE as with Linux code Reviewed-by: ohair ! src/solaris/classes/java/lang/UNIXProcess.java.solaris ! src/windows/classes/java/lang/ProcessImpl.java Changeset: 76a9c90e9019 Author: alanb Date: 2010-06-15 10:03 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/76a9c90e9019 6961062: (dc) Several DatagramChannel tests timeout or fail with "address already in use" Reviewed-by: chegar ! test/ProblemList.txt ! test/java/nio/channels/DatagramChannel/Connect.java ! test/java/nio/channels/DatagramChannel/EmptyBuffer.java ! test/java/nio/channels/DatagramChannel/NoSender.java ! test/java/nio/channels/DatagramChannel/SRTest.java ! test/java/nio/channels/DatagramChannel/Sender.java Changeset: fb2d88134382 Author: mchung Date: 2010-06-14 14:44 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/fb2d88134382 6960789: com.sun.servicetag API needs to be added in ct.sym Summary: Include com.sun.servicetag classes when generating ct.sym Reviewed-by: alanb, jjg ! make/common/Release.gmk ! test/ProblemList.txt Changeset: c1f7ff3447ba Author: mchung Date: 2010-06-15 09:49 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/c1f7ff3447ba 6952161: Rebranding: Registration html for servicetag Summary: Rebrand register.html and jdk_header.png Reviewed-by: ohair, asaha, ogino, mfang ! src/share/classes/com/sun/servicetag/resources/jdk_header.png ! src/share/classes/com/sun/servicetag/resources/register.html ! src/share/classes/com/sun/servicetag/resources/register_ja.html ! src/share/classes/com/sun/servicetag/resources/register_zh_CN.html Changeset: 915ca65d1db7 Author: mchung Date: 2010-06-15 09:52 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/915ca65d1db7 Merge ! test/ProblemList.txt Changeset: 8d7438dede10 Author: mchung Date: 2010-06-15 09:54 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/8d7438dede10 6959641: testcase failing java/util/Locale/Bug4184873Test.java Summary: Revert the Bug4184873_{he,id,yi} files to revision 0 (before rebranding) Reviewed-by: naoto ! test/ProblemList.txt ! test/java/util/Locale/Bug4184873_he ! test/java/util/Locale/Bug4184873_id ! test/java/util/Locale/Bug4184873_yi Changeset: 72022d7d4578 Author: alanb Date: 2010-06-15 16:36 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/72022d7d4578 6932744: TEST_BUG: java/nio/channels/Selector/OpRead.java failing Reviewed-by: chegar ! test/ProblemList.txt ! test/java/nio/channels/Selector/OpRead.java Changeset: 91124d60b2ed Author: alanb Date: 2010-06-15 16:42 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/91124d60b2ed 6961358: TEST_BUG: java/nio/channels/SocketChannel/OpenLeak.java can't run in samevm mode Reviewed-by: chegar ! test/ProblemList.txt ! test/java/nio/channels/SocketChannel/OpenLeak.java Changeset: 125ec775c9d1 Author: alanb Date: 2010-06-15 21:43 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/125ec775c9d1 Merge ! test/ProblemList.txt Changeset: 1b7879ca3e74 Author: mchung Date: 2010-06-15 20:29 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/1b7879ca3e74 6961518: TEST_BUG: add @run main/othervm in tests that call setSecurityManager Summary: Mark tests to run in othervm Reviewed-by: ohair ! test/ProblemList.txt ! test/java/beans/Beans/Test4080522.java ! test/java/beans/EventHandler/Test6277246.java ! test/java/beans/EventHandler/Test6277266.java ! test/java/beans/Introspector/Test6277246.java ! test/java/lang/ClassLoader/UninitializedParent.java ! test/java/lang/ClassLoader/findSystemClass/Loader.java ! test/java/lang/System/IgnoreNullSecurityManager.java ! test/java/lang/annotation/ParameterAnnotations.java ! test/java/util/ResourceBundle/Bug6359330.java ! test/java/util/ResourceBundle/Test4300693.java Changeset: 55e512967525 Author: mchung Date: 2010-06-15 20:34 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/55e512967525 6961506: TEST_BUG: ResourceBundle/Bug4168625Test.java and TestBug4179766.java fails in samevm mode Summary: Set the proper parent class loader of Loader and SimpleLoader Reviewed-by: naoto ! test/ProblemList.txt ! test/java/util/ResourceBundle/Bug4168625Test.java ! test/java/util/ResourceBundle/TestBug4179766.java Changeset: 8a4557c5dfa1 Author: alanb Date: 2010-06-16 14:24 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/8a4557c5dfa1 6961630: TEST_BUG: Several SocketChannel and Selector tests can fail with "address already in use" Reviewed-by: chegar ! test/ProblemList.txt ! test/java/nio/channels/Selector/ByteServer.java ! test/java/nio/channels/Selector/CloseThenRegister.java ! test/java/nio/channels/Selector/ReadAfterConnect.java ! test/java/nio/channels/Selector/SelectAfterRead.java ! test/java/nio/channels/Selector/SelectWrite.java ! test/java/nio/channels/SocketChannel/BigReadWrite.java ! test/java/nio/channels/SocketChannel/VectorIO.java ! test/java/nio/channels/SocketChannel/Write.java ! test/java/nio/channels/spi/SelectorProvider/inheritedChannel/EchoTest.java Changeset: 8a286789de96 Author: ksrini Date: 2010-06-16 12:36 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/8a286789de96 6575373: Error verifying signatures of pack200 files in some cases Reviewed-by: jrose, forax ! src/share/classes/com/sun/java/util/jar/pack/PropMap.java ! src/share/classes/java/util/jar/Pack200.java ! test/tools/pack200/Pack200Test.java + test/tools/pack200/SegmentLimit.java Changeset: 705777f990cf Author: mchung Date: 2010-06-16 12:40 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/705777f990cf 6961502: TEST_BUG: test/java/lang/ClassLoader/defineClass/DefineClassByteBuffer.java fails Summary: Fix the test to define TestClass by DummyClassLoader as it intends to do Reviewed-by: alanb ! test/ProblemList.txt ! test/java/lang/ClassLoader/defineClass/DefineClassByteBuffer.java Changeset: 94404fea2067 Author: lana Date: 2010-06-16 14:07 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/94404fea2067 Merge - make/com/sun/inputmethods/Makefile - make/com/sun/inputmethods/indicim/Makefile - make/com/sun/inputmethods/thaiim/Makefile ! make/common/Defs-linux.gmk ! make/common/Defs-solaris.gmk ! make/common/Release.gmk - src/share/classes/com/sun/inputmethods/internal/indicim/DevanagariInputMethodDescriptor.java - src/share/classes/com/sun/inputmethods/internal/indicim/DevanagariTables.java - src/share/classes/com/sun/inputmethods/internal/indicim/IndicInputMethod.java - src/share/classes/com/sun/inputmethods/internal/indicim/IndicInputMethodImpl.java - src/share/classes/com/sun/inputmethods/internal/indicim/java.awt.im.spi.InputMethodDescriptor - src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames.properties - src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_de.properties - src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_es.properties - src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_fr.properties - src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_it.properties - src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_ja.properties - src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_ko.properties - src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_sv.properties - src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_zh_CN.properties - src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames_zh_TW.properties - src/share/classes/com/sun/inputmethods/internal/thaiim/ThaiInputMethod.java - src/share/classes/com/sun/inputmethods/internal/thaiim/ThaiInputMethodDescriptor.java - src/share/classes/com/sun/inputmethods/internal/thaiim/ThaiInputMethodImpl.java - src/share/classes/com/sun/inputmethods/internal/thaiim/ThaiRules.java - src/share/classes/com/sun/inputmethods/internal/thaiim/java.awt.im.spi.InputMethodDescriptor - src/share/classes/com/sun/inputmethods/internal/thaiim/resources/DisplayNames.properties ! src/share/classes/com/sun/servicetag/resources/register.html ! src/share/classes/com/sun/servicetag/resources/register_ja.html ! src/share/classes/com/sun/servicetag/resources/register_zh_CN.html - src/share/classes/javax/swing/text/html/parser/html32.bdtd ! test/java/util/ResourceBundle/Bug4168625Test.java Changeset: 3df25d0680f3 Author: weijun Date: 2010-06-17 13:46 +0800 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/3df25d0680f3 6959292: regression: cannot login if session key and preauth does not use the same etype Reviewed-by: xuelei, valeriep ! src/share/classes/sun/security/krb5/Credentials.java ! src/share/classes/sun/security/krb5/EncryptionKey.java ! src/share/classes/sun/security/krb5/KrbAsReq.java ! src/share/classes/sun/security/krb5/internal/KRBError.java ! src/windows/classes/sun/security/krb5/internal/tools/Kinit.java ! test/sun/security/krb5/auto/KDC.java ! test/sun/security/krb5/auto/W83.java Changeset: c995607e7719 Author: mchung Date: 2010-06-16 23:27 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/c995607e7719 6961408: test/java/util/logging/ParentLoggersTest.java fails in samevm mode Summary: Check against the list of loggers added since the test begins to run Reviewed-by: dcubed ! test/ProblemList.txt ! test/java/util/logging/ParentLoggersTest.java Changeset: 1281181df71b Author: alanb Date: 2010-06-17 17:49 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/1281181df71b 6395224: (so) SocketChannel writer blocked on large buffer is not preempted by close method (vista) Reviewed-by: chegar ! src/windows/native/sun/nio/ch/SocketDispatcher.c ! src/windows/native/sun/nio/ch/nio_util.h ! test/ProblemList.txt ! test/java/nio/channels/AsyncCloseAndInterrupt.java Changeset: 5e4547833379 Author: sherman Date: 2010-06-17 13:21 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/5e4547833379 6962067: TEST_BUG: Tests in java/util/zip/ZipFile leave file open Summary: Close zipfile and io stream when done Reviewed-by: alanb ! test/ProblemList.txt ! test/java/util/zip/InfoZip.java ! test/java/util/zip/ZipFile/Comment.java ! test/java/util/zip/ZipFile/CorruptedZipFiles.java ! test/java/util/zip/ZipFile/ManyEntries.java Changeset: 006e852b692e Author: ohair Date: 2010-06-17 14:42 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/006e852b692e 6869741: Integrate JAX-WS 2.2 and JAXB 2.2 in JDK 7 Reviewed-by: ramap ! make/docs/CORE_PKGS.gmk Changeset: 6c188df7bfef Author: alanb Date: 2010-06-18 16:16 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/6c188df7bfef 4981129: (dc) DatagramSocket created by DatagramChannel does not provide sender info Reviewed-by: chegar ! src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java ! test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java Changeset: 7526d0b9aab0 Author: mchung Date: 2010-06-18 09:35 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/7526d0b9aab0 6961894: TEST_BUG: jdk_lang tests fail in samevm mode Summary: Fixed jdk_lang tests to run in samevm mode or mark to run in othervm Reviewed-by: alanb ! test/ProblemList.txt ! test/java/lang/System/ExitFinalizersAndJIT.java ! test/java/lang/Thread/GenerifyStackTraces.java ! test/java/lang/Thread/StackTraces.java ! test/java/lang/management/ClassLoadingMXBean/LoadCounts.java ! test/java/lang/management/ManagementFactory/MXBeanProxyTest.java ! test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java ! test/java/lang/management/MemoryMXBean/LowMemoryTest.java ! test/java/lang/management/MemoryMXBean/MemoryManagement.java ! test/java/lang/management/MemoryMXBean/Pending.java ! test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java ! test/java/lang/management/MemoryPoolMXBean/ThresholdTest.java ! test/java/lang/management/RuntimeMXBean/UpTime.java ! test/java/lang/management/ThreadMXBean/AllThreadIds.java ! test/java/lang/management/ThreadMXBean/DisableTest.java ! test/java/lang/management/ThreadMXBean/EnableTest.java ! test/java/lang/management/ThreadMXBean/FindDeadlocks.java ! test/java/lang/management/ThreadMXBean/FindMonitorDeadlock.java ! test/java/lang/management/ThreadMXBean/Locks.java ! test/java/lang/reflect/Proxy/Boxing.java ! test/java/lang/reflect/Proxy/ClassRestrictions.java ! test/java/lang/reflect/Proxy/returnTypes/Test.java Changeset: ac93014a4d78 Author: alanb Date: 2010-06-18 20:59 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/ac93014a4d78 6962045: TEST_BUG: Tests in test/java/io/Serializable leave files open Reviewed-by: mchung ! test/ProblemList.txt ! test/java/io/Serializable/ClassCastExceptionDetail/Read.java ! test/java/io/Serializable/auditStreamSubclass/AuditStreamSubclass.java ! test/java/io/Serializable/backRefCNFException/Read.java ! test/java/io/Serializable/checkModifiers/CheckModifiers.java ! test/java/io/Serializable/classDescFlagConflict/Read.java ! test/java/io/Serializable/classDescHooks/ClassDescHooks.java ! test/java/io/Serializable/duplicateSerialFields/Test.java ! test/java/io/Serializable/enum/badResolve/Read.java ! test/java/io/Serializable/enum/constantSubclasses/Read.java ! test/java/io/Serializable/enum/missingConstant/Read.java ! test/java/io/Serializable/fieldTypeString/Read.java ! test/java/io/Serializable/illegalHandle/Test.java ! test/java/io/Serializable/longString/LongString.java ! test/java/io/Serializable/oldTests/AnnotateClass.java ! test/java/io/Serializable/oldTests/ArrayFields.java ! test/java/io/Serializable/oldTests/ArraysOfArrays.java ! test/java/io/Serializable/oldTests/BinaryTree.java ! test/java/io/Serializable/oldTests/CircularList.java ! test/java/io/Serializable/oldTests/SimpleArrays.java ! test/java/io/Serializable/oldTests/WritePrimitive.java ! test/java/io/Serializable/packageAccess/Test.java ! test/java/io/Serializable/parents/EvolvedClass.java ! test/java/io/Serializable/parents/OriginalClass.java ! test/java/io/Serializable/proxy/Basic.java ! test/java/io/Serializable/proxy/skipMissing/Read.java ! test/java/io/Serializable/proxy/skipMissing/Write.java ! test/java/io/Serializable/readObjectNoData/Read.java ! test/java/io/Serializable/skipWriteObject/Read.java ! test/java/io/Serializable/skippedObjCNFException/Read.java ! test/java/io/Serializable/stopCustomDeserialization/Read.java ! test/java/io/Serializable/unresolvedClassDesc/Read.java ! test/java/io/Serializable/unshared/Read.java ! test/java/io/Serializable/wrongReturnTypes/Read.java Changeset: 5919f0c72c0b Author: alanb Date: 2010-06-19 15:17 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/5919f0c72c0b 6962419: TEST_BUG: java_io tests fails in samevm mode Reviewed-by: ohair, sherman ! test/ProblemList.txt ! test/java/io/BufferedReader/BigMark.java ! test/java/io/BufferedReader/ReadLineSync.java ! test/java/io/DataInputStream/OpsAfterClose.java ! test/java/io/DataInputStream/ReadFully.java ! test/java/io/File/DeleteOnExit.java ! test/java/io/File/DeleteOnExitNPE.java ! test/java/io/File/IsHidden.java ! test/java/io/FileInputStream/LeadingSlash.java ! test/java/io/InputStream/OpsAfterClose.java ! test/java/io/InputStream/ReadParams.java ! test/java/io/InputStreamReader/GrowAfterEOF.java ! test/java/io/ObjectInputStream/ResolveProxyClass.java ! test/java/io/RandomAccessFile/EOF.java ! test/java/io/RandomAccessFile/ParameterCheck.java ! test/java/io/RandomAccessFile/ReadLine.java ! test/java/io/RandomAccessFile/Seek.java ! test/java/io/RandomAccessFile/WriteBytesChars.java ! test/java/io/RandomAccessFile/WriteUTF.java ! test/java/io/RandomAccessFile/skipBytes/SkipBytes.java ! test/java/io/Reader/Skip.java ! test/java/io/Reader/SkipNegative.java ! test/java/io/StreamTokenizer/Comment.java ! test/java/io/readBytes/ReadBytesBounds.java Changeset: 43dfa39686a1 Author: ksrini Date: 2010-06-19 17:42 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/43dfa39686a1 6712743: pack200: should default to 150.7 pack format for classfiles without any classes. Reviewed-by: jrose ! src/share/classes/com/sun/java/util/jar/pack/Constants.java ! src/share/classes/com/sun/java/util/jar/pack/Package.java ! src/share/classes/java/util/jar/Pack200.java + test/tools/pack200/PackageVersionTest.java Changeset: a086a3d98711 Author: ohair Date: 2010-06-20 14:51 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/a086a3d98711 6960853: Cleanup makefiles, remove unused vars etc. Reviewed-by: alanb ! make/common/shared/Defs-control.gmk ! make/netbeans/README ! make/netbeans/world/README ! make/netbeans/world/build.xml Changeset: 840265545bc3 Author: ohair Date: 2010-06-20 14:53 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/840265545bc3 6962617: Testcase changes, cleanup of problem list for jdk_tools targets Reviewed-by: alanb ! test/Makefile ! test/ProblemList.txt ! test/com/sun/jdi/PopAndInvokeTest.java ! test/com/sun/servicetag/JavaServiceTagTest1.java ! test/com/sun/servicetag/SystemRegistryTest.java ! test/com/sun/tools/attach/BasicTests.sh ! test/com/sun/tracing/BasicFunctionality.java ! test/sun/jvmstat/testlibrary/utils.sh ! test/sun/tools/jps/jps-Vvml_2.sh ! test/sun/tools/jps/jps-m_2.sh ! test/sun/tools/jstatd/jstatdDefaults.sh ! test/sun/tools/jstatd/jstatdExternalRegistry.sh ! test/sun/tools/jstatd/jstatdPort.sh ! test/sun/tools/jstatd/jstatdServerName.sh ! test/tools/jar/UpdateManifest.java ! test/tools/jar/index/MetaInf.java Changeset: 2366c2a5624c Author: mchung Date: 2010-06-20 19:56 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/2366c2a5624c 6962478: Privacy page referenced in register_ja.html is incorrect Summary: Fix the URL for the privacy page Reviewed-by: ogino ! src/share/classes/com/sun/servicetag/resources/register_ja.html Changeset: fe7271b4aeea Author: mchung Date: 2010-06-21 15:02 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/fe7271b4aeea 6962815: support enable and disable of the servicetag's system registry for testing purpose Summary: Allow the system registry to be disabled/enabled at runtime Reviewed-by: ksrini ! src/share/classes/com/sun/servicetag/Registry.java ! test/com/sun/servicetag/FindServiceTags.java ! test/com/sun/servicetag/JavaServiceTagTest1.java ! test/com/sun/servicetag/SystemRegistryTest.java ! test/com/sun/servicetag/Util.java Changeset: 5438223734aa Author: lana Date: 2010-06-21 22:08 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/5438223734aa Merge Changeset: 10a6319c9c15 Author: lana Date: 2010-06-29 22:34 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/10a6319c9c15 Merge Changeset: 4da6837dd085 Author: lana Date: 2010-06-30 15:09 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/4da6837dd085 Merge From lana.steuck at oracle.com Thu Jul 1 00:47:34 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Thu, 01 Jul 2010 00:47:34 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/langtools: 23 new changesets Message-ID: <20100701004815.DD7BF47677@hg.openjdk.java.net> Changeset: 3b38f3aa3dc3 Author: mikejwre Date: 2010-06-10 13:59 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/3b38f3aa3dc3 Added tag jdk7-b97 for changeset c0a41294297e ! .hgtags Changeset: ab1356297c67 Author: mikejwre Date: 2010-06-17 16:28 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/ab1356297c67 Added tag jdk7-b98 for changeset 3b38f3aa3dc3 ! .hgtags Changeset: f0e3ec1f9d9f Author: jrose Date: 2010-05-01 15:05 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/f0e3ec1f9d9f 6939134: JSR 292 adjustments to method handle invocation Summary: split MethodHandle.invoke into invokeExact and invokeGeneric Reviewed-by: twisti ! src/share/classes/com/sun/tools/javac/code/Flags.java ! src/share/classes/com/sun/tools/javac/code/Source.java ! src/share/classes/com/sun/tools/javac/code/Symtab.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/MemberEnter.java ! src/share/classes/com/sun/tools/javac/comp/Resolve.java ! src/share/classes/com/sun/tools/javac/jvm/ClassReader.java ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java ! src/share/classes/com/sun/tools/javac/jvm/Gen.java ! src/share/classes/com/sun/tools/javac/main/Main.java ! src/share/classes/com/sun/tools/javac/util/Names.java ! test/tools/javac/meth/InvokeDyn.java ! test/tools/javac/meth/InvokeMH.java Changeset: 2a28dcbef3a7 Author: jrose Date: 2010-05-13 20:01 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/2a28dcbef3a7 Merge Changeset: 005bec70ca27 Author: jrose Date: 2010-06-18 15:12 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/005bec70ca27 Merge ! src/share/classes/com/sun/tools/javac/code/Flags.java ! src/share/classes/com/sun/tools/javac/code/Source.java ! src/share/classes/com/sun/tools/javac/code/Symtab.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/MemberEnter.java ! src/share/classes/com/sun/tools/javac/comp/Resolve.java ! src/share/classes/com/sun/tools/javac/jvm/ClassReader.java ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java ! src/share/classes/com/sun/tools/javac/jvm/Gen.java ! src/share/classes/com/sun/tools/javac/main/Main.java ! src/share/classes/com/sun/tools/javac/util/Names.java ! test/tools/javac/meth/InvokeDyn.java ! test/tools/javac/meth/InvokeMH.java Changeset: 9d02c4ce4275 Author: mikejwre Date: 2010-06-24 20:03 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/9d02c4ce4275 Added tag jdk7-b99 for changeset 005bec70ca27 ! .hgtags Changeset: 9a7c998bf2fc Author: darcy Date: 2010-06-02 19:08 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/9a7c998bf2fc 6933147: Provided new utility visitors supporting SourceVersion.RELEASE_7 Reviewed-by: jjg ! src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java ! src/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java ! src/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java ! src/share/classes/com/sun/tools/javah/JavahTask.java ! src/share/classes/com/sun/tools/javah/LLNI.java ! src/share/classes/com/sun/tools/javah/TypeSignature.java ! src/share/classes/javax/lang/model/element/ElementVisitor.java ! src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java + src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor7.java ! src/share/classes/javax/lang/model/util/AbstractElementVisitor6.java + src/share/classes/javax/lang/model/util/AbstractElementVisitor7.java ! src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java + src/share/classes/javax/lang/model/util/AbstractTypeVisitor7.java ! src/share/classes/javax/lang/model/util/ElementKindVisitor6.java + src/share/classes/javax/lang/model/util/ElementKindVisitor7.java ! src/share/classes/javax/lang/model/util/ElementScanner6.java + src/share/classes/javax/lang/model/util/ElementScanner7.java ! src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java + src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor7.java ! src/share/classes/javax/lang/model/util/SimpleElementVisitor6.java + src/share/classes/javax/lang/model/util/SimpleElementVisitor7.java ! src/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java + src/share/classes/javax/lang/model/util/SimpleTypeVisitor7.java ! src/share/classes/javax/lang/model/util/TypeKindVisitor6.java + src/share/classes/javax/lang/model/util/TypeKindVisitor7.java ! src/share/sample/javac/processing/src/CheckNamesProcessor.java ! test/tools/javac/6402516/CheckLocalElements.java ! test/tools/javac/api/TestOperators.java ! test/tools/javac/enum/6424358/T6424358.java ! test/tools/javac/processing/model/6194785/T6194785.java ! test/tools/javac/processing/model/type/NoTypes.java ! test/tools/javac/processing/model/util/deprecation/TestDeprecation.java Changeset: 559c9a37d9f6 Author: jjg Date: 2010-06-03 17:14 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/559c9a37d9f6 6955264: add option to suppress Abort in Check.completionError Reviewed-by: mcimadamore ! src/share/classes/com/sun/tools/javac/comp/Check.java Changeset: 852d8bb356bc Author: darcy Date: 2010-06-03 19:56 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/852d8bb356bc 6519115: MirroredTypeException thrown but should be MirroredTypesException Reviewed-by: jjg ! src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java ! src/share/classes/javax/lang/model/type/MirroredTypeException.java ! src/share/classes/javax/lang/model/type/MirroredTypesException.java + test/tools/javac/processing/model/type/MirroredTypeEx/Plurality.java Changeset: b7fc560217d3 Author: jjg Date: 2010-06-04 14:54 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/b7fc560217d3 6958391: add vizant support to langtools build Reviewed-by: mcimadamore ! make/build.properties ! make/build.xml Changeset: d33b91f360fc Author: jjg Date: 2010-06-04 17:33 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/d33b91f360fc 6958802: cleanup and doc langtools build.xml file Reviewed-by: ohair ! make/build.properties ! make/build.xml Changeset: 46cf751559ae Author: mcimadamore Date: 2010-06-10 09:29 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/46cf751559ae 6945418: Project Coin: Simplified Varargs Method Invocation Summary: Add new mandatory warning for unsafe vararg method declaration. Warning can be suppressed as usual (@SuppressWarnings("varargs")/-Xlint:-varargs) Reviewed-by: jjg, darcy ! src/share/classes/com/sun/tools/javac/code/Lint.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/Check.java ! src/share/classes/com/sun/tools/javac/comp/Infer.java ! src/share/classes/com/sun/tools/javac/comp/Resolve.java ! src/share/classes/com/sun/tools/javac/resources/compiler.properties ! src/share/classes/com/sun/tools/javac/util/List.java ! test/tools/javac/varargs/6730476/T6730476a.java ! test/tools/javac/varargs/6806876/T6806876.out + test/tools/javac/varargs/warning/Warn4.java Changeset: f2fdd52e4e87 Author: jjg Date: 2010-06-10 16:08 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/f2fdd52e4e87 6944312: Potential rebranding issues in openjdk/langtools repository sources Reviewed-by: darcy ! src/share/classes/com/sun/javadoc/package.html ! src/share/classes/com/sun/mirror/overview.html ! src/share/classes/com/sun/source/tree/DisjointTypeTree.java ! src/share/classes/com/sun/tools/apt/comp/Apt.java ! src/share/classes/com/sun/tools/apt/main/CommandLine.java ! src/share/classes/com/sun/tools/apt/main/JavaCompiler.java ! src/share/classes/com/sun/tools/apt/main/Main.java ! src/share/classes/com/sun/tools/apt/util/Bark.java ! src/share/classes/com/sun/tools/classfile/AccessFlags.java ! src/share/classes/com/sun/tools/classfile/Annotation.java ! src/share/classes/com/sun/tools/classfile/AnnotationDefault_attribute.java ! src/share/classes/com/sun/tools/classfile/Attribute.java ! src/share/classes/com/sun/tools/classfile/AttributeException.java ! src/share/classes/com/sun/tools/classfile/Attributes.java ! src/share/classes/com/sun/tools/classfile/CharacterRangeTable_attribute.java ! src/share/classes/com/sun/tools/classfile/ClassFile.java ! src/share/classes/com/sun/tools/classfile/ClassReader.java ! src/share/classes/com/sun/tools/classfile/ClassTranslator.java ! src/share/classes/com/sun/tools/classfile/ClassWriter.java ! src/share/classes/com/sun/tools/classfile/Code_attribute.java ! src/share/classes/com/sun/tools/classfile/CompilationID_attribute.java ! src/share/classes/com/sun/tools/classfile/ConstantPool.java ! src/share/classes/com/sun/tools/classfile/ConstantPoolException.java ! src/share/classes/com/sun/tools/classfile/ConstantValue_attribute.java ! src/share/classes/com/sun/tools/classfile/DefaultAttribute.java ! src/share/classes/com/sun/tools/classfile/Deprecated_attribute.java ! src/share/classes/com/sun/tools/classfile/Descriptor.java ! src/share/classes/com/sun/tools/classfile/DescriptorException.java ! src/share/classes/com/sun/tools/classfile/EnclosingMethod_attribute.java ! src/share/classes/com/sun/tools/classfile/Exceptions_attribute.java ! src/share/classes/com/sun/tools/classfile/ExtendedAnnotation.java ! src/share/classes/com/sun/tools/classfile/Field.java ! src/share/classes/com/sun/tools/classfile/InnerClasses_attribute.java ! src/share/classes/com/sun/tools/classfile/Instruction.java ! src/share/classes/com/sun/tools/classfile/LineNumberTable_attribute.java ! src/share/classes/com/sun/tools/classfile/LocalVariableTable_attribute.java ! src/share/classes/com/sun/tools/classfile/LocalVariableTypeTable_attribute.java ! src/share/classes/com/sun/tools/classfile/Method.java ! src/share/classes/com/sun/tools/classfile/Opcode.java ! src/share/classes/com/sun/tools/classfile/RuntimeAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/RuntimeInvisibleAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/RuntimeInvisibleParameterAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/RuntimeInvisibleTypeAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/RuntimeParameterAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/RuntimeTypeAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/RuntimeVisibleAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/RuntimeVisibleParameterAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/RuntimeVisibleTypeAnnotations_attribute.java ! src/share/classes/com/sun/tools/classfile/Signature.java ! src/share/classes/com/sun/tools/classfile/Signature_attribute.java ! src/share/classes/com/sun/tools/classfile/SourceDebugExtension_attribute.java ! src/share/classes/com/sun/tools/classfile/SourceFile_attribute.java ! src/share/classes/com/sun/tools/classfile/SourceID_attribute.java ! src/share/classes/com/sun/tools/classfile/StackMapTable_attribute.java ! src/share/classes/com/sun/tools/classfile/StackMap_attribute.java ! src/share/classes/com/sun/tools/classfile/Synthetic_attribute.java ! src/share/classes/com/sun/tools/classfile/Type.java ! src/share/classes/com/sun/tools/javac/Launcher.java ! src/share/classes/com/sun/tools/javac/Server.java ! src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java ! src/share/classes/com/sun/tools/javac/api/Formattable.java ! src/share/classes/com/sun/tools/javac/api/JavacScope.java ! src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java ! src/share/classes/com/sun/tools/javac/api/JavacTool.java ! src/share/classes/com/sun/tools/javac/api/JavacTrees.java ! src/share/classes/com/sun/tools/javac/api/Messages.java ! src/share/classes/com/sun/tools/javac/api/WrappingJavaFileManager.java ! src/share/classes/com/sun/tools/javac/code/Attribute.java ! src/share/classes/com/sun/tools/javac/code/BoundKind.java ! src/share/classes/com/sun/tools/javac/code/Flags.java ! src/share/classes/com/sun/tools/javac/code/Kinds.java ! src/share/classes/com/sun/tools/javac/code/Lint.java ! src/share/classes/com/sun/tools/javac/code/Printer.java ! src/share/classes/com/sun/tools/javac/code/Scope.java ! src/share/classes/com/sun/tools/javac/code/Source.java ! src/share/classes/com/sun/tools/javac/code/Symbol.java ! src/share/classes/com/sun/tools/javac/code/Symtab.java ! src/share/classes/com/sun/tools/javac/code/TargetType.java ! src/share/classes/com/sun/tools/javac/code/Type.java ! src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java ! src/share/classes/com/sun/tools/javac/code/TypeTags.java ! src/share/classes/com/sun/tools/javac/code/Types.java ! src/share/classes/com/sun/tools/javac/comp/Annotate.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/AttrContext.java ! src/share/classes/com/sun/tools/javac/comp/AttrContextEnv.java ! src/share/classes/com/sun/tools/javac/comp/Check.java ! src/share/classes/com/sun/tools/javac/comp/ConstFold.java ! src/share/classes/com/sun/tools/javac/comp/Enter.java ! src/share/classes/com/sun/tools/javac/comp/Env.java ! src/share/classes/com/sun/tools/javac/comp/Flow.java ! src/share/classes/com/sun/tools/javac/comp/Infer.java ! src/share/classes/com/sun/tools/javac/comp/Lower.java ! src/share/classes/com/sun/tools/javac/comp/MemberEnter.java ! src/share/classes/com/sun/tools/javac/comp/Resolve.java ! src/share/classes/com/sun/tools/javac/comp/Todo.java ! src/share/classes/com/sun/tools/javac/comp/TransTypes.java ! src/share/classes/com/sun/tools/javac/file/BaseFileObject.java ! src/share/classes/com/sun/tools/javac/file/CacheFSInfo.java ! src/share/classes/com/sun/tools/javac/file/FSInfo.java ! src/share/classes/com/sun/tools/javac/file/JavacFileManager.java ! src/share/classes/com/sun/tools/javac/file/Paths.java ! src/share/classes/com/sun/tools/javac/file/RegularFileObject.java ! src/share/classes/com/sun/tools/javac/file/RelativePath.java ! src/share/classes/com/sun/tools/javac/file/SymbolArchive.java ! src/share/classes/com/sun/tools/javac/file/ZipArchive.java ! src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java ! src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java ! src/share/classes/com/sun/tools/javac/jvm/ByteCodes.java ! src/share/classes/com/sun/tools/javac/jvm/CRTFlags.java ! src/share/classes/com/sun/tools/javac/jvm/CRTable.java ! src/share/classes/com/sun/tools/javac/jvm/ClassFile.java ! src/share/classes/com/sun/tools/javac/jvm/ClassReader.java ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java ! src/share/classes/com/sun/tools/javac/jvm/Code.java ! src/share/classes/com/sun/tools/javac/jvm/Gen.java ! src/share/classes/com/sun/tools/javac/jvm/Items.java ! src/share/classes/com/sun/tools/javac/jvm/Pool.java ! src/share/classes/com/sun/tools/javac/jvm/Target.java ! src/share/classes/com/sun/tools/javac/jvm/UninitializedType.java ! src/share/classes/com/sun/tools/javac/main/CommandLine.java ! src/share/classes/com/sun/tools/javac/main/JavaCompiler.java ! src/share/classes/com/sun/tools/javac/main/JavacOption.java ! src/share/classes/com/sun/tools/javac/main/Main.java ! src/share/classes/com/sun/tools/javac/main/OptionName.java ! src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java ! src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java ! src/share/classes/com/sun/tools/javac/model/FilteredMemberList.java ! src/share/classes/com/sun/tools/javac/model/JavacElements.java ! src/share/classes/com/sun/tools/javac/model/JavacSourcePosition.java ! src/share/classes/com/sun/tools/javac/model/JavacTypes.java ! src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java ! src/share/classes/com/sun/tools/javac/nio/PathFileManager.java ! src/share/classes/com/sun/tools/javac/nio/PathFileObject.java ! src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java ! src/share/classes/com/sun/tools/javac/parser/EndPosParser.java ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java ! src/share/classes/com/sun/tools/javac/parser/Keywords.java ! src/share/classes/com/sun/tools/javac/parser/Lexer.java ! src/share/classes/com/sun/tools/javac/parser/Parser.java ! src/share/classes/com/sun/tools/javac/parser/ParserFactory.java ! src/share/classes/com/sun/tools/javac/parser/Scanner.java ! src/share/classes/com/sun/tools/javac/parser/Token.java ! src/share/classes/com/sun/tools/javac/processing/AnnotationProcessingError.java ! src/share/classes/com/sun/tools/javac/processing/JavacFiler.java ! src/share/classes/com/sun/tools/javac/processing/JavacMessager.java ! src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java ! src/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java ! src/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java ! src/share/classes/com/sun/tools/javac/processing/ServiceProxy.java ! src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java ! src/share/classes/com/sun/tools/javac/tree/JCTree.java ! src/share/classes/com/sun/tools/javac/tree/Pretty.java ! src/share/classes/com/sun/tools/javac/tree/TreeCopier.java ! src/share/classes/com/sun/tools/javac/tree/TreeInfo.java ! src/share/classes/com/sun/tools/javac/tree/TreeMaker.java ! src/share/classes/com/sun/tools/javac/tree/TreeScanner.java ! src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java ! src/share/classes/com/sun/tools/javac/util/Abort.java ! src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java ! src/share/classes/com/sun/tools/javac/util/AbstractLog.java ! src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java ! src/share/classes/com/sun/tools/javac/util/Bits.java ! src/share/classes/com/sun/tools/javac/util/ByteBuffer.java ! src/share/classes/com/sun/tools/javac/util/ClientCodeException.java ! src/share/classes/com/sun/tools/javac/util/CloseableURLClassLoader.java ! src/share/classes/com/sun/tools/javac/util/Constants.java ! src/share/classes/com/sun/tools/javac/util/Context.java ! src/share/classes/com/sun/tools/javac/util/Convert.java ! src/share/classes/com/sun/tools/javac/util/DiagnosticSource.java ! src/share/classes/com/sun/tools/javac/util/FatalError.java ! src/share/classes/com/sun/tools/javac/util/ForwardingDiagnosticFormatter.java ! src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java ! src/share/classes/com/sun/tools/javac/util/JavacMessages.java ! src/share/classes/com/sun/tools/javac/util/LayoutCharacters.java ! src/share/classes/com/sun/tools/javac/util/List.java ! src/share/classes/com/sun/tools/javac/util/ListBuffer.java ! src/share/classes/com/sun/tools/javac/util/Log.java ! src/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java ! src/share/classes/com/sun/tools/javac/util/Name.java ! src/share/classes/com/sun/tools/javac/util/Names.java ! src/share/classes/com/sun/tools/javac/util/Options.java ! src/share/classes/com/sun/tools/javac/util/Pair.java ! src/share/classes/com/sun/tools/javac/util/Position.java ! src/share/classes/com/sun/tools/javac/util/PropagatedException.java ! src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java ! src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java ! src/share/classes/com/sun/tools/javac/util/SharedNameTable.java ! src/share/classes/com/sun/tools/javac/util/UnsharedNameTable.java ! src/share/classes/com/sun/tools/javac/util/Warner.java ! src/share/classes/com/sun/tools/javah/Gen.java ! src/share/classes/com/sun/tools/javah/InternalError.java ! src/share/classes/com/sun/tools/javah/JNI.java ! src/share/classes/com/sun/tools/javah/JavahFileManager.java ! src/share/classes/com/sun/tools/javah/JavahTask.java ! src/share/classes/com/sun/tools/javah/JavahTool.java ! src/share/classes/com/sun/tools/javah/LLNI.java ! src/share/classes/com/sun/tools/javah/Main.java ! src/share/classes/com/sun/tools/javah/Mangle.java ! src/share/classes/com/sun/tools/javah/NativeHeaderTool.java ! src/share/classes/com/sun/tools/javah/TypeSignature.java ! src/share/classes/com/sun/tools/javah/Util.java ! src/share/classes/com/sun/tools/javap/AnnotationWriter.java ! src/share/classes/com/sun/tools/javap/AttributeWriter.java ! src/share/classes/com/sun/tools/javap/BasicWriter.java ! src/share/classes/com/sun/tools/javap/ClassWriter.java ! src/share/classes/com/sun/tools/javap/CodeWriter.java ! src/share/classes/com/sun/tools/javap/ConstantWriter.java ! src/share/classes/com/sun/tools/javap/Context.java ! src/share/classes/com/sun/tools/javap/DisassemblerTool.java ! src/share/classes/com/sun/tools/javap/InstructionDetailWriter.java ! src/share/classes/com/sun/tools/javap/InternalError.java ! src/share/classes/com/sun/tools/javap/JavapFileManager.java ! src/share/classes/com/sun/tools/javap/JavapTask.java ! src/share/classes/com/sun/tools/javap/LocalVariableTableWriter.java ! src/share/classes/com/sun/tools/javap/LocalVariableTypeTableWriter.java ! src/share/classes/com/sun/tools/javap/Main.java ! src/share/classes/com/sun/tools/javap/Messages.java ! src/share/classes/com/sun/tools/javap/Options.java ! src/share/classes/com/sun/tools/javap/SourceWriter.java ! src/share/classes/com/sun/tools/javap/StackMapWriter.java ! src/share/classes/com/sun/tools/javap/TryBlockWriter.java ! src/share/classes/com/sun/tools/javap/TypeAnnotationWriter.java ! src/share/classes/javax/lang/model/overview.html ! test/tools/apt/mirror/declaration/pkg1/pkg2/package.html ! test/tools/javac/6948381/T6948381.java ! test/tools/javac/6948381/npe/A.java ! test/tools/javac/6948381/npe/B.java ! test/tools/javac/api/evalexpr/ByteArrayClassLoader.java ! test/tools/javac/api/evalexpr/CompileFromString.java ! test/tools/javac/api/evalexpr/MemoryFileManager.java ! test/tools/javac/generics/diamond/T6951833.java ! test/tools/javac/generics/typevars/T6880344.java ! test/tools/javac/varargs/warning/Warn4.java Changeset: 366a7b9b5627 Author: jjg Date: 2010-06-10 17:09 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/366a7b9b5627 6960407: Potential rebranding issues in openjdk/langtools repository sources Reviewed-by: darcy ! make/Makefile ! make/Makefile-classic ! src/share/classes/com/sun/source/tree/Tree.java ! src/share/classes/com/sun/source/util/JavacTask.java ! src/share/classes/com/sun/source/util/TaskEvent.java ! src/share/classes/com/sun/source/util/TaskListener.java ! src/share/classes/com/sun/tools/doclets/formats/html/package.html ! src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java ! src/share/classes/com/sun/tools/javac/code/Flags.java ! src/share/classes/com/sun/tools/javac/code/Lint.java ! src/share/classes/com/sun/tools/javac/code/Symtab.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/Check.java ! src/share/classes/com/sun/tools/javac/resources/compiler.properties ! src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties ! src/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties ! src/share/classes/javax/tools/JavaFileManager.java Changeset: 224533455888 Author: jjg Date: 2010-06-11 07:12 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/224533455888 6877961: langtools build should allow more options when running jtreg Reviewed-by: mcimadamore ! make/build.xml Changeset: d1ea43cb71c1 Author: jjg Date: 2010-06-11 17:24 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/d1ea43cb71c1 6958836: javadoc should support -Xmaxerrs and -Xmaxwarns Reviewed-by: darcy ! src/share/classes/com/sun/tools/javac/util/Log.java ! src/share/classes/com/sun/tools/javadoc/DocletInvoker.java ! src/share/classes/com/sun/tools/javadoc/Messager.java ! src/share/classes/com/sun/tools/javadoc/Start.java ! src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties + test/tools/javadoc/6958836/Test.java + test/tools/javadoc/6958836/errs/Errors.java + test/tools/javadoc/6958836/warns/Warnings.java Changeset: 0840dd65b9e2 Author: jjg Date: 2010-06-16 16:23 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/0840dd65b9e2 6956638: JavacTask.generate does not generate all required files Reviewed-by: darcy Contributed-by: joshuamaurice at gmail.com + test/tools/javac/T6956638.java Changeset: 93e1975eea7a Author: lana Date: 2010-06-16 14:09 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/93e1975eea7a Merge ! test/tools/apt/mirror/declaration/pkg1/pkg2/package.html Changeset: e2b845fdc437 Author: lana Date: 2010-06-16 17:52 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/e2b845fdc437 Merge Changeset: 0ba1f80b73a5 Author: jjg Date: 2010-06-18 16:45 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/0ba1f80b73a5 6962540: langtools Makefile sets DEV_NULL incorrectly Reviewed-by: ohair ! make/Makefile Changeset: 4177f5bdd189 Author: jjg Date: 2010-06-18 21:13 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/4177f5bdd189 6961178: Allow doclet.xml to contain XML attributes Reviewed-by: bpatel ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractMemberBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeOptionalMemberBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeRequiredMemberBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ClassBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ConstantsSummaryBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ConstructorBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/EnumConstantBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/FieldBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/LayoutParser.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MethodBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/PackageSummaryBuilder.java ! src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java + src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/XMLNode.java Changeset: 4cca8d7ce6c1 Author: lana Date: 2010-06-21 22:09 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/4cca8d7ce6c1 Merge Changeset: d1d7595fa824 Author: lana Date: 2010-06-29 22:43 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/d1d7595fa824 Merge ! src/share/classes/com/sun/tools/javac/code/Flags.java ! src/share/classes/com/sun/tools/javac/code/Source.java ! src/share/classes/com/sun/tools/javac/code/Symtab.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/MemberEnter.java ! src/share/classes/com/sun/tools/javac/comp/Resolve.java ! src/share/classes/com/sun/tools/javac/jvm/ClassReader.java ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java ! src/share/classes/com/sun/tools/javac/jvm/Gen.java ! src/share/classes/com/sun/tools/javac/main/Main.java ! src/share/classes/com/sun/tools/javac/util/Names.java From linuxhippy at gmail.com Thu Jul 1 10:57:23 2010 From: linuxhippy at gmail.com (Clemens Eisserer) Date: Thu, 1 Jul 2010 12:57:23 +0200 Subject: [OpenJDK 2D-Dev] 2 small xrender fixes In-Reply-To: <4C2128C8.8070302@oracle.com> References: <4C2128C8.8070302@oracle.com> Message-ID: Hi Phil, The whitespace one, I'm not aware that T2K will do this. > I find that it sets it width and height to zero for whitespace. > I instrumented the rasteriser and ran with code like this. > Wow, actually that took me quite a while to figure out what was going wrong. T2K does set width=-1 for whitespace, but only if subpixel antialiasing is enabled. Because width is unsigned in C, I get the 65535. public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); char[] chars = {' '}; Font f = new Font("Serif", Font.PLAIN, 14); g.setFont(f); g.drawChars(chars, 0, 1, 30, 30); } Can you reproduce this? By the way, I would like to re-do the Jules thing a bit, so please don't integrate it for now. Thanks, Clemens -------------- next part -------------- An HTML attachment was scrubbed... URL: From dlila at redhat.com Fri Jul 2 19:37:50 2010 From: dlila at redhat.com (Denis Lila) Date: Fri, 2 Jul 2010 15:37:50 -0400 (EDT) Subject: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines. In-Reply-To: <253692521.202071278099234509.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <1343560286.202281278099470219.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hello. I think I got this working. The webrev is at: http://icedtea.classpath.org/~dlila/webrevs/bezierRoundJoins/webrev/ (NOTE: this is not a final version. I have included 2 versions of 2 methods. Only one set should be kept. See below for more.) My Changes: ----------- 1. I've made LineSink into an interface, rather than an abstract class, because all of its methods were abstract, so it makes more sense this way. 2. I've introduced a new interface that extends LineSink called PathSink, which allows the curveTo method, so there have been no changes to Stroker's public interface. When someone wants to create a Stroker with a PathSink output, it simply passes its constructor a PathSink, so the only changes outside of Stroker are in PiscesRenderingEngine, where the methods that handle Path2D and PathConsumer2D objects create nameless PathSinks instead of nameless LineSinks. 3. In Stroker: I've introduced a method called drawBezRoundJoin, analogous to computeRoundJoin. In drawRoundJoin I detect whether the output is a PathSink. If it is, I call drawBezRoundJoin, otherwise everything proceeds as it used to. drawBezRoundJoin uses computeBezierPoints to compute the control points. computeBezierPoints computes the control points for an arc of t radians, starting at angle a, with radius r by computing the control points of an arc of radius 1 of t radians that starts at angle -t/2. This is done by solving the equations resulting from the constraints that (P3-P2) and (P1-P0) must be parallel to the arc's tangents at P3 and P0 respectively, and that B(1/2)=(1,0). Then the points are scaled by r, and rotated counter clockwise by a+t/2. Then drawBezRoundJoin emits the curve. All this is done in a loop which is used to break up large arcs into more than one bezier curve. Through the iterations, the computed control points don't change - the only thing that changes is how they're rotated. So a good alternative approach would be to do the rotation outside of computeBezierPoints, and call computeBezierPoints once outside of the loop, so that the control points aren't recomputed unnecessarily. I have included code for this in the methods computeBezierPoints2 and drawBezRoundJoin2. This is my favoured approach, since it is almost as clear as the other one, and it is faster. There is one more optimization that can be made, and I've included it in a comment in line 703. I would very much appreciate any comments about any of this, but especially about the idea in line 703 and about computeBezierPoints2,drawBezRoundJoin2 vs. computeBezierPoints,drawBezRoundJoin. 4. Stroker used to only have lines, but now it can emit lines and curves, so I needed to change the format of reverse, to not only store coordinates, but to also tag them as belonging to a line or a curve. Other Approaches: ----------------- 1. Since what needed to be done was to alter the behaviour of one part of Stroker (drawing of round joins/caps) depending on the type of the output object, I thought it would be appropriate to make Stroker an abstract factory, turn the methods that draw round joins/caps into abstract ones, put all the common functionality in concrete methods in Stroker, and put all the join/cap drawing methods in overriding methods in concrete children of Stroker (instances of which were returned by static factories in Stroker). However, this was a bad approach, because the round cap/join drawing methods are private, so the only way to call them in Stroker's children from public methods in Stroker is to cast "this". So the code became littered with instanceof operators and casts. Not to mention that Stroker's public interface had to change, and some functionality was lost: Stroker allows changing it's output, so it is possible to use just 1 Stroker object to widen paths going to many different outputs (but not at the same time). This could no longer be supported with this approach. The way I did it has none of these weaknesses. 2. As for algorithms for the circle approximation, I considered 2: a. Compute the control points using the constraints that B(1/3)=A(a+t/3) and B(2/3) = A(a+2t/3) (i.e. make the arc and the bezier curve coincide at 2 evenly spaced points in the arc). This didn't work very well: some of the end caps looked more like triangles. b. Let B(1/2) = A(a+t/2), and B'(1/2) = A'(a+t/2). This worked better, but still not good enough. If anyone knows of any better ways to compute the control points, please let me know. I'm sorry for the length of this. I tried to make it shorter. Thank you very much, Denis. ----- "Jim Graham" wrote: > Hi Denis, > > Consider the case of using BasicStroke.createStrokedShape(). How do > you > know how many pixels the resulting path will occupy? You can't reduce > > to concrete samples if you don't know the transform. > > So, for rendering, then you may be correct. But for cases where the > path is being asked for then beziers are the only responsible > solution... > > ...jim > > Denis Lila wrote: > > Hello Jim. > > > > I thought about checking the output and changing the behaviour > > depending on whether the output is a PC2D or a LineSink, but I > didn't > > implement it because I thought the point was to get rid of the > sampling > > at this stage. However, if performance is the issue, then I guess > I'll > > start working on it. > > > > Although, I wonder whether it is really worth it. I think most lines > drawn > > won't be wider than about 5 pixels, which means that the current way > will > > emit about 7 lines, so that's 14 coordinates. 2 bezier quarter > circles will > > require 12 coordinates. In terms of storage, there isn't much > difference, and > > for lines of width 4 or smaller the current method is more > efficient. > > > > I'm also guessing that it's harder for the rasterizer to deal with > bezier > > curves than with straight lines, so is it possible that replacing > the > > 3.14*lineWidth/2 lines generated by the current method with 2 bezier > > > quarter circles isn't worth it (for small lineWidths)? > > > > Thanks, > > Denis. > > > > ----- "Jim Graham" wrote: > > > >> Sigh - that makes sense. One issue is that the resulting paths it > > >> generates are much more "verbose" than they need to be. This would > > >> generally mean that it takes far more storage than it would > otherwise > >> > >> need - and it means that if the result needs to be transformed then > it > >> > >> would take many more computations to transform each segment than > the > >> bezier. > >> > >> So, perhaps it would be worth having it check the type of the > output > >> and > >> do either a bezier or a bunch of lines depending on if it is a PC2D > or > >> a > >> LineSink? > >> > >> Also, it isn't really that difficult to for Renderer to include > its > >> own > >> Cubic/Quadratic flattening code, but it might involve more > >> calculations > >> than the round-cap code since it would have to be written for > >> arbitrary > >> beziers whereas if you know it is a quarter circle then it is > easier > >> to > >> know how far to subdivide... :-( > >> > >> ...jim > >> > >> Denis Lila wrote: > >>> So, I have been thinking about this, and I can't see a good > >>> way to do it that wouldn't involve heavy changes to Pisces. > >>> > >>> In order for Stroker to generate Bezier quarter circles, it would > >>> have to implement a curveTo method, which means Stroker should > >>> start implementing PathConsumer2D and instead of using a LineSink > >>> output it would have to use a PathConsumer2D output (either that, > >> or > >>> LineSink should include a curveTo method, but then there won't > >> really > >>> be any difference between a LineSink and a PathConsumer2D. By the > >> way, > >>> LineSink doesn't have any implemented methods, so why is it an > >> abstract > >>> class as opposed to an interface?) > >>> > >>> Stroker is used in 3 ways: > >>> 1. As an implementation of BasicStroke's createStrokedShape > method. > >> This > >>> uses a Path2D object as output. > >>> 2. As a way of feeding a PathConsumer2D without calling > >> createStrokedShape > >>> to generate an intermediate Shape. This uses a PathConsumer2D > >> output. > >>> 3. As a way of feeding lines to a Renderer object, which > generates > >> alpha > >>> tiles used for anti-aliasing that are fed to a cache and > extracted > >> as needed > >>> by an AATileGenerator. Obviously, Stroker's output here is a > >> Renderer. > >>> 1 and 2 aren't problems, because the underlying output objects > >> support > >>> Bezier curves. 3, however, doesn't, and it seems like implementing > a > >>> curveTo method for Renderer would be very difficult because the > way > >> it > >>> generates alpha tiles is by scanning the drawn edges with > >> horizontal > >>> scan lines, and for each scan line finding the x-intersections of > >> the scan > >>> lines and the edges. Then it determines the alpha values (I'm not > >> too sure > >>> how it does this). > >>> In order to implement Bezier curves in Renderer, we would have to > >> have > >>> a quick way of computing, for each scan line, all its > intersections > >> with > >>> however many Bezier curves are being drawn. > >>> > >>> I haven't given much thought to how this could be done, as I am > not > >> very > >>> familiar with Bezier curves, but it doesn't seem easy enough to > >> justify > >>> fixing such a small bug. > >>> > >>> ----- Original Message ----- > >>> From: "Jim Graham" > >>> To: "Denis Lila" > >>> Cc: 2d-dev at openjdk.java.net > >>> Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada > >> Eastern > >>> Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on > >> scaled lines. > >>> I don't understand - why do we generate sample points based on > the > >> size > >>> of the cap? Why not generate a pair of bezier quarter-circles > and > >> let > >>> the rasterizer deal with sampling? > >>> > >>> ...jim > >>> > >>> Denis Lila wrote: > >>>> Hello. > >>>> > >>>> I think I have a fix for this bug: > >>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506 > >>>> > >>>> Basically, the problem is that if there is a magnifying affine > >> transformation set on the graphics object and one tries to draw a > line > >> with small thickness and round end caps, the end caps appear > jagged. > >> This is because the computation of the length of the array that > >> contains the points on the "pen" with which the decoration is > drawn > >> does not take into account the size of the pen after the > magnification > >> of the affine transformation. So, for example, if the line length > was > >> set to 1, and the transformation was a scaling by 10, the > resulting > >> pen would have a diameter of 10, but only 3 pen points would be > >> computed (pi*untransformedLineWidth), so the end cap looks like a > >> triangle. > >>>> My fix computes an approximation of the circumference of the > >> transformed pen (which is an ellipse) and uses that as the number > of > >> points on the pen. The approximation is crude, but it is simple, > >> faster than alternatives > >> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can > say > >> from observations that it works fairly well. > >>>> There is also icing on the cake, in the form of slight > improvements > >> in performance when the scaling is a zooming out. Example: if the > >> original line width was 100, but g2d.scale(0.1,0.1) was set, then > the > >> resulting line would have a width of 10, so only ~31 points are > >> necessary for the decoration to look like a circle, but without > this > >> patch, about 314 points are computed (and a line is emitted to > each > >> one of them). > >>>> I appreciate any feedback. > >>>> > >>>> Regards, > >>>> Denis Lila. > >>>> From dlila at redhat.com Fri Jul 2 20:28:43 2010 From: dlila at redhat.com (Denis Lila) Date: Fri, 2 Jul 2010 16:28:43 -0400 (EDT) Subject: [OpenJDK 2D-Dev] Fix for uniformly scaled dashed lines. In-Reply-To: <1645259791.205311278102178167.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <1895965261.205581278102523268.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hello Jim. Here is a webrev for the patch: http://icedtea.classpath.org/~dlila/webrevs/dasherFix/webrev/ I have eliminated most of the setup code, like you suggested. This is both more efficient, and far clearer than the original code (and especially my version of the patch. It is also correct in cases where the transform is [[n,0],[0,n]]). I still have my version of the patch (the one with "dashesToCompute"), and as I mentioned in another e-mail, the allocation of the array can be eliminated, since it can be turned into a field. So it should have better performance in pretty much all cases. If you would like me to send a webrev for that too, e-mail me. Thank you, Denis. ----- "Jim Graham" wrote: > Hi Denis, > > One request on your code - please don't use the variable "lowercase > L". > On my screen with Courier font I cannot distinguish between the > number > 1 and the lowercase L character and so I cannot verify if your code is > > correct. > > Also, by "inner loop" I meant the single loop. I use the term to mean > > the "loop that does all the work at the innermost level" without > regard > to whether the case contains only 1 loop and is therefore a degenerate > > application of the term. > > My comment about the "major axis" stuff was an optimization that is no > > longer needed. I though I saw calls to hypot() in the inner loop, but > I > just noticed that those were in deleted code and the new code has no > such calls, so you can ignore it. If it makes the comment clearer, > "major axis" is either the X or Y axis depending on whether the line > is > more horizontal or vertical, but you can ignore it now. > > I will note that the 2 arrays you compute are simply scaled versions > of > the dash array and so we could eliminate the extra allocations by > simply > computing the values inside the loop at the cost of a multiply per > dash > segment to offset the cost of an allocation per incoming line segment. > > Also, you would no longer need to compute the "dashesToCompute" value > > and the setup code would be much, much simpler (basically you just > need > to compute the untransformed length and the cx and cy values and then > > jump into the loop). > > I'm leaning towards the multiplies in the loop to greatly simplify the > > code... > > (One last comment - have you checked what happens with the code in the > > presence of a degenerate transform? A non-invertible transform may > run > the risk of an infinite loop if you assume that you can reverse > compute > the line length and end up with a finite value...) > > ...jim > > Denis Lila wrote: > > Hello Jim. > > > > Thank you for your reply. It seems my code did not fully take into > > account your second point after all. > > The dx's of the transformed dashes are di*newx/ (where > > di is the untransformed dash length, newx is the transformed x > > coordinate, and is the untransformed line length). Obviously, > > newx/ is constant for all dash segments, so it can be computed > > outside of the loop, but I was computing t=di/ inside the loop, > > > and then t*newx also inside the loop. > > > > I have fixed this and I included an improved version of the patch. > > > > However, I do not understand the second part of your e-mail > > ("One more optimization ..."). I am not sure what you mean by > > "major axis", how one would loop along it, and what the "inner > loop" > > is. There are no nested loops in this method. > > > > Also, the computation of the dxi and dyi of the transformed dash > segment > > dash[i] involves just 1 multiplication and 1 bit shift (along with > an > > overhead of 2 divisions and 2 bit shifts). > > The computation of the actual endpoint of the dashes (done in the > while(true) > > loop) most of the time involves just 2 additions. > > I am not sure how this can be made any simpler. > > > > Thank you, > > Denis. > > > > ----- "Jim Graham" wrote: > > > >> Hi Denis, > >> > >> Here are my thoughts on it: > >> > >> - Lines are affinely transformed into lines. The slope may be > >> different > >> before and after the transform, but both have a single slope. > >> > >> - The ratio of a line length to its transformed line length is a > scale > >> > >> factor that depends solely on the angle of the line. Thus, for > >> determining dashing you can simply compute this scale factor once > for > >> a > >> given line and then that single scale factor can be applied to > every > >> dash segment. > >> > >> It appears that your setup code takes these factors into account, > >> though > >> I haven't done a grueling line by line analysis as to whether you > got > >> > >> the math right. > >> > >> One more optimization is that once you know the angle of the line > then > >> > >> you have a factor for how the length of a segment of that line > relates > >> > >> to its dx and dy. Note that for horizontal and vertical lines one > of > >> > >> those factors may be Infinity, but every line will have a non-zero > and > >> > >> non-infinity factor for one of those two dimensions. > >> > >> This means that you can calculate the dashing by simply looping > along > >> > >> the major axis of the line and comparing either the dx, or the dy > to > >> scaled "lengths" that represent the lengths of the transformed > dashes > >> > >> projected onto the major axis. > >> > >> Finally, the other dx,dy can be computed from the dx,dy of the > major > >> axis with another scale. I am pretty sure that this dx=>dy or > dy=>dx > >> > >> scale factor might be zero, but it would never be infinite if you > are > >> > >> calculating along the major axis of the transformed line, but I > didn't > >> > >> write out a proof for it. > >> > >> Taking both of these concepts into account - can that make the > inner > >> loop even simpler? > >> > >> ...jim > >> > >> Denis Lila wrote: > >>> Hello. > >>> > >>> I think I have a fix for this bug: > >> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=504 > >>> The problem is caused by the "symmetric" variable in > >> pisces/Dasher.java. > >>> symmetric is set to (m00 == m11 && m10 == -m01), and never > changed. > >>> > >>> It is only used in one place (in lineTo) to simplify the > computation > >> of > >>> the length of the line before an affine transformation A was > applied > >> to it. > >>> This is why it causes a problem: > >>> If A = [[a00, a01], [a10, a11]] and (x,y) is a point obtained by > >> applying > >>> A to some other point (x',y'), then what we want is the length of > >> the vector > >>> (x',y'), which is ||Ainv*(x,y)||. Ainv = (1/det(A)) * [[a11, > >> -a01],[-a10, a00]], > >>> so, after some calculations, ||Ainv*(x,y)|| ends up being equal > to > >>> sqrt(x^2*(a11^2 + a10^2) + y^2*(a00^2 + a01^2) - x*y*(a11*a01 + > >> a00*a10)) * 1/|det(A)|. > >>> If symmetric==true, this simplifies to: > >>> sqrt((a11^2 + a01^2) * (x^2 + y^2)) * 1/|det(A)|, and > >>> |det(A)| = a11^2 + a01^2, so, the final answer is: > >>> sqrt((x^2 + y^2)) / sqrt(det(A)). Therefore the problem in > >> Dasher.java > >>> is that it divides by det(A), not sqrt(det(A)). > >>> > >>> My fix for this was to remove the "symmetric" special case. > Another > >> possible fix > >>> would have been to introduce an instance "sqrtldet" and set it to > >> sqrt(det(A)), > >>> and divide by that instead of det(A). This didn't seem worth it, > >> because the only > >>> benefit we gain by having the "symmetric" variable is to save 3 > >> multiplications > >>> and 1 division per iteration of the while(true) loop, at the > expense > >> of making the > >>> code more complex, harder to read, introducing more opportunity > for > >> bugs, and adding > >>> hundreds of operations of overhead (since PiscesMath.sqrt would > have > >> to be called to > >>> initialize sqrtldet). > >>> > >>> To make up for this slight performance loss I have moved the code > >> that computes > >>> the transformed dash vectors outside of the while loop, since > they > >> are constant > >>> and they only need to be computed once for any one line. > >>> Moreover, computing the constant dash vectors inside the loop > >> causes > >>> them to not really be constant (since they're computed by > dividing > >> numbers that > >>> aren't constant). This can cause irregularities in dashes (see > >> comment 14 in > >>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=197). > >>> > >>> I would very much appreciate any comments/suggestions. > >>> > >>> Thank you, > >>> Denis Lila. > >>> From dlila at redhat.com Mon Jul 5 18:21:33 2010 From: dlila at redhat.com (Denis Lila) Date: Mon, 5 Jul 2010 14:21:33 -0400 (EDT) Subject: [OpenJDK 2D-Dev] X11 uniform scaled wide lines and dashed lines; STROKE_CONTROL in Pisces In-Reply-To: <716306149.303561278352768911.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <1621437549.303931278354093053.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hello everyone. In sun.java2d.x11.X11Renderer, line 340, it says: // REMIND: X11 can handle uniform scaled wide lines // and dashed lines itself if we set the appropriate // XGC attributes (TBD). Also, it is a known issue that Pisces does not support the STROKE_CONTROL hint. I have been wanting to implement these two features, and I have a few questions: Has anything been decided on the first issue? Do we still want to implement it? If yes, can anyone give me some rough suggestions as to how I can get started? What would be involved in making STROKE_CONTROL available in Pisces? Is it just a matter of setting input coordinates to the nearest pixel's centre when VALUE_STROKE_NORMALIZE is on? Thank you, Denis. From linuxhippy at gmail.com Mon Jul 5 20:49:17 2010 From: linuxhippy at gmail.com (Clemens Eisserer) Date: Mon, 5 Jul 2010 22:49:17 +0200 Subject: [OpenJDK 2D-Dev] X11 uniform scaled wide lines and dashed lines; STROKE_CONTROL in Pisces In-Reply-To: <1621437549.303931278354093053.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <716306149.303561278352768911.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> <1621437549.303931278354093053.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: Hi Denis, > In sun.java2d.x11.X11Renderer, line 340, it says: > ? ? ? ? ? ?// REMIND: X11 can handle uniform scaled wide lines > ? ? ? ? ? ?// and dashed lines itself if we set the appropriate > ? ? ? ? ? ?// XGC attributes (TBD). > > > Also, it is a known issue that Pisces does not support the STROKE_CONTROL > hint. > > I have been wanting to implement these two features, and I have a few questions: > Has anything been decided on the first issue? Do we still want to implement it? > If yes, can anyone give me some rough suggestions as to how I can get started? Its just my personal opinion, but I would recommend not implementing it. Xorg falls back to software anyway for anything more complex than solid rectangles and blits and those code-paths will only be triggered for non-antialised rendering with solid colors. Implementing it in Pisces would help every backend OpenJDK supports :) Just checked and I also ignore the STROKE_CONTROL stuff completly in the cairo based Jules rasterizer. Curious how that could be mapped to Cairo, do you know any more in-depth explanation how it works - or examples how it should look like? Thanks, Clemens From dlila at redhat.com Tue Jul 6 15:10:27 2010 From: dlila at redhat.com (Denis Lila) Date: Tue, 6 Jul 2010 11:10:27 -0400 (EDT) Subject: [OpenJDK 2D-Dev] X11 uniform scaled wide lines and dashed lines; STROKE_CONTROL in Pisces In-Reply-To: <840616781.345841278426869391.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <58312289.350011278429027922.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Clemens, thanks for your reply. > Its just my personal opinion, but I would recommend not implementing > it. > Xorg falls back to software anyway for anything more complex than > solid rectangles and blits > and those code-paths will only be triggered for non-antialised > rendering with solid colors. > > Implementing it in Pisces would help every backend OpenJDK supports > :) That makes sense. I think you're right. > Just checked and I also ignore the STROKE_CONTROL stuff completly in > the cairo based Jules rasterizer. > Curious how that could be mapped to Cairo, do you know any more > in-depth explanation how it works - or examples how it should look > like? > > Thanks, Clemens Regarding VALUE_STROKE_NORMALIZE the API says: Stroke normalization control hint value -- geometry should be normalized to improve uniformity or spacing of lines and overall aesthetics. Note that different normalization algorithms may be more successful than others for given input paths. I can only think of one example where VALUE_STROKE_NORMALIZE makes a visible difference between the closed source implementation and OpenJDK: when drawing anti-aliased horizontal or vertical lines of width 1, Pisces draws a 2 pixel wide line with half intensity (because integer coordinates are between pixels). Sun's jdk with VALUE_SROKE_NORMALIZE turned on draws a 1 pixel line with full intensity. This could to achieved by just checking for normalization and rounding coordinates to the nearest half pixel, but this solution seems too simple, and I'm not sure whether I'm missing anything. It would also probably cause problems when drawing anti-aliased short lines (which is done when drawing any sort of curve) Unless, of course, this rounding was restricted to just horizontal and vertical lines. Regards, Denis. From igor.nekrestyanov at sun.com Wed Jul 7 01:25:17 2010 From: igor.nekrestyanov at sun.com (igor.nekrestyanov at sun.com) Date: Wed, 07 Jul 2010 01:25:17 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/jdk: 6967050: JDK build issues with cygwin/vc2010 Message-ID: <20100707012601.DED5F477E2@hg.openjdk.java.net> Changeset: ab55cb957830 Author: igor Date: 2010-07-06 18:23 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/ab55cb957830 6967050: JDK build issues with cygwin/vc2010 Reviewed-by: prr, ohair ! make/common/shared/Defs-windows.gmk ! make/mkdemo/Makefile From linuxhippy at gmail.com Wed Jul 7 19:28:46 2010 From: linuxhippy at gmail.com (Clemens Eisserer) Date: Wed, 7 Jul 2010 21:28:46 +0200 Subject: [OpenJDK 2D-Dev] 2 small xrender fixes In-Reply-To: <4C2D2496.80303@oracle.com> References: <4C2128C8.8070302@oracle.com> <4C2D2496.80303@oracle.com> Message-ID: Hi Phil, Strange, running your test I get width=-1 when uploading as well as rendering the glyph - and the pipeline basically just reads the native GlyphInfo structure by using Unsafe. > I'll have to think about it a bit more .. Anything I could to to help to track that down? Thanks, Clemens From philip.race at oracle.com Wed Jul 7 23:20:56 2010 From: philip.race at oracle.com (Phil Race) Date: Wed, 07 Jul 2010 16:20:56 -0700 Subject: [OpenJDK 2D-Dev] 2 small xrender fixes In-Reply-To: References: <4C2128C8.8070302@oracle.com> <4C2D2496.80303@oracle.com> Message-ID: <4C350BD8.40403@oracle.com> I see the problem now. I looked at what T2K (the rasteriser) reports, but in the non-T2K glue code we then make an adjustment in the case of LCD glyphs which simply should never have been applied in the case of an empty image. It has never affected any of our code as I think we only truly use the width (not the same as advance) during blitting and the check for a null image stops us before that's an issue. I'll file a bug and fix this. Thanks, -phil. On 7/7/2010 12:28 PM, Clemens Eisserer wrote: > Hi Phil, > > Strange, running your test I get width=-1 when uploading as well as > rendering the glyph - and the pipeline basically just reads the native > GlyphInfo structure by using Unsafe. > > >> I'll have to think about it a bit more .. >> > Anything I could to to help to track that down? > > Thanks, Clemens > From james.graham at oracle.com Thu Jul 8 00:50:52 2010 From: james.graham at oracle.com (Jim Graham) Date: Wed, 07 Jul 2010 17:50:52 -0700 Subject: [OpenJDK 2D-Dev] Fix for uniformly scaled dashed lines. In-Reply-To: <1352155522.626481277217047436.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <1352155522.626481277217047436.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C3520EC.1030603@oracle.com> Hi Denis, Saving the arrays depends on both the original value of the array and also the transform being used. Can a given Dasher be used by more than one rendering thread at a time? (I forget if this is possible.) Even if we currently cannot use them from more than one thread, I prefer re-entrant code to non-re-entrant code in general unless there is a big performance savings, and then the reuse of data should really be carefully planned and accounted for in the interfaces. Also, scale and shear are both potentially non-invertible. Scale(0,0) is non-invertible and I believe that something like Shear(1,1) is also non-invertible. Also some combinations including rotate can become non-invertible even though the rest of the chain of transforms looks benign. Just because the transform is affine does not mean it is invertible (witness the fact that we have to throw non-invertible exceptions from some methods)... ...jim Denis Lila wrote: > Hello Jim. > > Sorry about the l. It was already there, and I wanted to change as > little as possible. > > As for whether to compute the transformed dashes inside the while(true) > or not... the main point of this patch was to fix a bug where zooming > transforms weren't handled properly. The efficiency improvements were > just something I threw in because a bunch of stuff was being computed > too many times, so I can go either way. I should note that the allocations > can be easily removed by just turning the arrays into fields, and allocating > them at setParameters, since for any one Dasher object their length is > constant. So the choice is between clearer and slower code and mine. I > have 2 patches ready, one for each way of doing it. Just tell me which > to send. > > As for degenerate inputs: I did think about non-invertible transforms, but > since they weren't being handled in the original Dasher and Stroker, and > since the API provides no way of using non-invertible transforms (the only > possible ones are shear, rotate, translate, and scale, all of which are > invertible), I didn't think it was necessary to check for them. > How do you think they should be handled? I think we should just throw > an InvalidInputException if the determinant is 0. > One more thing: it turns out that by computing dashes outside of the while(true) > I introduced the possibility for divide by zero errors. I fixed this. > > Thanks, > Denis. > ----- "Jim Graham" wrote: > >> Hi Denis, >> >> One request on your code - please don't use the variable "lowercase >> L". >> On my screen with Courier font I cannot distinguish between the >> number >> 1 and the lowercase L character and so I cannot verify if your code is >> >> correct. >> >> Also, by "inner loop" I meant the single loop. I use the term to mean >> >> the "loop that does all the work at the innermost level" without >> regard >> to whether the case contains only 1 loop and is therefore a degenerate >> >> application of the term. >> >> My comment about the "major axis" stuff was an optimization that is no >> >> longer needed. I though I saw calls to hypot() in the inner loop, but >> I >> just noticed that those were in deleted code and the new code has no >> such calls, so you can ignore it. If it makes the comment clearer, >> "major axis" is either the X or Y axis depending on whether the line >> is >> more horizontal or vertical, but you can ignore it now. >> >> I will note that the 2 arrays you compute are simply scaled versions >> of >> the dash array and so we could eliminate the extra allocations by >> simply >> computing the values inside the loop at the cost of a multiply per >> dash >> segment to offset the cost of an allocation per incoming line segment. >> >> Also, you would no longer need to compute the "dashesToCompute" value >> >> and the setup code would be much, much simpler (basically you just >> need >> to compute the untransformed length and the cx and cy values and then >> >> jump into the loop). >> >> I'm leaning towards the multiplies in the loop to greatly simplify the >> >> code... >> >> (One last comment - have you checked what happens with the code in the >> >> presence of a degenerate transform? A non-invertible transform may >> run >> the risk of an infinite loop if you assume that you can reverse >> compute >> the line length and end up with a finite value...) >> >> ...jim >> >> Denis Lila wrote: >>> Hello Jim. >>> >>> Thank you for your reply. It seems my code did not fully take into >>> account your second point after all. >>> The dx's of the transformed dashes are di*newx/ (where >>> di is the untransformed dash length, newx is the transformed x >>> coordinate, and is the untransformed line length). Obviously, >>> newx/ is constant for all dash segments, so it can be computed >>> outside of the loop, but I was computing t=di/ inside the loop, >>> and then t*newx also inside the loop. >>> >>> I have fixed this and I included an improved version of the patch. >>> >>> However, I do not understand the second part of your e-mail >>> ("One more optimization ..."). I am not sure what you mean by >>> "major axis", how one would loop along it, and what the "inner >> loop" >>> is. There are no nested loops in this method. >>> >>> Also, the computation of the dxi and dyi of the transformed dash >> segment >>> dash[i] involves just 1 multiplication and 1 bit shift (along with >> an >>> overhead of 2 divisions and 2 bit shifts). >>> The computation of the actual endpoint of the dashes (done in the >> while(true) >>> loop) most of the time involves just 2 additions. >>> I am not sure how this can be made any simpler. >>> >>> Thank you, >>> Denis. >>> >>> ----- "Jim Graham" wrote: >>> >>>> Hi Denis, >>>> >>>> Here are my thoughts on it: >>>> >>>> - Lines are affinely transformed into lines. The slope may be >>>> different >>>> before and after the transform, but both have a single slope. >>>> >>>> - The ratio of a line length to its transformed line length is a >> scale >>>> factor that depends solely on the angle of the line. Thus, for >>>> determining dashing you can simply compute this scale factor once >> for >>>> a >>>> given line and then that single scale factor can be applied to >> every >>>> dash segment. >>>> >>>> It appears that your setup code takes these factors into account, >>>> though >>>> I haven't done a grueling line by line analysis as to whether you >> got >>>> the math right. >>>> >>>> One more optimization is that once you know the angle of the line >> then >>>> you have a factor for how the length of a segment of that line >> relates >>>> to its dx and dy. Note that for horizontal and vertical lines one >> of >>>> those factors may be Infinity, but every line will have a non-zero >> and >>>> non-infinity factor for one of those two dimensions. >>>> >>>> This means that you can calculate the dashing by simply looping >> along >>>> the major axis of the line and comparing either the dx, or the dy >> to >>>> scaled "lengths" that represent the lengths of the transformed >> dashes >>>> projected onto the major axis. >>>> >>>> Finally, the other dx,dy can be computed from the dx,dy of the >> major >>>> axis with another scale. I am pretty sure that this dx=>dy or >> dy=>dx >>>> scale factor might be zero, but it would never be infinite if you >> are >>>> calculating along the major axis of the transformed line, but I >> didn't >>>> write out a proof for it. >>>> >>>> Taking both of these concepts into account - can that make the >> inner >>>> loop even simpler? >>>> >>>> ...jim >>>> >>>> Denis Lila wrote: >>>>> Hello. >>>>> >>>>> I think I have a fix for this bug: >>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=504 >>>>> The problem is caused by the "symmetric" variable in >>>> pisces/Dasher.java. >>>>> symmetric is set to (m00 == m11 && m10 == -m01), and never >> changed. >>>>> It is only used in one place (in lineTo) to simplify the >> computation >>>> of >>>>> the length of the line before an affine transformation A was >> applied >>>> to it. >>>>> This is why it causes a problem: >>>>> If A = [[a00, a01], [a10, a11]] and (x,y) is a point obtained by >>>> applying >>>>> A to some other point (x',y'), then what we want is the length of >>>> the vector >>>>> (x',y'), which is ||Ainv*(x,y)||. Ainv = (1/det(A)) * [[a11, >>>> -a01],[-a10, a00]], >>>>> so, after some calculations, ||Ainv*(x,y)|| ends up being equal >> to >>>>> sqrt(x^2*(a11^2 + a10^2) + y^2*(a00^2 + a01^2) - x*y*(a11*a01 + >>>> a00*a10)) * 1/|det(A)|. >>>>> If symmetric==true, this simplifies to: >>>>> sqrt((a11^2 + a01^2) * (x^2 + y^2)) * 1/|det(A)|, and >>>>> |det(A)| = a11^2 + a01^2, so, the final answer is: >>>>> sqrt((x^2 + y^2)) / sqrt(det(A)). Therefore the problem in >>>> Dasher.java >>>>> is that it divides by det(A), not sqrt(det(A)). >>>>> >>>>> My fix for this was to remove the "symmetric" special case. >> Another >>>> possible fix >>>>> would have been to introduce an instance "sqrtldet" and set it to >>>> sqrt(det(A)), >>>>> and divide by that instead of det(A). This didn't seem worth it, >>>> because the only >>>>> benefit we gain by having the "symmetric" variable is to save 3 >>>> multiplications >>>>> and 1 division per iteration of the while(true) loop, at the >> expense >>>> of making the >>>>> code more complex, harder to read, introducing more opportunity >> for >>>> bugs, and adding >>>>> hundreds of operations of overhead (since PiscesMath.sqrt would >> have >>>> to be called to >>>>> initialize sqrtldet). >>>>> >>>>> To make up for this slight performance loss I have moved the code >>>> that computes >>>>> the transformed dash vectors outside of the while loop, since >> they >>>> are constant >>>>> and they only need to be computed once for any one line. >>>>> Moreover, computing the constant dash vectors inside the loop >>>> causes >>>>> them to not really be constant (since they're computed by >> dividing >>>> numbers that >>>>> aren't constant). This can cause irregularities in dashes (see >>>> comment 14 in >>>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=197). >>>>> >>>>> I would very much appreciate any comments/suggestions. >>>>> >>>>> Thank you, >>>>> Denis Lila. >>>>> From james.graham at oracle.com Thu Jul 8 01:00:58 2010 From: james.graham at oracle.com (Jim Graham) Date: Wed, 07 Jul 2010 18:00:58 -0700 Subject: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines. In-Reply-To: <2015058373.629241277218727181.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <2015058373.629241277218727181.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C35234A.4070303@oracle.com> Hi Denis, We need a lot of upgrades in this area, but they will come with some engineering cost. Note that the Ductus line widening code widens curves to curves, but many (most?) line wideners flatten everything to do widening so they only have to deal with algorithms that widen and join lines. I haven't applied myself to the task of creating an algorithm that can do their "direct curve widening" technique yet so I don't have a canned solution for that, but it would make the results of BasicStroke.createStrokedShape() much less verbose. Also, for a practical matter the existing down-stream rendering classes that take the output from these widening classes only deal with lines, but if they took the curves directly then they might be able to do a more efficient job of flattening the segments. Until then, the only case where it would matter much for these classes to output curves would be for BS.createStrokedShape() and even that would probably require some more plumbing from the code that feeds these classes. But, I want to raise visibility of these issues here because we should not be blindly accepting flattening as the law when we consider upgrades to this part of the code. It is currently an "easy way out" and as we spend time on the code we should provide resistance to accepting that philosophy by default... ...jim Denis Lila wrote: > That's true. > > Well, if we're worried about the generated paths being verbose > and taking long to process then the problem extends beyond just > drawing round end caps. As far as I can see, whenever a path is > drawn that doesn't consist only of straight lines (i.e. an ellipse), > a flattening path iterator is being used to feed Stroker. So all > the bezier curves are still broken down into tiny straight lines, > just not by Stroker itself. > > So, my question is, given a bezier curve C and a number w, is > there a way of quickly computing the control points of two bezier > curves C1, C2 such that the stuff between C1 and C2 is the widened > path? > More formally: compute the control points of C1, C2, where > C1 = {(x,y) + N(x,y)*(w/2) | (x,y) in C} > C1 = {(x,y) - N(x,y)*(w/2) | (x,y) in C}, where N(x,y) is the normal > of C at (x,y). > > If we could do this easily, then we can just make a new class that > outputs bezier curves that is similar in purpose to Stroker, but that > is used only when the output can handle bezier curves. This way, the > only use left for Stroker would be when anti-aliasing, and for > every thing else we wouldn't have to use a flattening path iterator. > > Thanks, > Denis. > > ----- "Jim Graham" wrote: > >> Hi Denis, >> >> Consider the case of using BasicStroke.createStrokedShape(). How do >> you >> know how many pixels the resulting path will occupy? You can't reduce >> >> to concrete samples if you don't know the transform. >> >> So, for rendering, then you may be correct. But for cases where the >> path is being asked for then beziers are the only responsible >> solution... >> >> ...jim >> >> Denis Lila wrote: >>> Hello Jim. >>> >>> I thought about checking the output and changing the behaviour >>> depending on whether the output is a PC2D or a LineSink, but I >> didn't >>> implement it because I thought the point was to get rid of the >> sampling >>> at this stage. However, if performance is the issue, then I guess >> I'll >>> start working on it. >>> >>> Although, I wonder whether it is really worth it. I think most lines >> drawn >>> won't be wider than about 5 pixels, which means that the current way >> will >>> emit about 7 lines, so that's 14 coordinates. 2 bezier quarter >> circles will >>> require 12 coordinates. In terms of storage, there isn't much >> difference, and >>> for lines of width 4 or smaller the current method is more >> efficient. >>> I'm also guessing that it's harder for the rasterizer to deal with >> bezier >>> curves than with straight lines, so is it possible that replacing >> the >>> 3.14*lineWidth/2 lines generated by the current method with 2 bezier >>> quarter circles isn't worth it (for small lineWidths)? >>> >>> Thanks, >>> Denis. >>> >>> ----- "Jim Graham" wrote: >>> >>>> Sigh - that makes sense. One issue is that the resulting paths it >>>> generates are much more "verbose" than they need to be. This would >>>> generally mean that it takes far more storage than it would >> otherwise >>>> need - and it means that if the result needs to be transformed then >> it >>>> would take many more computations to transform each segment than >> the >>>> bezier. >>>> >>>> So, perhaps it would be worth having it check the type of the >> output >>>> and >>>> do either a bezier or a bunch of lines depending on if it is a PC2D >> or >>>> a >>>> LineSink? >>>> >>>> Also, it isn't really that difficult to for Renderer to include >> its >>>> own >>>> Cubic/Quadratic flattening code, but it might involve more >>>> calculations >>>> than the round-cap code since it would have to be written for >>>> arbitrary >>>> beziers whereas if you know it is a quarter circle then it is >> easier >>>> to >>>> know how far to subdivide... :-( >>>> >>>> ...jim >>>> >>>> Denis Lila wrote: >>>>> So, I have been thinking about this, and I can't see a good >>>>> way to do it that wouldn't involve heavy changes to Pisces. >>>>> >>>>> In order for Stroker to generate Bezier quarter circles, it would >>>>> have to implement a curveTo method, which means Stroker should >>>>> start implementing PathConsumer2D and instead of using a LineSink >>>>> output it would have to use a PathConsumer2D output (either that, >>>> or >>>>> LineSink should include a curveTo method, but then there won't >>>> really >>>>> be any difference between a LineSink and a PathConsumer2D. By the >>>> way, >>>>> LineSink doesn't have any implemented methods, so why is it an >>>> abstract >>>>> class as opposed to an interface?) >>>>> >>>>> Stroker is used in 3 ways: >>>>> 1. As an implementation of BasicStroke's createStrokedShape >> method. >>>> This >>>>> uses a Path2D object as output. >>>>> 2. As a way of feeding a PathConsumer2D without calling >>>> createStrokedShape >>>>> to generate an intermediate Shape. This uses a PathConsumer2D >>>> output. >>>>> 3. As a way of feeding lines to a Renderer object, which >> generates >>>> alpha >>>>> tiles used for anti-aliasing that are fed to a cache and >> extracted >>>> as needed >>>>> by an AATileGenerator. Obviously, Stroker's output here is a >>>> Renderer. >>>>> 1 and 2 aren't problems, because the underlying output objects >>>> support >>>>> Bezier curves. 3, however, doesn't, and it seems like implementing >> a >>>>> curveTo method for Renderer would be very difficult because the >> way >>>> it >>>>> generates alpha tiles is by scanning the drawn edges with >>>> horizontal >>>>> scan lines, and for each scan line finding the x-intersections of >>>> the scan >>>>> lines and the edges. Then it determines the alpha values (I'm not >>>> too sure >>>>> how it does this). >>>>> In order to implement Bezier curves in Renderer, we would have to >>>> have >>>>> a quick way of computing, for each scan line, all its >> intersections >>>> with >>>>> however many Bezier curves are being drawn. >>>>> >>>>> I haven't given much thought to how this could be done, as I am >> not >>>> very >>>>> familiar with Bezier curves, but it doesn't seem easy enough to >>>> justify >>>>> fixing such a small bug. >>>>> >>>>> ----- Original Message ----- >>>>> From: "Jim Graham" >>>>> To: "Denis Lila" >>>>> Cc: 2d-dev at openjdk.java.net >>>>> Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada >>>> Eastern >>>>> Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on >>>> scaled lines. >>>>> I don't understand - why do we generate sample points based on >> the >>>> size >>>>> of the cap? Why not generate a pair of bezier quarter-circles >> and >>>> let >>>>> the rasterizer deal with sampling? >>>>> >>>>> ...jim >>>>> >>>>> Denis Lila wrote: >>>>>> Hello. >>>>>> >>>>>> I think I have a fix for this bug: >>>>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506 >>>>>> >>>>>> Basically, the problem is that if there is a magnifying affine >>>> transformation set on the graphics object and one tries to draw a >> line >>>> with small thickness and round end caps, the end caps appear >> jagged. >>>> This is because the computation of the length of the array that >>>> contains the points on the "pen" with which the decoration is >> drawn >>>> does not take into account the size of the pen after the >> magnification >>>> of the affine transformation. So, for example, if the line length >> was >>>> set to 1, and the transformation was a scaling by 10, the >> resulting >>>> pen would have a diameter of 10, but only 3 pen points would be >>>> computed (pi*untransformedLineWidth), so the end cap looks like a >>>> triangle. >>>>>> My fix computes an approximation of the circumference of the >>>> transformed pen (which is an ellipse) and uses that as the number >> of >>>> points on the pen. The approximation is crude, but it is simple, >>>> faster than alternatives >>>> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can >> say >>>> from observations that it works fairly well. >>>>>> There is also icing on the cake, in the form of slight >> improvements >>>> in performance when the scaling is a zooming out. Example: if the >>>> original line width was 100, but g2d.scale(0.1,0.1) was set, then >> the >>>> resulting line would have a width of 10, so only ~31 points are >>>> necessary for the decoration to look like a circle, but without >> this >>>> patch, about 314 points are computed (and a line is emitted to >> each >>>> one of them). >>>>>> I appreciate any feedback. >>>>>> >>>>>> Regards, >>>>>> Denis Lila. >>>>>> From james.graham at oracle.com Thu Jul 8 01:03:19 2010 From: james.graham at oracle.com (Jim Graham) Date: Wed, 07 Jul 2010 18:03:19 -0700 Subject: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines. In-Reply-To: <173792935.668431277234148269.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <173792935.668431277234148269.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C3523D7.3010002@oracle.com> You can google and find a dozen sites that detail the math that shows that Bezier approximations to quarter circles approximate the original arc to within about .1%. We use that kind of math in the geom classes (see ArcIterator and EllipseIterator)... ...jim Denis Lila wrote: > I also have two questions about computing a good bezier approximation > to circle arcs. > > 1. Given the arc (1,0)->(cos(a),sin(a)) where 0 in a good approximation to find the control points p1, p2 by solving > the equations imposed by the requirements B(1/3) = (cos(a/3), sin(a/3) > and B(2/3) = (cos(2a/3), sin(2a/3)). In other words, requiring that the > bezier curve go through two evenly spaced points in the arc. > > 2. If we have an affine transformation A which turns the circle arc in an > ellipse arc will the transformed control points Ap0, Ap1, Ap2, Ap3 define > a good bezier approximation to the ellipse arc? > > Thank you, > Denis. > > ----- "Denis Lila" wrote: > >> That's true. >> >> Well, if we're worried about the generated paths being verbose >> and taking long to process then the problem extends beyond just >> drawing round end caps. As far as I can see, whenever a path is >> drawn that doesn't consist only of straight lines (i.e. an ellipse), >> a flattening path iterator is being used to feed Stroker. So all >> the bezier curves are still broken down into tiny straight lines, >> just not by Stroker itself. >> >> So, my question is, given a bezier curve C and a number w, is >> there a way of quickly computing the control points of two bezier >> curves C1, C2 such that the stuff between C1 and C2 is the widened >> path? >> More formally: compute the control points of C1, C2, where >> C1 = {(x,y) + N(x,y)*(w/2) | (x,y) in C} >> C1 = {(x,y) - N(x,y)*(w/2) | (x,y) in C}, where N(x,y) is the normal >> of C at (x,y). >> >> If we could do this easily, then we can just make a new class that >> outputs bezier curves that is similar in purpose to Stroker, but that >> is used only when the output can handle bezier curves. This way, the >> only use left for Stroker would be when anti-aliasing, and for >> every thing else we wouldn't have to use a flattening path iterator. >> >> Thanks, >> Denis. >> >> ----- "Jim Graham" wrote: >> >>> Hi Denis, >>> >>> Consider the case of using BasicStroke.createStrokedShape(). How do >>> you >>> know how many pixels the resulting path will occupy? You can't >> reduce >>> to concrete samples if you don't know the transform. >>> >>> So, for rendering, then you may be correct. But for cases where the >>> path is being asked for then beziers are the only responsible >>> solution... >>> >>> ...jim >>> >>> Denis Lila wrote: >>>> Hello Jim. >>>> >>>> I thought about checking the output and changing the behaviour >>>> depending on whether the output is a PC2D or a LineSink, but I >>> didn't >>>> implement it because I thought the point was to get rid of the >>> sampling >>>> at this stage. However, if performance is the issue, then I guess >>> I'll >>>> start working on it. >>>> >>>> Although, I wonder whether it is really worth it. I think most >> lines >>> drawn >>>> won't be wider than about 5 pixels, which means that the current >> way >>> will >>>> emit about 7 lines, so that's 14 coordinates. 2 bezier quarter >>> circles will >>>> require 12 coordinates. In terms of storage, there isn't much >>> difference, and >>>> for lines of width 4 or smaller the current method is more >>> efficient. >>>> I'm also guessing that it's harder for the rasterizer to deal with >>> bezier >>>> curves than with straight lines, so is it possible that replacing >>> the >>>> 3.14*lineWidth/2 lines generated by the current method with 2 >> bezier >>>> quarter circles isn't worth it (for small lineWidths)? >>>> >>>> Thanks, >>>> Denis. >>>> >>>> ----- "Jim Graham" wrote: >>>> >>>>> Sigh - that makes sense. One issue is that the resulting paths >> it >>>>> generates are much more "verbose" than they need to be. This >> would >>>>> generally mean that it takes far more storage than it would >>> otherwise >>>>> need - and it means that if the result needs to be transformed >> then >>> it >>>>> would take many more computations to transform each segment than >>> the >>>>> bezier. >>>>> >>>>> So, perhaps it would be worth having it check the type of the >>> output >>>>> and >>>>> do either a bezier or a bunch of lines depending on if it is a >> PC2D >>> or >>>>> a >>>>> LineSink? >>>>> >>>>> Also, it isn't really that difficult to for Renderer to include >>> its >>>>> own >>>>> Cubic/Quadratic flattening code, but it might involve more >>>>> calculations >>>>> than the round-cap code since it would have to be written for >>>>> arbitrary >>>>> beziers whereas if you know it is a quarter circle then it is >>> easier >>>>> to >>>>> know how far to subdivide... :-( >>>>> >>>>> ...jim >>>>> >>>>> Denis Lila wrote: >>>>>> So, I have been thinking about this, and I can't see a good >>>>>> way to do it that wouldn't involve heavy changes to Pisces. >>>>>> >>>>>> In order for Stroker to generate Bezier quarter circles, it >> would >>>>>> have to implement a curveTo method, which means Stroker should >>>>>> start implementing PathConsumer2D and instead of using a >> LineSink >>>>>> output it would have to use a PathConsumer2D output (either >> that, >>>>> or >>>>>> LineSink should include a curveTo method, but then there won't >>>>> really >>>>>> be any difference between a LineSink and a PathConsumer2D. By >> the >>>>> way, >>>>>> LineSink doesn't have any implemented methods, so why is it an >>>>> abstract >>>>>> class as opposed to an interface?) >>>>>> >>>>>> Stroker is used in 3 ways: >>>>>> 1. As an implementation of BasicStroke's createStrokedShape >>> method. >>>>> This >>>>>> uses a Path2D object as output. >>>>>> 2. As a way of feeding a PathConsumer2D without calling >>>>> createStrokedShape >>>>>> to generate an intermediate Shape. This uses a PathConsumer2D >>>>> output. >>>>>> 3. As a way of feeding lines to a Renderer object, which >>> generates >>>>> alpha >>>>>> tiles used for anti-aliasing that are fed to a cache and >>> extracted >>>>> as needed >>>>>> by an AATileGenerator. Obviously, Stroker's output here is a >>>>> Renderer. >>>>>> 1 and 2 aren't problems, because the underlying output objects >>>>> support >>>>>> Bezier curves. 3, however, doesn't, and it seems like >> implementing >>> a >>>>>> curveTo method for Renderer would be very difficult because the >>> way >>>>> it >>>>>> generates alpha tiles is by scanning the drawn edges with >>>>> horizontal >>>>>> scan lines, and for each scan line finding the x-intersections >> of >>>>> the scan >>>>>> lines and the edges. Then it determines the alpha values (I'm >> not >>>>> too sure >>>>>> how it does this). >>>>>> In order to implement Bezier curves in Renderer, we would have >> to >>>>> have >>>>>> a quick way of computing, for each scan line, all its >>> intersections >>>>> with >>>>>> however many Bezier curves are being drawn. >>>>>> >>>>>> I haven't given much thought to how this could be done, as I am >>> not >>>>> very >>>>>> familiar with Bezier curves, but it doesn't seem easy enough to >>>>> justify >>>>>> fixing such a small bug. >>>>>> >>>>>> ----- Original Message ----- >>>>>> From: "Jim Graham" >>>>>> To: "Denis Lila" >>>>>> Cc: 2d-dev at openjdk.java.net >>>>>> Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada >>>>> Eastern >>>>>> Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on >>>>> scaled lines. >>>>>> I don't understand - why do we generate sample points based on >>> the >>>>> size >>>>>> of the cap? Why not generate a pair of bezier quarter-circles >>> and >>>>> let >>>>>> the rasterizer deal with sampling? >>>>>> >>>>>> ...jim >>>>>> >>>>>> Denis Lila wrote: >>>>>>> Hello. >>>>>>> >>>>>>> I think I have a fix for this bug: >>>>>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506 >>>>>>> >>>>>>> Basically, the problem is that if there is a magnifying affine >>>>> transformation set on the graphics object and one tries to draw a >>> line >>>>> with small thickness and round end caps, the end caps appear >>> jagged. >>>>> This is because the computation of the length of the array that >>>>> contains the points on the "pen" with which the decoration is >>> drawn >>>>> does not take into account the size of the pen after the >>> magnification >>>>> of the affine transformation. So, for example, if the line length >>> was >>>>> set to 1, and the transformation was a scaling by 10, the >>> resulting >>>>> pen would have a diameter of 10, but only 3 pen points would be >>>>> computed (pi*untransformedLineWidth), so the end cap looks like a >>>>> triangle. >>>>>>> My fix computes an approximation of the circumference of the >>>>> transformed pen (which is an ellipse) and uses that as the number >>> of >>>>> points on the pen. The approximation is crude, but it is simple, >>>>> faster than alternatives >>>>> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can >>> say >>>>> from observations that it works fairly well. >>>>>>> There is also icing on the cake, in the form of slight >>> improvements >>>>> in performance when the scaling is a zooming out. Example: if the >>>>> original line width was 100, but g2d.scale(0.1,0.1) was set, then >>> the >>>>> resulting line would have a width of 10, so only ~31 points are >>>>> necessary for the decoration to look like a circle, but without >>> this >>>>> patch, about 314 points are computed (and a line is emitted to >>> each >>>>> one of them). >>>>>>> I appreciate any feedback. >>>>>>> >>>>>>> Regards, >>>>>>> Denis Lila. >>>>>>> From james.graham at oracle.com Thu Jul 8 01:29:05 2010 From: james.graham at oracle.com (Jim Graham) Date: Wed, 07 Jul 2010 18:29:05 -0700 Subject: [OpenJDK 2D-Dev] X11 uniform scaled wide lines and dashed lines; STROKE_CONTROL in Pisces In-Reply-To: <58312289.350011278429027922.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <58312289.350011278429027922.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C3529E1.6030107@oracle.com> For AA this is exactly what we do (round to nearest pixel centers for strokes). Note that this is done prior to any line widening code is executed. For non-AA we normalize coordinates to, I believe the (0.25, 0.25) sub-pixel location. This is so that the transitions between widening of lines occurs evenly (particularly for horizontal and vertical wide lines). If you round to pixel edges then you have the following progression (note that the line width grows by half on either side of the original geometry so you have to consider the "line widths" where you encounter the pixel centers to your left and right (or above and below) which govern when that column (or row) of pixels first turns on): width 0.00 => 0.99 nothing drawn (except we kludge this) width 1.00 => 1.00 1 pixel wide (col to left turns on) width 1.01 => 2.99 2 pixels wide (col to right turns on) width 3.00 => 3.00 3 pixels wide (etc.) width 3.01 => 4.99 4 pixels wide Note that it is nearly impossible to get an odd-width line. You basically have to have exactly an integer width to get an odd-width line. This is because at the odd widths you reach the "half pixel" locations on both sides of the line at the same time. Due to the "half-open" insideness rules only one of the pixels will be chosen to be inside this path. Just below these sizes and you fail to hit either pixel center. Just at the integer size you reach both pixel centers at the same time. Just slightly larger than that width and now you've fully enclosed both pixel centers and the line width has to increase by nearly 2.0 until you reach the next pixel centers. (The kludge I talk about above is that we set a minimum pen width so that we never fail to draw a line even if the line width is set to 0.0, but the above table was a theoretical description of the absolute rules.) If we rounded them to pixel centers, then the transitions look like this: width 0.00 => 0.00 nothing drawn (modulo kludge) width 0.01 => 1.99 1 pixel wide (column you are in turns on) width 2.00 => 2.00 2 pixels wide (column to left turns on) width 2.01 => 3.99 3 pixels wide (column to right turns on) width 4.00 => 4.00 4 pixels wide (etc.) width 4.01 => 5.99 5 pixels wide We have a similar effect as above, but biased towards making even line widths harder. So, by locating lines at (0.25, 0.25) subpixel location we end up with a very even progression: width 0.00 => 0.50 nothing drawn (modulo kludge) width 0.51 => 1.50 1 pixel wide (column you are in turns on) width 1.51 => 2.50 2 pixel wide (column to left gets added) width 2.51 => 3.50 3 pixel wide (column to right gets added) width 3.51 => 4.50 4 pixel wide (etc.) This gives us nice even and gradual widening of the lines as we increase the line width by sub-pixel amounts and the line widths are fairly stable around integer widths. Also, note that we don't say "when stroking" as you might want to normalize both strokes and fills so that they continue to match. I believe that we normalize both strokes and fills for non-AA and we only normalize strokes for AA (and leave AA fills as "pure"). AA is less problematic with respect to creating gaps if your stroke and fill normalization are not consistent. The rounding equations are along the lines of: v = Math.floor(v + rval) + aval; For center of pixel you use (rval=0.0, aval=0.5) For 0.25,0.25 rounding use (rval=0.25, aval=0.25) For edge of pixel you use (rval=0.5, aval=0.0) Also, we came up with an interesting way of adjusting the control points of quads and cubics if we adjusted their end points, but I don't know if what we did was really the best idea. For quads we adjust the control point by the average of the adjustments that we applied to its 2 end points. For cubics, we move the first control point by the same amount as we moved the starting endpoint and the second control point by the amount we moved the final endpoint. The jury is out on whether that is the most aesthetic technique... ...jim Denis Lila wrote: > Regarding VALUE_STROKE_NORMALIZE the API says: > Stroke normalization control hint value -- geometry should > be normalized to improve uniformity or spacing of lines and > overall aesthetics. Note that different normalization > algorithms may be more successful than others for given > input paths. > > I can only think of one example where VALUE_STROKE_NORMALIZE makes a visible > difference between the closed source implementation and OpenJDK: > when drawing anti-aliased horizontal or vertical lines of width 1, Pisces > draws a 2 pixel wide line with half intensity (because integer coordinates > are between pixels). Sun's jdk with VALUE_SROKE_NORMALIZE turned on draws > a 1 pixel line with full intensity. This could to achieved by just > checking for normalization and rounding coordinates to the nearest half > pixel, but this solution seems too simple, and I'm not sure whether I'm missing > anything. It would also probably cause problems when drawing anti-aliased > short lines (which is done when drawing any sort of curve) > Unless, of course, this rounding was restricted to just horizontal and > vertical lines. > > Regards, > Denis. From james.graham at oracle.com Thu Jul 8 01:33:16 2010 From: james.graham at oracle.com (Jim Graham) Date: Wed, 07 Jul 2010 18:33:16 -0700 Subject: [OpenJDK 2D-Dev] X11 uniform scaled wide lines and dashed lines; STROKE_CONTROL in Pisces In-Reply-To: References: <716306149.303561278352768911.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> <1621437549.303931278354093053.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C352ADC.7040702@oracle.com> The first part means that if the scale is uniform in X and Y (AffineTransform has some logic to determine this property in its getType() method) then we can use X11 to do line widening by just giving it a scaled line width. Also, X11 is limited to integer line widths so we would only want to do this if the SPEED hint is specified (not QUALITY) or if the scaled line width was close to an integer. If we are going to use a software rasterizer to widen the line and then send over spans to render, it may be faster to just give X11 the original path and a scaled line width and ask it to widen the line. Even if it uses a software renderer the reduction in protocol traffic is a win, and their rasterizer is probably optimized for integer polygons and may likely be faster than our more general curve-handling code. But, I would rank this low on optimizations at this point... ...jim Clemens Eisserer wrote: > Hi Denis, > >> In sun.java2d.x11.X11Renderer, line 340, it says: >> // REMIND: X11 can handle uniform scaled wide lines >> // and dashed lines itself if we set the appropriate >> // XGC attributes (TBD). >> >> >> Also, it is a known issue that Pisces does not support the STROKE_CONTROL >> hint. >> >> I have been wanting to implement these two features, and I have a few questions: >> Has anything been decided on the first issue? Do we still want to implement it? >> If yes, can anyone give me some rough suggestions as to how I can get started? > > Its just my personal opinion, but I would recommend not implementing it. > Xorg falls back to software anyway for anything more complex than > solid rectangles and blits > and those code-paths will only be triggered for non-antialised > rendering with solid colors. > > Implementing it in Pisces would help every backend OpenJDK supports :) > > Just checked and I also ignore the STROKE_CONTROL stuff completly in > the cairo based Jules rasterizer. > Curious how that could be mapped to Cairo, do you know any more > in-depth explanation how it works - or examples how it should look > like? > > Thanks, Clemens From james.graham at oracle.com Thu Jul 8 01:38:19 2010 From: james.graham at oracle.com (Jim Graham) Date: Wed, 07 Jul 2010 18:38:19 -0700 Subject: [OpenJDK 2D-Dev] Fix for uniformly scaled dashed lines. In-Reply-To: <1895965261.205581278102523268.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <1895965261.205581278102523268.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C352C0B.6040707@oracle.com> This looks good, but don't assert that the transform is non-singular. Transforms can frequently be singular and that isn't an exception. Actually, a singular transform simply means that the entire coordinate space has collapsed to a line or a point and so nothing need be rendered. If there is a way to shortcut the rendering to a NOP that would be the right reaction to a singular transform... ...jim Denis Lila wrote: > Hello Jim. > > Here is a webrev for the patch: > http://icedtea.classpath.org/~dlila/webrevs/dasherFix/webrev/ > I have eliminated most of the setup code, like you suggested. > > This is both more efficient, and far clearer than the original code > (and especially my version of the patch. It is also correct in cases > where the transform is [[n,0],[0,n]]). > > I still have my version of the patch (the one with "dashesToCompute"), > and as I mentioned in another e-mail, the allocation of the array > can be eliminated, since it can be turned into a field. So it should > have better performance in pretty much all cases. > If you would like me to send a webrev for that too, e-mail me. > > Thank you, > Denis. > > ----- "Jim Graham" wrote: > >> Hi Denis, >> >> One request on your code - please don't use the variable "lowercase >> L". >> On my screen with Courier font I cannot distinguish between the >> number >> 1 and the lowercase L character and so I cannot verify if your code is >> >> correct. >> >> Also, by "inner loop" I meant the single loop. I use the term to mean >> >> the "loop that does all the work at the innermost level" without >> regard >> to whether the case contains only 1 loop and is therefore a degenerate >> >> application of the term. >> >> My comment about the "major axis" stuff was an optimization that is no >> >> longer needed. I though I saw calls to hypot() in the inner loop, but >> I >> just noticed that those were in deleted code and the new code has no >> such calls, so you can ignore it. If it makes the comment clearer, >> "major axis" is either the X or Y axis depending on whether the line >> is >> more horizontal or vertical, but you can ignore it now. >> >> I will note that the 2 arrays you compute are simply scaled versions >> of >> the dash array and so we could eliminate the extra allocations by >> simply >> computing the values inside the loop at the cost of a multiply per >> dash >> segment to offset the cost of an allocation per incoming line segment. >> >> Also, you would no longer need to compute the "dashesToCompute" value >> >> and the setup code would be much, much simpler (basically you just >> need >> to compute the untransformed length and the cx and cy values and then >> >> jump into the loop). >> >> I'm leaning towards the multiplies in the loop to greatly simplify the >> >> code... >> >> (One last comment - have you checked what happens with the code in the >> >> presence of a degenerate transform? A non-invertible transform may >> run >> the risk of an infinite loop if you assume that you can reverse >> compute >> the line length and end up with a finite value...) >> >> ...jim >> >> Denis Lila wrote: >>> Hello Jim. >>> >>> Thank you for your reply. It seems my code did not fully take into >>> account your second point after all. >>> The dx's of the transformed dashes are di*newx/ (where >>> di is the untransformed dash length, newx is the transformed x >>> coordinate, and is the untransformed line length). Obviously, >>> newx/ is constant for all dash segments, so it can be computed >>> outside of the loop, but I was computing t=di/ inside the loop, >>> and then t*newx also inside the loop. >>> >>> I have fixed this and I included an improved version of the patch. >>> >>> However, I do not understand the second part of your e-mail >>> ("One more optimization ..."). I am not sure what you mean by >>> "major axis", how one would loop along it, and what the "inner >> loop" >>> is. There are no nested loops in this method. >>> >>> Also, the computation of the dxi and dyi of the transformed dash >> segment >>> dash[i] involves just 1 multiplication and 1 bit shift (along with >> an >>> overhead of 2 divisions and 2 bit shifts). >>> The computation of the actual endpoint of the dashes (done in the >> while(true) >>> loop) most of the time involves just 2 additions. >>> I am not sure how this can be made any simpler. >>> >>> Thank you, >>> Denis. >>> >>> ----- "Jim Graham" wrote: >>> >>>> Hi Denis, >>>> >>>> Here are my thoughts on it: >>>> >>>> - Lines are affinely transformed into lines. The slope may be >>>> different >>>> before and after the transform, but both have a single slope. >>>> >>>> - The ratio of a line length to its transformed line length is a >> scale >>>> factor that depends solely on the angle of the line. Thus, for >>>> determining dashing you can simply compute this scale factor once >> for >>>> a >>>> given line and then that single scale factor can be applied to >> every >>>> dash segment. >>>> >>>> It appears that your setup code takes these factors into account, >>>> though >>>> I haven't done a grueling line by line analysis as to whether you >> got >>>> the math right. >>>> >>>> One more optimization is that once you know the angle of the line >> then >>>> you have a factor for how the length of a segment of that line >> relates >>>> to its dx and dy. Note that for horizontal and vertical lines one >> of >>>> those factors may be Infinity, but every line will have a non-zero >> and >>>> non-infinity factor for one of those two dimensions. >>>> >>>> This means that you can calculate the dashing by simply looping >> along >>>> the major axis of the line and comparing either the dx, or the dy >> to >>>> scaled "lengths" that represent the lengths of the transformed >> dashes >>>> projected onto the major axis. >>>> >>>> Finally, the other dx,dy can be computed from the dx,dy of the >> major >>>> axis with another scale. I am pretty sure that this dx=>dy or >> dy=>dx >>>> scale factor might be zero, but it would never be infinite if you >> are >>>> calculating along the major axis of the transformed line, but I >> didn't >>>> write out a proof for it. >>>> >>>> Taking both of these concepts into account - can that make the >> inner >>>> loop even simpler? >>>> >>>> ...jim >>>> >>>> Denis Lila wrote: >>>>> Hello. >>>>> >>>>> I think I have a fix for this bug: >>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=504 >>>>> The problem is caused by the "symmetric" variable in >>>> pisces/Dasher.java. >>>>> symmetric is set to (m00 == m11 && m10 == -m01), and never >> changed. >>>>> It is only used in one place (in lineTo) to simplify the >> computation >>>> of >>>>> the length of the line before an affine transformation A was >> applied >>>> to it. >>>>> This is why it causes a problem: >>>>> If A = [[a00, a01], [a10, a11]] and (x,y) is a point obtained by >>>> applying >>>>> A to some other point (x',y'), then what we want is the length of >>>> the vector >>>>> (x',y'), which is ||Ainv*(x,y)||. Ainv = (1/det(A)) * [[a11, >>>> -a01],[-a10, a00]], >>>>> so, after some calculations, ||Ainv*(x,y)|| ends up being equal >> to >>>>> sqrt(x^2*(a11^2 + a10^2) + y^2*(a00^2 + a01^2) - x*y*(a11*a01 + >>>> a00*a10)) * 1/|det(A)|. >>>>> If symmetric==true, this simplifies to: >>>>> sqrt((a11^2 + a01^2) * (x^2 + y^2)) * 1/|det(A)|, and >>>>> |det(A)| = a11^2 + a01^2, so, the final answer is: >>>>> sqrt((x^2 + y^2)) / sqrt(det(A)). Therefore the problem in >>>> Dasher.java >>>>> is that it divides by det(A), not sqrt(det(A)). >>>>> >>>>> My fix for this was to remove the "symmetric" special case. >> Another >>>> possible fix >>>>> would have been to introduce an instance "sqrtldet" and set it to >>>> sqrt(det(A)), >>>>> and divide by that instead of det(A). This didn't seem worth it, >>>> because the only >>>>> benefit we gain by having the "symmetric" variable is to save 3 >>>> multiplications >>>>> and 1 division per iteration of the while(true) loop, at the >> expense >>>> of making the >>>>> code more complex, harder to read, introducing more opportunity >> for >>>> bugs, and adding >>>>> hundreds of operations of overhead (since PiscesMath.sqrt would >> have >>>> to be called to >>>>> initialize sqrtldet). >>>>> >>>>> To make up for this slight performance loss I have moved the code >>>> that computes >>>>> the transformed dash vectors outside of the while loop, since >> they >>>> are constant >>>>> and they only need to be computed once for any one line. >>>>> Moreover, computing the constant dash vectors inside the loop >>>> causes >>>>> them to not really be constant (since they're computed by >> dividing >>>> numbers that >>>>> aren't constant). This can cause irregularities in dashes (see >>>> comment 14 in >>>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=197). >>>>> >>>>> I would very much appreciate any comments/suggestions. >>>>> >>>>> Thank you, >>>>> Denis Lila. >>>>> From linuxhippy at gmail.com Thu Jul 8 19:40:48 2010 From: linuxhippy at gmail.com (Clemens Eisserer) Date: Thu, 8 Jul 2010 21:40:48 +0200 Subject: [OpenJDK 2D-Dev] 2 small xrender fixes In-Reply-To: <4C350BD8.40403@oracle.com> References: <4C2128C8.8070302@oracle.com> <4C2D2496.80303@oracle.com> <4C350BD8.40403@oracle.com> Message-ID: Hi Phil, > I see the problem now. I looked at what T2K (the rasteriser) reports, but > in the non-T2K glue code we then make an adjustment in the case of LCD > glyphs > which simply should never have been applied in the case of an empty image. > It has never affected any of our code as I think we only truly use the width > (not the > same as advance) during blitting and the check for a null image stops us > before that's > an issue. Great you were able to reproduce it. With XRender the width is stored when uploading the glyph server-side, and somehow X didn't check for an empty glyph. > I'll file a bug and fix this. Thanks :) I'll do some further validation on the locking stuff, I am still not really sure were these jules crashes come from :-/ - Clemens From philip.race at oracle.com Thu Jul 8 19:50:29 2010 From: philip.race at oracle.com (Phil Race) Date: Thu, 08 Jul 2010 12:50:29 -0700 Subject: [OpenJDK 2D-Dev] 2 small xrender fixes In-Reply-To: References: <4C2128C8.8070302@oracle.com> <4C2D2496.80303@oracle.com> <4C350BD8.40403@oracle.com> Message-ID: <4C362C05.1040607@oracle.com> On 7/8/2010 12:40 PM, Clemens Eisserer wrote: > Hi Phil, > > >> I see the problem now. I looked at what T2K (the rasteriser) reports, but >> in the non-T2K glue code we then make an adjustment in the case of LCD >> glyphs >> which simply should never have been applied in the case of an empty image. >> It has never affected any of our code as I think we only truly use the width >> (not the >> same as advance) during blitting and the check for a null image stops us >> before that's >> an issue. >> > Great you were able to reproduce it. > With XRender the width is stored when uploading the glyph server-side, > and somehow X didn't check for an empty glyph. > > >> I'll file a bug and fix this. >> FYI .. I pushed the fix this morning. Its in the closed repo so you won't see it of course, except some day when it makes it into master and then into a binary build. -phil. > Thanks :) > > I'll do some further validation on the locking stuff, I am still not > really sure were these jules crashes come from :-/ > > - Clemens > From dlila at redhat.com Thu Jul 8 22:28:07 2010 From: dlila at redhat.com (Denis Lila) Date: Thu, 8 Jul 2010 18:28:07 -0400 (EDT) Subject: [OpenJDK 2D-Dev] X11 uniform scaled wide lines and dashed lines; STROKE_CONTROL in Pisces In-Reply-To: <766177342.562671278627935855.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <670766454.562791278628087354.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hello Jim. Thanks for that. I'll get to work on implementing it. One thing though, about normalizing the control points of bezier curves: pisces never gets any bezier curves as input. It only gets lines that are the product of flattening bezier curves. Pisces receives its input from flattening path iterators which get it from other path iterators. Of course we can't require these to send out normalized points. In order to normalize the control points we need to be able to look at the bezier curves in Pisces, so we can't just take all the input from the flattener. However, pisces can't handle curves (yet, hopefully), so after the normalization, they must be flattened, and this is the problem. I think it's a pretty good idea to do this by storing the input form the iterator into pisces (after normalization), creating a nameless path iterator that just iterates through all that, and using this iterator to create a flattening iterator, which then is used as before. Does anyone have any other ideas? Thank you, Denis. ----- "Jim Graham" wrote: > For AA this is exactly what we do (round to nearest pixel centers for > > strokes). Note that this is done prior to any line widening code is > executed. > > For non-AA we normalize coordinates to, I believe the (0.25, 0.25) > sub-pixel location. This is so that the transitions between widening > of > lines occurs evenly (particularly for horizontal and vertical wide > lines). If you round to pixel edges then you have the following > progression (note that the line width grows by half on either side of > > the original geometry so you have to consider the "line widths" where > > you encounter the pixel centers to your left and right (or above and > below) which govern when that column (or row) of pixels first turns > on): > > width 0.00 => 0.99 nothing drawn (except we kludge this) > width 1.00 => 1.00 1 pixel wide (col to left turns on) > width 1.01 => 2.99 2 pixels wide (col to right turns on) > width 3.00 => 3.00 3 pixels wide (etc.) > width 3.01 => 4.99 4 pixels wide > > Note that it is nearly impossible to get an odd-width line. You > basically have to have exactly an integer width to get an odd-width > line. This is because at the odd widths you reach the "half pixel" > locations on both sides of the line at the same time. Due to the > "half-open" insideness rules only one of the pixels will be chosen to > be > inside this path. Just below these sizes and you fail to hit either > pixel center. Just at the integer size you reach both pixel centers > at > the same time. Just slightly larger than that width and now you've > fully enclosed both pixel centers and the line width has to increase > by > nearly 2.0 until you reach the next pixel centers. > > (The kludge I talk about above is that we set a minimum pen width so > that we never fail to draw a line even if the line width is set to > 0.0, > but the above table was a theoretical description of the absolute > rules.) > > If we rounded them to pixel centers, then the transitions look like > this: > > width 0.00 => 0.00 nothing drawn (modulo kludge) > width 0.01 => 1.99 1 pixel wide (column you are in turns on) > width 2.00 => 2.00 2 pixels wide (column to left turns on) > width 2.01 => 3.99 3 pixels wide (column to right turns on) > width 4.00 => 4.00 4 pixels wide (etc.) > width 4.01 => 5.99 5 pixels wide > > We have a similar effect as above, but biased towards making even line > > widths harder. > > So, by locating lines at (0.25, 0.25) subpixel location we end up with > a > very even progression: > > width 0.00 => 0.50 nothing drawn (modulo kludge) > width 0.51 => 1.50 1 pixel wide (column you are in turns on) > width 1.51 => 2.50 2 pixel wide (column to left gets added) > width 2.51 => 3.50 3 pixel wide (column to right gets added) > width 3.51 => 4.50 4 pixel wide (etc.) > > This gives us nice even and gradual widening of the lines as we > increase > the line width by sub-pixel amounts and the line widths are fairly > stable around integer widths. > > Also, note that we don't say "when stroking" as you might want to > normalize both strokes and fills so that they continue to match. I > believe that we normalize both strokes and fills for non-AA and we > only > normalize strokes for AA (and leave AA fills as "pure"). AA is less > problematic with respect to creating gaps if your stroke and fill > normalization are not consistent. > > The rounding equations are along the lines of: > > v = Math.floor(v + rval) + aval; > > For center of pixel you use (rval=0.0, aval=0.5) > For 0.25,0.25 rounding use (rval=0.25, aval=0.25) > For edge of pixel you use (rval=0.5, aval=0.0) > > Also, we came up with an interesting way of adjusting the control > points > of quads and cubics if we adjusted their end points, but I don't know > if > what we did was really the best idea. For quads we adjust the control > > point by the average of the adjustments that we applied to its 2 end > points. For cubics, we move the first control point by the same > amount > as we moved the starting endpoint and the second control point by the > > amount we moved the final endpoint. The jury is out on whether that > is > the most aesthetic technique... > > ...jim > > Denis Lila wrote: > > Regarding VALUE_STROKE_NORMALIZE the API says: > > Stroke normalization control hint value -- geometry > should > > be normalized to improve uniformity or spacing of > lines and > > overall aesthetics. Note that different > normalization > > algorithms may be more successful than others for > given > > input paths. > > > > I can only think of one example where VALUE_STROKE_NORMALIZE makes a > visible > > difference between the closed source implementation and OpenJDK: > > when drawing anti-aliased horizontal or vertical lines of width 1, > Pisces > > draws a 2 pixel wide line with half intensity (because integer > coordinates > > are between pixels). Sun's jdk with VALUE_SROKE_NORMALIZE turned on > draws > > a 1 pixel line with full intensity. This could to achieved by just > > checking for normalization and rounding coordinates to the nearest > half > > pixel, but this solution seems too simple, and I'm not sure whether > I'm missing > > anything. It would also probably cause problems when drawing > anti-aliased > > short lines (which is done when drawing any sort of curve) > > Unless, of course, this rounding was restricted to just horizontal > and > > vertical lines. > > > > Regards, > > Denis. From dlila at redhat.com Fri Jul 9 19:24:48 2010 From: dlila at redhat.com (Denis Lila) Date: Fri, 9 Jul 2010 15:24:48 -0400 (EDT) Subject: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines. In-Reply-To: <1127536592.47461278703417624.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <1809042573.47591278703488559.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hello. I just noticed that approximation of circle arcs by bezier curves had already been implemented in ArcIterator by Jim Graham. It computes the same control points as my solution, but it does so more straightforwardly, without any rotation, so it is faster and clearer. I have updated my solution to include this. The link remains the same. Thanks, Denis. ----- "Denis Lila" wrote: > Hello. > > I think I got this working. The webrev is at: > http://icedtea.classpath.org/~dlila/webrevs/bezierRoundJoins/webrev/ > (NOTE: this is not a final version. I have included 2 versions > of 2 methods. Only one set should be kept. See below for more.) > > My Changes: > ----------- > 1. > I've made LineSink into an interface, rather than an abstract > class, > because all of its methods were abstract, so it makes more sense this > way. > > 2. > I've introduced a new interface that extends LineSink called > PathSink, > which allows the curveTo method, so there have been no changes to > Stroker's public interface. When someone wants to create a Stroker > with a PathSink output, it simply passes its constructor a PathSink, > so the only changes outside of Stroker are in PiscesRenderingEngine, > where the methods that handle Path2D and PathConsumer2D objects > create nameless PathSinks instead of nameless LineSinks. > > 3. In Stroker: > I've introduced a method called drawBezRoundJoin, analogous to > computeRoundJoin. In drawRoundJoin I detect whether the output is > a PathSink. If it is, I call drawBezRoundJoin, otherwise everything > proceeds as it used to. drawBezRoundJoin uses computeBezierPoints to > compute the control points. computeBezierPoints computes the control > points > for an arc of t radians, starting at angle a, with radius r > by computing the control points of an arc of radius 1 of t radians > that > starts at angle -t/2. This is done by solving the equations resulting > from the constraints that (P3-P2) and (P1-P0) must be parallel to the > arc's tangents at P3 and P0 respectively, and that B(1/2)=(1,0). Then > the > points are scaled by r, and rotated counter clockwise by a+t/2. > Then drawBezRoundJoin emits the curve. > All this is done in a loop which is used to break up large arcs > into > more than one bezier curve. Through the iterations, the computed > control > points don't change - the only thing that changes is how they're > rotated. > So a good alternative approach would be to do the rotation outside > of > computeBezierPoints, and call computeBezierPoints once outside of the > loop, > so that the control points aren't recomputed unnecessarily. > I have included code for this in the methods computeBezierPoints2 and > drawBezRoundJoin2. This is my favoured approach, since it is almost > as clear as the other one, and it is faster. > > There is one more optimization that can be made, and I've included > it > in a comment in line 703. > > I would very much appreciate any comments about any of this, but > especially > about the idea in line 703 and about > computeBezierPoints2,drawBezRoundJoin2 > vs. computeBezierPoints,drawBezRoundJoin. > > 4. > Stroker used to only have lines, but now it can emit lines and > curves, so > I needed to change the format of reverse, to not only store > coordinates, but > to also tag them as belonging to a line or a curve. > > > Other Approaches: > ----------------- > 1. > Since what needed to be done was to alter the behaviour of one > part of Stroker (drawing of round joins/caps) depending on the type > of the output object, I thought it would be appropriate to make > Stroker > an abstract factory, turn the methods that draw round joins/caps into > abstract ones, put all the common functionality in concrete methods > in Stroker, and put all the join/cap drawing methods in overriding > methods > in concrete children of Stroker (instances of which were returned > by static factories in Stroker). > However, this was a bad approach, because the round cap/join > drawing > methods are private, so the only way to call them in Stroker's > children > from public methods in Stroker is to cast "this". So the code became > littered with instanceof operators and casts. Not to mention that > Stroker's > public interface had to change, and some functionality was lost: > Stroker > allows changing it's output, so it is possible to use just 1 Stroker > object > to widen paths going to many different outputs (but not at the same > time). > This could no longer be supported with this approach. > The way I did it has none of these weaknesses. > > 2. As for algorithms for the circle approximation, I considered 2: > a. Compute the control points using the constraints that > B(1/3)=A(a+t/3) > and B(2/3) = A(a+2t/3) (i.e. make the arc and the bezier curve > coincide at 2 > evenly spaced points in the arc). This didn't work very well: some of > the end > caps looked more like triangles. > b. Let B(1/2) = A(a+t/2), and B'(1/2) = A'(a+t/2). This worked > better, but > still not good enough. > > If anyone knows of any better ways to compute the control points, > please let > me know. > > I'm sorry for the length of this. I tried to make it shorter. > > Thank you very much, > Denis. > > > ----- "Jim Graham" wrote: > > > Hi Denis, > > > > Consider the case of using BasicStroke.createStrokedShape(). How do > > you > > know how many pixels the resulting path will occupy? You can't > reduce > > > > to concrete samples if you don't know the transform. > > > > So, for rendering, then you may be correct. But for cases where the > > path is being asked for then beziers are the only responsible > > solution... > > > > ...jim > > > > Denis Lila wrote: > > > Hello Jim. > > > > > > I thought about checking the output and changing the behaviour > > > depending on whether the output is a PC2D or a LineSink, but I > > didn't > > > implement it because I thought the point was to get rid of the > > sampling > > > at this stage. However, if performance is the issue, then I guess > > I'll > > > start working on it. > > > > > > Although, I wonder whether it is really worth it. I think most > lines > > drawn > > > won't be wider than about 5 pixels, which means that the current > way > > will > > > emit about 7 lines, so that's 14 coordinates. 2 bezier quarter > > circles will > > > require 12 coordinates. In terms of storage, there isn't much > > difference, and > > > for lines of width 4 or smaller the current method is more > > efficient. > > > > > > I'm also guessing that it's harder for the rasterizer to deal with > > bezier > > > curves than with straight lines, so is it possible that replacing > > the > > > 3.14*lineWidth/2 lines generated by the current method with 2 > bezier > > > > > quarter circles isn't worth it (for small lineWidths)? > > > > > > Thanks, > > > Denis. > > > > > > ----- "Jim Graham" wrote: > > > > > >> Sigh - that makes sense. One issue is that the resulting paths > it > > > > >> generates are much more "verbose" than they need to be. This > would > > > > >> generally mean that it takes far more storage than it would > > otherwise > > >> > > >> need - and it means that if the result needs to be transformed > then > > it > > >> > > >> would take many more computations to transform each segment than > > the > > >> bezier. > > >> > > >> So, perhaps it would be worth having it check the type of the > > output > > >> and > > >> do either a bezier or a bunch of lines depending on if it is a > PC2D > > or > > >> a > > >> LineSink? > > >> > > >> Also, it isn't really that difficult to for Renderer to include > > its > > >> own > > >> Cubic/Quadratic flattening code, but it might involve more > > >> calculations > > >> than the round-cap code since it would have to be written for > > >> arbitrary > > >> beziers whereas if you know it is a quarter circle then it is > > easier > > >> to > > >> know how far to subdivide... :-( > > >> > > >> ...jim > > >> > > >> Denis Lila wrote: > > >>> So, I have been thinking about this, and I can't see a good > > >>> way to do it that wouldn't involve heavy changes to Pisces. > > >>> > > >>> In order for Stroker to generate Bezier quarter circles, it > would > > >>> have to implement a curveTo method, which means Stroker should > > >>> start implementing PathConsumer2D and instead of using a > LineSink > > >>> output it would have to use a PathConsumer2D output (either > that, > > >> or > > >>> LineSink should include a curveTo method, but then there won't > > >> really > > >>> be any difference between a LineSink and a PathConsumer2D. By > the > > >> way, > > >>> LineSink doesn't have any implemented methods, so why is it an > > >> abstract > > >>> class as opposed to an interface?) > > >>> > > >>> Stroker is used in 3 ways: > > >>> 1. As an implementation of BasicStroke's createStrokedShape > > method. > > >> This > > >>> uses a Path2D object as output. > > >>> 2. As a way of feeding a PathConsumer2D without calling > > >> createStrokedShape > > >>> to generate an intermediate Shape. This uses a PathConsumer2D > > >> output. > > >>> 3. As a way of feeding lines to a Renderer object, which > > generates > > >> alpha > > >>> tiles used for anti-aliasing that are fed to a cache and > > extracted > > >> as needed > > >>> by an AATileGenerator. Obviously, Stroker's output here is a > > >> Renderer. > > >>> 1 and 2 aren't problems, because the underlying output objects > > >> support > > >>> Bezier curves. 3, however, doesn't, and it seems like > implementing > > a > > >>> curveTo method for Renderer would be very difficult because the > > way > > >> it > > >>> generates alpha tiles is by scanning the drawn edges with > > >> horizontal > > >>> scan lines, and for each scan line finding the x-intersections > of > > >> the scan > > >>> lines and the edges. Then it determines the alpha values (I'm > not > > >> too sure > > >>> how it does this). > > >>> In order to implement Bezier curves in Renderer, we would have > to > > >> have > > >>> a quick way of computing, for each scan line, all its > > intersections > > >> with > > >>> however many Bezier curves are being drawn. > > >>> > > >>> I haven't given much thought to how this could be done, as I am > > not > > >> very > > >>> familiar with Bezier curves, but it doesn't seem easy enough to > > >> justify > > >>> fixing such a small bug. > > >>> > > >>> ----- Original Message ----- > > >>> From: "Jim Graham" > > >>> To: "Denis Lila" > > >>> Cc: 2d-dev at openjdk.java.net > > >>> Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada > > >> Eastern > > >>> Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on > > >> scaled lines. > > >>> I don't understand - why do we generate sample points based on > > the > > >> size > > >>> of the cap? Why not generate a pair of bezier quarter-circles > > and > > >> let > > >>> the rasterizer deal with sampling? > > >>> > > >>> ...jim > > >>> > > >>> Denis Lila wrote: > > >>>> Hello. > > >>>> > > >>>> I think I have a fix for this bug: > > >>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506 > > >>>> > > >>>> Basically, the problem is that if there is a magnifying affine > > >> transformation set on the graphics object and one tries to draw a > > line > > >> with small thickness and round end caps, the end caps appear > > jagged. > > >> This is because the computation of the length of the array that > > >> contains the points on the "pen" with which the decoration is > > drawn > > >> does not take into account the size of the pen after the > > magnification > > >> of the affine transformation. So, for example, if the line length > > was > > >> set to 1, and the transformation was a scaling by 10, the > > resulting > > >> pen would have a diameter of 10, but only 3 pen points would be > > >> computed (pi*untransformedLineWidth), so the end cap looks like a > > >> triangle. > > >>>> My fix computes an approximation of the circumference of the > > >> transformed pen (which is an ellipse) and uses that as the number > > of > > >> points on the pen. The approximation is crude, but it is simple, > > >> faster than alternatives > > >> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can > > say > > >> from observations that it works fairly well. > > >>>> There is also icing on the cake, in the form of slight > > improvements > > >> in performance when the scaling is a zooming out. Example: if the > > >> original line width was 100, but g2d.scale(0.1,0.1) was set, then > > the > > >> resulting line would have a width of 10, so only ~31 points are > > >> necessary for the decoration to look like a circle, but without > > this > > >> patch, about 314 points are computed (and a line is emitted to > > each > > >> one of them). > > >>>> I appreciate any feedback. > > >>>> > > >>>> Regards, > > >>>> Denis Lila. > > >>>> From james.graham at oracle.com Fri Jul 9 23:53:32 2010 From: james.graham at oracle.com (Jim Graham) Date: Fri, 09 Jul 2010 16:53:32 -0700 Subject: [OpenJDK 2D-Dev] X11 uniform scaled wide lines and dashed lines; STROKE_CONTROL in Pisces In-Reply-To: <670766454.562791278628087354.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <670766454.562791278628087354.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C37B67C.60704@oracle.com> Hi Denis, It would be ill-advised to normalize the coordinates after flattening. The quality would be really bad. Perhaps this is a good reason to start looking at updating Pisces to take curves and flatten at the lowest level? Or, I suppose we could get a non-flattened iterator from the source path, send it through a "normalizing" filter, and then through a flattening filter (the way many of the existing objects do flattening is to just get their regular iterator and run it through an instance of FlatteningPathIterator so we could do this manually with an intervening "NormalizingPathIterator" if normalization is needed)... ...jim Denis Lila wrote: > Hello Jim. > > Thanks for that. I'll get to work on implementing it. > > One thing though, about normalizing the control points of bezier > curves: pisces never gets any bezier curves as input. It only gets > lines that are the product of flattening bezier curves. > > Pisces receives its input from flattening path iterators which get it > from other path iterators. Of course we can't require these to send out > normalized points. In order to normalize the control points we need to > be able to look at the bezier curves in Pisces, so we can't just take > all the input from the flattener. However, pisces can't handle curves > (yet, hopefully), so after the normalization, they must be flattened, and > this is the problem. I think it's a pretty good idea to do this by > storing the input form the iterator into pisces (after normalization), > creating a nameless path iterator that just iterates through all that, > and using this iterator to create a flattening iterator, which then > is used as before. > > Does anyone have any other ideas? > > Thank you, > Denis. > > > ----- "Jim Graham" wrote: > >> For AA this is exactly what we do (round to nearest pixel centers for >> >> strokes). Note that this is done prior to any line widening code is >> executed. >> >> For non-AA we normalize coordinates to, I believe the (0.25, 0.25) >> sub-pixel location. This is so that the transitions between widening >> of >> lines occurs evenly (particularly for horizontal and vertical wide >> lines). If you round to pixel edges then you have the following >> progression (note that the line width grows by half on either side of >> >> the original geometry so you have to consider the "line widths" where >> >> you encounter the pixel centers to your left and right (or above and >> below) which govern when that column (or row) of pixels first turns >> on): >> >> width 0.00 => 0.99 nothing drawn (except we kludge this) >> width 1.00 => 1.00 1 pixel wide (col to left turns on) >> width 1.01 => 2.99 2 pixels wide (col to right turns on) >> width 3.00 => 3.00 3 pixels wide (etc.) >> width 3.01 => 4.99 4 pixels wide >> >> Note that it is nearly impossible to get an odd-width line. You >> basically have to have exactly an integer width to get an odd-width >> line. This is because at the odd widths you reach the "half pixel" >> locations on both sides of the line at the same time. Due to the >> "half-open" insideness rules only one of the pixels will be chosen to >> be >> inside this path. Just below these sizes and you fail to hit either >> pixel center. Just at the integer size you reach both pixel centers >> at >> the same time. Just slightly larger than that width and now you've >> fully enclosed both pixel centers and the line width has to increase >> by >> nearly 2.0 until you reach the next pixel centers. >> >> (The kludge I talk about above is that we set a minimum pen width so >> that we never fail to draw a line even if the line width is set to >> 0.0, >> but the above table was a theoretical description of the absolute >> rules.) >> >> If we rounded them to pixel centers, then the transitions look like >> this: >> >> width 0.00 => 0.00 nothing drawn (modulo kludge) >> width 0.01 => 1.99 1 pixel wide (column you are in turns on) >> width 2.00 => 2.00 2 pixels wide (column to left turns on) >> width 2.01 => 3.99 3 pixels wide (column to right turns on) >> width 4.00 => 4.00 4 pixels wide (etc.) >> width 4.01 => 5.99 5 pixels wide >> >> We have a similar effect as above, but biased towards making even line >> >> widths harder. >> >> So, by locating lines at (0.25, 0.25) subpixel location we end up with >> a >> very even progression: >> >> width 0.00 => 0.50 nothing drawn (modulo kludge) >> width 0.51 => 1.50 1 pixel wide (column you are in turns on) >> width 1.51 => 2.50 2 pixel wide (column to left gets added) >> width 2.51 => 3.50 3 pixel wide (column to right gets added) >> width 3.51 => 4.50 4 pixel wide (etc.) >> >> This gives us nice even and gradual widening of the lines as we >> increase >> the line width by sub-pixel amounts and the line widths are fairly >> stable around integer widths. >> >> Also, note that we don't say "when stroking" as you might want to >> normalize both strokes and fills so that they continue to match. I >> believe that we normalize both strokes and fills for non-AA and we >> only >> normalize strokes for AA (and leave AA fills as "pure"). AA is less >> problematic with respect to creating gaps if your stroke and fill >> normalization are not consistent. >> >> The rounding equations are along the lines of: >> >> v = Math.floor(v + rval) + aval; >> >> For center of pixel you use (rval=0.0, aval=0.5) >> For 0.25,0.25 rounding use (rval=0.25, aval=0.25) >> For edge of pixel you use (rval=0.5, aval=0.0) >> >> Also, we came up with an interesting way of adjusting the control >> points >> of quads and cubics if we adjusted their end points, but I don't know >> if >> what we did was really the best idea. For quads we adjust the control >> >> point by the average of the adjustments that we applied to its 2 end >> points. For cubics, we move the first control point by the same >> amount >> as we moved the starting endpoint and the second control point by the >> >> amount we moved the final endpoint. The jury is out on whether that >> is >> the most aesthetic technique... >> >> ...jim >> >> Denis Lila wrote: >>> Regarding VALUE_STROKE_NORMALIZE the API says: >>> Stroke normalization control hint value -- geometry >> should >>> be normalized to improve uniformity or spacing of >> lines and >>> overall aesthetics. Note that different >> normalization >>> algorithms may be more successful than others for >> given >>> input paths. >>> >>> I can only think of one example where VALUE_STROKE_NORMALIZE makes a >> visible >>> difference between the closed source implementation and OpenJDK: >>> when drawing anti-aliased horizontal or vertical lines of width 1, >> Pisces >>> draws a 2 pixel wide line with half intensity (because integer >> coordinates >>> are between pixels). Sun's jdk with VALUE_SROKE_NORMALIZE turned on >> draws >>> a 1 pixel line with full intensity. This could to achieved by just >>> checking for normalization and rounding coordinates to the nearest >> half >>> pixel, but this solution seems too simple, and I'm not sure whether >> I'm missing >>> anything. It would also probably cause problems when drawing >> anti-aliased >>> short lines (which is done when drawing any sort of curve) >>> Unless, of course, this rounding was restricted to just horizontal >> and >>> vertical lines. >>> >>> Regards, >>> Denis. From james.graham at oracle.com Fri Jul 9 23:54:15 2010 From: james.graham at oracle.com (Jim Graham) Date: Fri, 09 Jul 2010 16:54:15 -0700 Subject: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines. In-Reply-To: <1809042573.47591278703488559.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <1809042573.47591278703488559.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C37B6A7.1030805@oracle.com> (For the record, I got that algorithm from the web... ;-) ...jim Denis Lila wrote: > Hello. > > I just noticed that approximation of circle arcs by bezier curves > had already been implemented in ArcIterator by Jim Graham. > > It computes the same control points as my solution, but it does so > more straightforwardly, without any rotation, so it is faster and > clearer. I have updated my solution to include this. > > The link remains the same. > > Thanks, > Denis. > > ----- "Denis Lila" wrote: > >> Hello. >> >> I think I got this working. The webrev is at: >> http://icedtea.classpath.org/~dlila/webrevs/bezierRoundJoins/webrev/ >> (NOTE: this is not a final version. I have included 2 versions >> of 2 methods. Only one set should be kept. See below for more.) >> >> My Changes: >> ----------- >> 1. >> I've made LineSink into an interface, rather than an abstract >> class, >> because all of its methods were abstract, so it makes more sense this >> way. >> >> 2. >> I've introduced a new interface that extends LineSink called >> PathSink, >> which allows the curveTo method, so there have been no changes to >> Stroker's public interface. When someone wants to create a Stroker >> with a PathSink output, it simply passes its constructor a PathSink, >> so the only changes outside of Stroker are in PiscesRenderingEngine, >> where the methods that handle Path2D and PathConsumer2D objects >> create nameless PathSinks instead of nameless LineSinks. >> >> 3. In Stroker: >> I've introduced a method called drawBezRoundJoin, analogous to >> computeRoundJoin. In drawRoundJoin I detect whether the output is >> a PathSink. If it is, I call drawBezRoundJoin, otherwise everything >> proceeds as it used to. drawBezRoundJoin uses computeBezierPoints to >> compute the control points. computeBezierPoints computes the control >> points >> for an arc of t radians, starting at angle a, with radius r >> by computing the control points of an arc of radius 1 of t radians >> that >> starts at angle -t/2. This is done by solving the equations resulting >> from the constraints that (P3-P2) and (P1-P0) must be parallel to the >> arc's tangents at P3 and P0 respectively, and that B(1/2)=(1,0). Then >> the >> points are scaled by r, and rotated counter clockwise by a+t/2. >> Then drawBezRoundJoin emits the curve. >> All this is done in a loop which is used to break up large arcs >> into >> more than one bezier curve. Through the iterations, the computed >> control >> points don't change - the only thing that changes is how they're >> rotated. >> So a good alternative approach would be to do the rotation outside >> of >> computeBezierPoints, and call computeBezierPoints once outside of the >> loop, >> so that the control points aren't recomputed unnecessarily. >> I have included code for this in the methods computeBezierPoints2 and >> drawBezRoundJoin2. This is my favoured approach, since it is almost >> as clear as the other one, and it is faster. >> >> There is one more optimization that can be made, and I've included >> it >> in a comment in line 703. >> >> I would very much appreciate any comments about any of this, but >> especially >> about the idea in line 703 and about >> computeBezierPoints2,drawBezRoundJoin2 >> vs. computeBezierPoints,drawBezRoundJoin. >> >> 4. >> Stroker used to only have lines, but now it can emit lines and >> curves, so >> I needed to change the format of reverse, to not only store >> coordinates, but >> to also tag them as belonging to a line or a curve. >> >> >> Other Approaches: >> ----------------- >> 1. >> Since what needed to be done was to alter the behaviour of one >> part of Stroker (drawing of round joins/caps) depending on the type >> of the output object, I thought it would be appropriate to make >> Stroker >> an abstract factory, turn the methods that draw round joins/caps into >> abstract ones, put all the common functionality in concrete methods >> in Stroker, and put all the join/cap drawing methods in overriding >> methods >> in concrete children of Stroker (instances of which were returned >> by static factories in Stroker). >> However, this was a bad approach, because the round cap/join >> drawing >> methods are private, so the only way to call them in Stroker's >> children >> from public methods in Stroker is to cast "this". So the code became >> littered with instanceof operators and casts. Not to mention that >> Stroker's >> public interface had to change, and some functionality was lost: >> Stroker >> allows changing it's output, so it is possible to use just 1 Stroker >> object >> to widen paths going to many different outputs (but not at the same >> time). >> This could no longer be supported with this approach. >> The way I did it has none of these weaknesses. >> >> 2. As for algorithms for the circle approximation, I considered 2: >> a. Compute the control points using the constraints that >> B(1/3)=A(a+t/3) >> and B(2/3) = A(a+2t/3) (i.e. make the arc and the bezier curve >> coincide at 2 >> evenly spaced points in the arc). This didn't work very well: some of >> the end >> caps looked more like triangles. >> b. Let B(1/2) = A(a+t/2), and B'(1/2) = A'(a+t/2). This worked >> better, but >> still not good enough. >> >> If anyone knows of any better ways to compute the control points, >> please let >> me know. >> >> I'm sorry for the length of this. I tried to make it shorter. >> >> Thank you very much, >> Denis. >> >> >> ----- "Jim Graham" wrote: >> >>> Hi Denis, >>> >>> Consider the case of using BasicStroke.createStrokedShape(). How do >>> you >>> know how many pixels the resulting path will occupy? You can't >> reduce >>> to concrete samples if you don't know the transform. >>> >>> So, for rendering, then you may be correct. But for cases where the >>> path is being asked for then beziers are the only responsible >>> solution... >>> >>> ...jim >>> >>> Denis Lila wrote: >>>> Hello Jim. >>>> >>>> I thought about checking the output and changing the behaviour >>>> depending on whether the output is a PC2D or a LineSink, but I >>> didn't >>>> implement it because I thought the point was to get rid of the >>> sampling >>>> at this stage. However, if performance is the issue, then I guess >>> I'll >>>> start working on it. >>>> >>>> Although, I wonder whether it is really worth it. I think most >> lines >>> drawn >>>> won't be wider than about 5 pixels, which means that the current >> way >>> will >>>> emit about 7 lines, so that's 14 coordinates. 2 bezier quarter >>> circles will >>>> require 12 coordinates. In terms of storage, there isn't much >>> difference, and >>>> for lines of width 4 or smaller the current method is more >>> efficient. >>>> I'm also guessing that it's harder for the rasterizer to deal with >>> bezier >>>> curves than with straight lines, so is it possible that replacing >>> the >>>> 3.14*lineWidth/2 lines generated by the current method with 2 >> bezier >>>> quarter circles isn't worth it (for small lineWidths)? >>>> >>>> Thanks, >>>> Denis. >>>> >>>> ----- "Jim Graham" wrote: >>>> >>>>> Sigh - that makes sense. One issue is that the resulting paths >> it >>>>> generates are much more "verbose" than they need to be. This >> would >>>>> generally mean that it takes far more storage than it would >>> otherwise >>>>> need - and it means that if the result needs to be transformed >> then >>> it >>>>> would take many more computations to transform each segment than >>> the >>>>> bezier. >>>>> >>>>> So, perhaps it would be worth having it check the type of the >>> output >>>>> and >>>>> do either a bezier or a bunch of lines depending on if it is a >> PC2D >>> or >>>>> a >>>>> LineSink? >>>>> >>>>> Also, it isn't really that difficult to for Renderer to include >>> its >>>>> own >>>>> Cubic/Quadratic flattening code, but it might involve more >>>>> calculations >>>>> than the round-cap code since it would have to be written for >>>>> arbitrary >>>>> beziers whereas if you know it is a quarter circle then it is >>> easier >>>>> to >>>>> know how far to subdivide... :-( >>>>> >>>>> ...jim >>>>> >>>>> Denis Lila wrote: >>>>>> So, I have been thinking about this, and I can't see a good >>>>>> way to do it that wouldn't involve heavy changes to Pisces. >>>>>> >>>>>> In order for Stroker to generate Bezier quarter circles, it >> would >>>>>> have to implement a curveTo method, which means Stroker should >>>>>> start implementing PathConsumer2D and instead of using a >> LineSink >>>>>> output it would have to use a PathConsumer2D output (either >> that, >>>>> or >>>>>> LineSink should include a curveTo method, but then there won't >>>>> really >>>>>> be any difference between a LineSink and a PathConsumer2D. By >> the >>>>> way, >>>>>> LineSink doesn't have any implemented methods, so why is it an >>>>> abstract >>>>>> class as opposed to an interface?) >>>>>> >>>>>> Stroker is used in 3 ways: >>>>>> 1. As an implementation of BasicStroke's createStrokedShape >>> method. >>>>> This >>>>>> uses a Path2D object as output. >>>>>> 2. As a way of feeding a PathConsumer2D without calling >>>>> createStrokedShape >>>>>> to generate an intermediate Shape. This uses a PathConsumer2D >>>>> output. >>>>>> 3. As a way of feeding lines to a Renderer object, which >>> generates >>>>> alpha >>>>>> tiles used for anti-aliasing that are fed to a cache and >>> extracted >>>>> as needed >>>>>> by an AATileGenerator. Obviously, Stroker's output here is a >>>>> Renderer. >>>>>> 1 and 2 aren't problems, because the underlying output objects >>>>> support >>>>>> Bezier curves. 3, however, doesn't, and it seems like >> implementing >>> a >>>>>> curveTo method for Renderer would be very difficult because the >>> way >>>>> it >>>>>> generates alpha tiles is by scanning the drawn edges with >>>>> horizontal >>>>>> scan lines, and for each scan line finding the x-intersections >> of >>>>> the scan >>>>>> lines and the edges. Then it determines the alpha values (I'm >> not >>>>> too sure >>>>>> how it does this). >>>>>> In order to implement Bezier curves in Renderer, we would have >> to >>>>> have >>>>>> a quick way of computing, for each scan line, all its >>> intersections >>>>> with >>>>>> however many Bezier curves are being drawn. >>>>>> >>>>>> I haven't given much thought to how this could be done, as I am >>> not >>>>> very >>>>>> familiar with Bezier curves, but it doesn't seem easy enough to >>>>> justify >>>>>> fixing such a small bug. >>>>>> >>>>>> ----- Original Message ----- >>>>>> From: "Jim Graham" >>>>>> To: "Denis Lila" >>>>>> Cc: 2d-dev at openjdk.java.net >>>>>> Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada >>>>> Eastern >>>>>> Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on >>>>> scaled lines. >>>>>> I don't understand - why do we generate sample points based on >>> the >>>>> size >>>>>> of the cap? Why not generate a pair of bezier quarter-circles >>> and >>>>> let >>>>>> the rasterizer deal with sampling? >>>>>> >>>>>> ...jim >>>>>> >>>>>> Denis Lila wrote: >>>>>>> Hello. >>>>>>> >>>>>>> I think I have a fix for this bug: >>>>>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506 >>>>>>> >>>>>>> Basically, the problem is that if there is a magnifying affine >>>>> transformation set on the graphics object and one tries to draw a >>> line >>>>> with small thickness and round end caps, the end caps appear >>> jagged. >>>>> This is because the computation of the length of the array that >>>>> contains the points on the "pen" with which the decoration is >>> drawn >>>>> does not take into account the size of the pen after the >>> magnification >>>>> of the affine transformation. So, for example, if the line length >>> was >>>>> set to 1, and the transformation was a scaling by 10, the >>> resulting >>>>> pen would have a diameter of 10, but only 3 pen points would be >>>>> computed (pi*untransformedLineWidth), so the end cap looks like a >>>>> triangle. >>>>>>> My fix computes an approximation of the circumference of the >>>>> transformed pen (which is an ellipse) and uses that as the number >>> of >>>>> points on the pen. The approximation is crude, but it is simple, >>>>> faster than alternatives >>>>> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can >>> say >>>>> from observations that it works fairly well. >>>>>>> There is also icing on the cake, in the form of slight >>> improvements >>>>> in performance when the scaling is a zooming out. Example: if the >>>>> original line width was 100, but g2d.scale(0.1,0.1) was set, then >>> the >>>>> resulting line would have a width of 10, so only ~31 points are >>>>> necessary for the decoration to look like a circle, but without >>> this >>>>> patch, about 314 points are computed (and a line is emitted to >>> each >>>>> one of them). >>>>>>> I appreciate any feedback. >>>>>>> >>>>>>> Regards, >>>>>>> Denis Lila. >>>>>>> From james.graham at oracle.com Sat Jul 10 00:05:40 2010 From: james.graham at oracle.com (Jim Graham) Date: Fri, 09 Jul 2010 17:05:40 -0700 Subject: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines. In-Reply-To: <1809042573.47591278703488559.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <1809042573.47591278703488559.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C37B954.7000608@oracle.com> Hi Denis, You moved some code around without modifying it. This makes it hard to see what changed and what didn't and verify that the changes are accurate. Also, it adds diffs to the file that are unrelated to the fixing of the bug. Was there a practical reason for why you moved the code around? In particular I refer to: - the setup code that deals with "if (joinStyle == JOIN_MITER)" - the setOutput method - which not only moved, but lost its javadocs - computeMiter() and drawMiter() All of that code "appears" to be unchanged at first glance, but it is hard to tell from the webrevs. Also, a couple of stylistic issues: - you changed the declarations of isCCW which moved its arguments over, but the continuation lines aren't indented to match - The two "flavors" of emitCurveTo() should probably be next to each other (i.e. not have emitLineTo() between them or fall between the two flavors of emitLineTo()). In general I think the changes are OK, but I'm still reviewing them and the above issues sprung to mind on a first pass (and/or they are complicating the "contextual" review) so I thought I'd mention them earlier than later... ...jim Denis Lila wrote: > Hello. > > I just noticed that approximation of circle arcs by bezier curves > had already been implemented in ArcIterator by Jim Graham. > > It computes the same control points as my solution, but it does so > more straightforwardly, without any rotation, so it is faster and > clearer. I have updated my solution to include this. > > The link remains the same. > > Thanks, > Denis. > > ----- "Denis Lila" wrote: > >> Hello. >> >> I think I got this working. The webrev is at: >> http://icedtea.classpath.org/~dlila/webrevs/bezierRoundJoins/webrev/ >> (NOTE: this is not a final version. I have included 2 versions >> of 2 methods. Only one set should be kept. See below for more.) >> >> My Changes: >> ----------- >> 1. >> I've made LineSink into an interface, rather than an abstract >> class, >> because all of its methods were abstract, so it makes more sense this >> way. >> >> 2. >> I've introduced a new interface that extends LineSink called >> PathSink, >> which allows the curveTo method, so there have been no changes to >> Stroker's public interface. When someone wants to create a Stroker >> with a PathSink output, it simply passes its constructor a PathSink, >> so the only changes outside of Stroker are in PiscesRenderingEngine, >> where the methods that handle Path2D and PathConsumer2D objects >> create nameless PathSinks instead of nameless LineSinks. >> >> 3. In Stroker: >> I've introduced a method called drawBezRoundJoin, analogous to >> computeRoundJoin. In drawRoundJoin I detect whether the output is >> a PathSink. If it is, I call drawBezRoundJoin, otherwise everything >> proceeds as it used to. drawBezRoundJoin uses computeBezierPoints to >> compute the control points. computeBezierPoints computes the control >> points >> for an arc of t radians, starting at angle a, with radius r >> by computing the control points of an arc of radius 1 of t radians >> that >> starts at angle -t/2. This is done by solving the equations resulting >> from the constraints that (P3-P2) and (P1-P0) must be parallel to the >> arc's tangents at P3 and P0 respectively, and that B(1/2)=(1,0). Then >> the >> points are scaled by r, and rotated counter clockwise by a+t/2. >> Then drawBezRoundJoin emits the curve. >> All this is done in a loop which is used to break up large arcs >> into >> more than one bezier curve. Through the iterations, the computed >> control >> points don't change - the only thing that changes is how they're >> rotated. >> So a good alternative approach would be to do the rotation outside >> of >> computeBezierPoints, and call computeBezierPoints once outside of the >> loop, >> so that the control points aren't recomputed unnecessarily. >> I have included code for this in the methods computeBezierPoints2 and >> drawBezRoundJoin2. This is my favoured approach, since it is almost >> as clear as the other one, and it is faster. >> >> There is one more optimization that can be made, and I've included >> it >> in a comment in line 703. >> >> I would very much appreciate any comments about any of this, but >> especially >> about the idea in line 703 and about >> computeBezierPoints2,drawBezRoundJoin2 >> vs. computeBezierPoints,drawBezRoundJoin. >> >> 4. >> Stroker used to only have lines, but now it can emit lines and >> curves, so >> I needed to change the format of reverse, to not only store >> coordinates, but >> to also tag them as belonging to a line or a curve. >> >> >> Other Approaches: >> ----------------- >> 1. >> Since what needed to be done was to alter the behaviour of one >> part of Stroker (drawing of round joins/caps) depending on the type >> of the output object, I thought it would be appropriate to make >> Stroker >> an abstract factory, turn the methods that draw round joins/caps into >> abstract ones, put all the common functionality in concrete methods >> in Stroker, and put all the join/cap drawing methods in overriding >> methods >> in concrete children of Stroker (instances of which were returned >> by static factories in Stroker). >> However, this was a bad approach, because the round cap/join >> drawing >> methods are private, so the only way to call them in Stroker's >> children >> from public methods in Stroker is to cast "this". So the code became >> littered with instanceof operators and casts. Not to mention that >> Stroker's >> public interface had to change, and some functionality was lost: >> Stroker >> allows changing it's output, so it is possible to use just 1 Stroker >> object >> to widen paths going to many different outputs (but not at the same >> time). >> This could no longer be supported with this approach. >> The way I did it has none of these weaknesses. >> >> 2. As for algorithms for the circle approximation, I considered 2: >> a. Compute the control points using the constraints that >> B(1/3)=A(a+t/3) >> and B(2/3) = A(a+2t/3) (i.e. make the arc and the bezier curve >> coincide at 2 >> evenly spaced points in the arc). This didn't work very well: some of >> the end >> caps looked more like triangles. >> b. Let B(1/2) = A(a+t/2), and B'(1/2) = A'(a+t/2). This worked >> better, but >> still not good enough. >> >> If anyone knows of any better ways to compute the control points, >> please let >> me know. >> >> I'm sorry for the length of this. I tried to make it shorter. >> >> Thank you very much, >> Denis. >> >> >> ----- "Jim Graham" wrote: >> >>> Hi Denis, >>> >>> Consider the case of using BasicStroke.createStrokedShape(). How do >>> you >>> know how many pixels the resulting path will occupy? You can't >> reduce >>> to concrete samples if you don't know the transform. >>> >>> So, for rendering, then you may be correct. But for cases where the >>> path is being asked for then beziers are the only responsible >>> solution... >>> >>> ...jim >>> >>> Denis Lila wrote: >>>> Hello Jim. >>>> >>>> I thought about checking the output and changing the behaviour >>>> depending on whether the output is a PC2D or a LineSink, but I >>> didn't >>>> implement it because I thought the point was to get rid of the >>> sampling >>>> at this stage. However, if performance is the issue, then I guess >>> I'll >>>> start working on it. >>>> >>>> Although, I wonder whether it is really worth it. I think most >> lines >>> drawn >>>> won't be wider than about 5 pixels, which means that the current >> way >>> will >>>> emit about 7 lines, so that's 14 coordinates. 2 bezier quarter >>> circles will >>>> require 12 coordinates. In terms of storage, there isn't much >>> difference, and >>>> for lines of width 4 or smaller the current method is more >>> efficient. >>>> I'm also guessing that it's harder for the rasterizer to deal with >>> bezier >>>> curves than with straight lines, so is it possible that replacing >>> the >>>> 3.14*lineWidth/2 lines generated by the current method with 2 >> bezier >>>> quarter circles isn't worth it (for small lineWidths)? >>>> >>>> Thanks, >>>> Denis. >>>> >>>> ----- "Jim Graham" wrote: >>>> >>>>> Sigh - that makes sense. One issue is that the resulting paths >> it >>>>> generates are much more "verbose" than they need to be. This >> would >>>>> generally mean that it takes far more storage than it would >>> otherwise >>>>> need - and it means that if the result needs to be transformed >> then >>> it >>>>> would take many more computations to transform each segment than >>> the >>>>> bezier. >>>>> >>>>> So, perhaps it would be worth having it check the type of the >>> output >>>>> and >>>>> do either a bezier or a bunch of lines depending on if it is a >> PC2D >>> or >>>>> a >>>>> LineSink? >>>>> >>>>> Also, it isn't really that difficult to for Renderer to include >>> its >>>>> own >>>>> Cubic/Quadratic flattening code, but it might involve more >>>>> calculations >>>>> than the round-cap code since it would have to be written for >>>>> arbitrary >>>>> beziers whereas if you know it is a quarter circle then it is >>> easier >>>>> to >>>>> know how far to subdivide... :-( >>>>> >>>>> ...jim >>>>> >>>>> Denis Lila wrote: >>>>>> So, I have been thinking about this, and I can't see a good >>>>>> way to do it that wouldn't involve heavy changes to Pisces. >>>>>> >>>>>> In order for Stroker to generate Bezier quarter circles, it >> would >>>>>> have to implement a curveTo method, which means Stroker should >>>>>> start implementing PathConsumer2D and instead of using a >> LineSink >>>>>> output it would have to use a PathConsumer2D output (either >> that, >>>>> or >>>>>> LineSink should include a curveTo method, but then there won't >>>>> really >>>>>> be any difference between a LineSink and a PathConsumer2D. By >> the >>>>> way, >>>>>> LineSink doesn't have any implemented methods, so why is it an >>>>> abstract >>>>>> class as opposed to an interface?) >>>>>> >>>>>> Stroker is used in 3 ways: >>>>>> 1. As an implementation of BasicStroke's createStrokedShape >>> method. >>>>> This >>>>>> uses a Path2D object as output. >>>>>> 2. As a way of feeding a PathConsumer2D without calling >>>>> createStrokedShape >>>>>> to generate an intermediate Shape. This uses a PathConsumer2D >>>>> output. >>>>>> 3. As a way of feeding lines to a Renderer object, which >>> generates >>>>> alpha >>>>>> tiles used for anti-aliasing that are fed to a cache and >>> extracted >>>>> as needed >>>>>> by an AATileGenerator. Obviously, Stroker's output here is a >>>>> Renderer. >>>>>> 1 and 2 aren't problems, because the underlying output objects >>>>> support >>>>>> Bezier curves. 3, however, doesn't, and it seems like >> implementing >>> a >>>>>> curveTo method for Renderer would be very difficult because the >>> way >>>>> it >>>>>> generates alpha tiles is by scanning the drawn edges with >>>>> horizontal >>>>>> scan lines, and for each scan line finding the x-intersections >> of >>>>> the scan >>>>>> lines and the edges. Then it determines the alpha values (I'm >> not >>>>> too sure >>>>>> how it does this). >>>>>> In order to implement Bezier curves in Renderer, we would have >> to >>>>> have >>>>>> a quick way of computing, for each scan line, all its >>> intersections >>>>> with >>>>>> however many Bezier curves are being drawn. >>>>>> >>>>>> I haven't given much thought to how this could be done, as I am >>> not >>>>> very >>>>>> familiar with Bezier curves, but it doesn't seem easy enough to >>>>> justify >>>>>> fixing such a small bug. >>>>>> >>>>>> ----- Original Message ----- >>>>>> From: "Jim Graham" >>>>>> To: "Denis Lila" >>>>>> Cc: 2d-dev at openjdk.java.net >>>>>> Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada >>>>> Eastern >>>>>> Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on >>>>> scaled lines. >>>>>> I don't understand - why do we generate sample points based on >>> the >>>>> size >>>>>> of the cap? Why not generate a pair of bezier quarter-circles >>> and >>>>> let >>>>>> the rasterizer deal with sampling? >>>>>> >>>>>> ...jim >>>>>> >>>>>> Denis Lila wrote: >>>>>>> Hello. >>>>>>> >>>>>>> I think I have a fix for this bug: >>>>>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506 >>>>>>> >>>>>>> Basically, the problem is that if there is a magnifying affine >>>>> transformation set on the graphics object and one tries to draw a >>> line >>>>> with small thickness and round end caps, the end caps appear >>> jagged. >>>>> This is because the computation of the length of the array that >>>>> contains the points on the "pen" with which the decoration is >>> drawn >>>>> does not take into account the size of the pen after the >>> magnification >>>>> of the affine transformation. So, for example, if the line length >>> was >>>>> set to 1, and the transformation was a scaling by 10, the >>> resulting >>>>> pen would have a diameter of 10, but only 3 pen points would be >>>>> computed (pi*untransformedLineWidth), so the end cap looks like a >>>>> triangle. >>>>>>> My fix computes an approximation of the circumference of the >>>>> transformed pen (which is an ellipse) and uses that as the number >>> of >>>>> points on the pen. The approximation is crude, but it is simple, >>>>> faster than alternatives >>>>> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can >>> say >>>>> from observations that it works fairly well. >>>>>>> There is also icing on the cake, in the form of slight >>> improvements >>>>> in performance when the scaling is a zooming out. Example: if the >>>>> original line width was 100, but g2d.scale(0.1,0.1) was set, then >>> the >>>>> resulting line would have a width of 10, so only ~31 points are >>>>> necessary for the decoration to look like a circle, but without >>> this >>>>> patch, about 314 points are computed (and a line is emitted to >>> each >>>>> one of them). >>>>>>> I appreciate any feedback. >>>>>>> >>>>>>> Regards, >>>>>>> Denis Lila. >>>>>>> From james.graham at oracle.com Sat Jul 10 00:16:38 2010 From: james.graham at oracle.com (Jim Graham) Date: Fri, 09 Jul 2010 17:16:38 -0700 Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <4C37B6A7.1030805@oracle.com> References: <1809042573.47591278703488559.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> <4C37B6A7.1030805@oracle.com> Message-ID: <4C37BBE6.2070903@oracle.com> Sigh... Pisces could really stand to upgrade to floats/doubles everywhere, for several reasons: - FPU ops are likely as fast if not faster on modern hardware due to parallel execution of FP instructions alongside regular instructions. - Don't have to worry about getting coordinates larger than 32K (I don't think this is well tested, but I imagine that Pisces will not deal with it very gracefully). - Lots of code is greatly simplified not having to deal with the semantics of how to do fixed point multiplies, divides, and conversions. I meant to do this during the original integration, but I wanted to get the task done as quickly as possible so that we could have an open source alternative to the closed Ductus code so I left that task for a later update. But, now that a lot of work is being done on the code to fix it up, it might be better to do the float conversion now so that the maintenance is easier and before we end up creating a lot of new fixed point code. My plate is full right now, but hopefully I can interest someone else in doing a cleanup cycle? (Donning my Tom Sawyer hat... ;-) ...jim From james.graham at oracle.com Sat Jul 10 00:17:52 2010 From: james.graham at oracle.com (Jim Graham) Date: Fri, 09 Jul 2010 17:17:52 -0700 Subject: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines. In-Reply-To: <4C37B954.7000608@oracle.com> References: <1809042573.47591278703488559.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> <4C37B954.7000608@oracle.com> Message-ID: <4C37BC30.7050002@oracle.com> Also, the Stroker() constructor, which was marked private in these webrevs, isn't used - it should probably just be deleted rather than made private... ...jim Jim Graham wrote: > Hi Denis, > > You moved some code around without modifying it. This makes it hard to > see what changed and what didn't and verify that the changes are > accurate. Also, it adds diffs to the file that are unrelated to the > fixing of the bug. Was there a practical reason for why you moved the > code around? In particular I refer to: > > - the setup code that deals with "if (joinStyle == JOIN_MITER)" > > - the setOutput method - which not only moved, but lost its javadocs > > - computeMiter() and drawMiter() > > All of that code "appears" to be unchanged at first glance, but it is > hard to tell from the webrevs. Also, a couple of stylistic issues: > > - you changed the declarations of isCCW which moved its arguments over, > but the continuation lines aren't indented to match > > - The two "flavors" of emitCurveTo() should probably be next to each > other (i.e. not have emitLineTo() between them or fall between the two > flavors of emitLineTo()). > > In general I think the changes are OK, but I'm still reviewing them and > the above issues sprung to mind on a first pass (and/or they are > complicating the "contextual" review) so I thought I'd mention them > earlier than later... > > ...jim > > Denis Lila wrote: >> Hello. >> >> I just noticed that approximation of circle arcs by bezier curves >> had already been implemented in ArcIterator by Jim Graham. >> It computes the same control points as my solution, but it does so >> more straightforwardly, without any rotation, so it is faster and >> clearer. I have updated my solution to include this. >> >> The link remains the same. >> >> Thanks, >> Denis. >> >> ----- "Denis Lila" wrote: >> >>> Hello. >>> >>> I think I got this working. The webrev is at: >>> http://icedtea.classpath.org/~dlila/webrevs/bezierRoundJoins/webrev/ >>> (NOTE: this is not a final version. I have included 2 versions >>> of 2 methods. Only one set should be kept. See below for more.) >>> >>> My Changes: >>> ----------- >>> 1. >>> I've made LineSink into an interface, rather than an abstract >>> class, >>> because all of its methods were abstract, so it makes more sense this >>> way. >>> >>> 2. >>> I've introduced a new interface that extends LineSink called >>> PathSink, >>> which allows the curveTo method, so there have been no changes to >>> Stroker's public interface. When someone wants to create a Stroker >>> with a PathSink output, it simply passes its constructor a PathSink, >>> so the only changes outside of Stroker are in PiscesRenderingEngine, >>> where the methods that handle Path2D and PathConsumer2D objects >>> create nameless PathSinks instead of nameless LineSinks. >>> >>> 3. In Stroker: >>> I've introduced a method called drawBezRoundJoin, analogous to >>> computeRoundJoin. In drawRoundJoin I detect whether the output is >>> a PathSink. If it is, I call drawBezRoundJoin, otherwise everything >>> proceeds as it used to. drawBezRoundJoin uses computeBezierPoints to >>> compute the control points. computeBezierPoints computes the control >>> points >>> for an arc of t radians, starting at angle a, with radius r >>> by computing the control points of an arc of radius 1 of t radians >>> that >>> starts at angle -t/2. This is done by solving the equations resulting >>> from the constraints that (P3-P2) and (P1-P0) must be parallel to the >>> arc's tangents at P3 and P0 respectively, and that B(1/2)=(1,0). Then >>> the >>> points are scaled by r, and rotated counter clockwise by a+t/2. >>> Then drawBezRoundJoin emits the curve. >>> All this is done in a loop which is used to break up large arcs >>> into >>> more than one bezier curve. Through the iterations, the computed >>> control >>> points don't change - the only thing that changes is how they're >>> rotated. >>> So a good alternative approach would be to do the rotation outside >>> of >>> computeBezierPoints, and call computeBezierPoints once outside of the >>> loop, >>> so that the control points aren't recomputed unnecessarily. >>> I have included code for this in the methods computeBezierPoints2 and >>> drawBezRoundJoin2. This is my favoured approach, since it is almost >>> as clear as the other one, and it is faster. >>> >>> There is one more optimization that can be made, and I've included >>> it >>> in a comment in line 703. >>> >>> I would very much appreciate any comments about any of this, but >>> especially >>> about the idea in line 703 and about >>> computeBezierPoints2,drawBezRoundJoin2 >>> vs. computeBezierPoints,drawBezRoundJoin. >>> >>> 4. >>> Stroker used to only have lines, but now it can emit lines and >>> curves, so >>> I needed to change the format of reverse, to not only store >>> coordinates, but >>> to also tag them as belonging to a line or a curve. >>> >>> >>> Other Approaches: >>> ----------------- >>> 1. >>> Since what needed to be done was to alter the behaviour of one >>> part of Stroker (drawing of round joins/caps) depending on the type >>> of the output object, I thought it would be appropriate to make >>> Stroker >>> an abstract factory, turn the methods that draw round joins/caps into >>> abstract ones, put all the common functionality in concrete methods >>> in Stroker, and put all the join/cap drawing methods in overriding >>> methods >>> in concrete children of Stroker (instances of which were returned >>> by static factories in Stroker). >>> However, this was a bad approach, because the round cap/join >>> drawing >>> methods are private, so the only way to call them in Stroker's >>> children >>> from public methods in Stroker is to cast "this". So the code became >>> littered with instanceof operators and casts. Not to mention that >>> Stroker's >>> public interface had to change, and some functionality was lost: >>> Stroker >>> allows changing it's output, so it is possible to use just 1 Stroker >>> object >>> to widen paths going to many different outputs (but not at the same >>> time). >>> This could no longer be supported with this approach. >>> The way I did it has none of these weaknesses. >>> >>> 2. As for algorithms for the circle approximation, I considered 2: >>> a. Compute the control points using the constraints that >>> B(1/3)=A(a+t/3) >>> and B(2/3) = A(a+2t/3) (i.e. make the arc and the bezier curve >>> coincide at 2 >>> evenly spaced points in the arc). This didn't work very well: some of >>> the end >>> caps looked more like triangles. >>> b. Let B(1/2) = A(a+t/2), and B'(1/2) = A'(a+t/2). This worked >>> better, but >>> still not good enough. >>> >>> If anyone knows of any better ways to compute the control points, >>> please let >>> me know. >>> >>> I'm sorry for the length of this. I tried to make it shorter. >>> >>> Thank you very much, >>> Denis. >>> >>> >>> ----- "Jim Graham" wrote: >>> >>>> Hi Denis, >>>> >>>> Consider the case of using BasicStroke.createStrokedShape(). How do >>>> you >>>> know how many pixels the resulting path will occupy? You can't >>> reduce >>>> to concrete samples if you don't know the transform. >>>> >>>> So, for rendering, then you may be correct. But for cases where the >>>> path is being asked for then beziers are the only responsible >>>> solution... >>>> >>>> ...jim >>>> >>>> Denis Lila wrote: >>>>> Hello Jim. >>>>> >>>>> I thought about checking the output and changing the behaviour >>>>> depending on whether the output is a PC2D or a LineSink, but I >>>> didn't >>>>> implement it because I thought the point was to get rid of the >>>> sampling >>>>> at this stage. However, if performance is the issue, then I guess >>>> I'll >>>>> start working on it. >>>>> >>>>> Although, I wonder whether it is really worth it. I think most >>> lines >>>> drawn >>>>> won't be wider than about 5 pixels, which means that the current >>> way >>>> will >>>>> emit about 7 lines, so that's 14 coordinates. 2 bezier quarter >>>> circles will >>>>> require 12 coordinates. In terms of storage, there isn't much >>>> difference, and >>>>> for lines of width 4 or smaller the current method is more >>>> efficient. >>>>> I'm also guessing that it's harder for the rasterizer to deal with >>>> bezier >>>>> curves than with straight lines, so is it possible that replacing >>>> the >>>>> 3.14*lineWidth/2 lines generated by the current method with 2 >>> bezier >>>>> quarter circles isn't worth it (for small lineWidths)? >>>>> >>>>> Thanks, >>>>> Denis. >>>>> >>>>> ----- "Jim Graham" wrote: >>>>> >>>>>> Sigh - that makes sense. One issue is that the resulting paths >>> it >>>>>> generates are much more "verbose" than they need to be. This >>> would >>>>>> generally mean that it takes far more storage than it would >>>> otherwise >>>>>> need - and it means that if the result needs to be transformed >>> then >>>> it >>>>>> would take many more computations to transform each segment than >>>> the >>>>>> bezier. >>>>>> >>>>>> So, perhaps it would be worth having it check the type of the >>>> output >>>>>> and >>>>>> do either a bezier or a bunch of lines depending on if it is a >>> PC2D >>>> or >>>>>> a >>>>>> LineSink? >>>>>> >>>>>> Also, it isn't really that difficult to for Renderer to include >>>> its >>>>>> own >>>>>> Cubic/Quadratic flattening code, but it might involve more >>>>>> calculations >>>>>> than the round-cap code since it would have to be written for >>>>>> arbitrary >>>>>> beziers whereas if you know it is a quarter circle then it is >>>> easier >>>>>> to >>>>>> know how far to subdivide... :-( >>>>>> >>>>>> ...jim >>>>>> >>>>>> Denis Lila wrote: >>>>>>> So, I have been thinking about this, and I can't see a good >>>>>>> way to do it that wouldn't involve heavy changes to Pisces. >>>>>>> >>>>>>> In order for Stroker to generate Bezier quarter circles, it >>> would >>>>>>> have to implement a curveTo method, which means Stroker should >>>>>>> start implementing PathConsumer2D and instead of using a >>> LineSink >>>>>>> output it would have to use a PathConsumer2D output (either >>> that, >>>>>> or >>>>>>> LineSink should include a curveTo method, but then there won't >>>>>> really >>>>>>> be any difference between a LineSink and a PathConsumer2D. By >>> the >>>>>> way, >>>>>>> LineSink doesn't have any implemented methods, so why is it an >>>>>> abstract >>>>>>> class as opposed to an interface?) >>>>>>> >>>>>>> Stroker is used in 3 ways: >>>>>>> 1. As an implementation of BasicStroke's createStrokedShape >>>> method. >>>>>> This >>>>>>> uses a Path2D object as output. >>>>>>> 2. As a way of feeding a PathConsumer2D without calling >>>>>> createStrokedShape >>>>>>> to generate an intermediate Shape. This uses a PathConsumer2D >>>>>> output. >>>>>>> 3. As a way of feeding lines to a Renderer object, which >>>> generates >>>>>> alpha >>>>>>> tiles used for anti-aliasing that are fed to a cache and >>>> extracted >>>>>> as needed >>>>>>> by an AATileGenerator. Obviously, Stroker's output here is a >>>>>> Renderer. >>>>>>> 1 and 2 aren't problems, because the underlying output objects >>>>>> support >>>>>>> Bezier curves. 3, however, doesn't, and it seems like >>> implementing >>>> a >>>>>>> curveTo method for Renderer would be very difficult because the >>>> way >>>>>> it >>>>>>> generates alpha tiles is by scanning the drawn edges with >>>>>> horizontal >>>>>>> scan lines, and for each scan line finding the x-intersections >>> of >>>>>> the scan >>>>>>> lines and the edges. Then it determines the alpha values (I'm >>> not >>>>>> too sure >>>>>>> how it does this). >>>>>>> In order to implement Bezier curves in Renderer, we would have >>> to >>>>>> have >>>>>>> a quick way of computing, for each scan line, all its >>>> intersections >>>>>> with >>>>>>> however many Bezier curves are being drawn. >>>>>>> >>>>>>> I haven't given much thought to how this could be done, as I am >>>> not >>>>>> very >>>>>>> familiar with Bezier curves, but it doesn't seem easy enough to >>>>>> justify >>>>>>> fixing such a small bug. >>>>>>> >>>>>>> ----- Original Message ----- >>>>>>> From: "Jim Graham" >>>>>>> To: "Denis Lila" >>>>>>> Cc: 2d-dev at openjdk.java.net >>>>>>> Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada >>>>>> Eastern >>>>>>> Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on >>>>>> scaled lines. >>>>>>> I don't understand - why do we generate sample points based on >>>> the >>>>>> size >>>>>>> of the cap? Why not generate a pair of bezier quarter-circles >>>> and >>>>>> let >>>>>>> the rasterizer deal with sampling? >>>>>>> >>>>>>> ...jim >>>>>>> >>>>>>> Denis Lila wrote: >>>>>>>> Hello. >>>>>>>> >>>>>>>> I think I have a fix for this bug: >>>>>>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506 >>>>>>>> >>>>>>>> Basically, the problem is that if there is a magnifying affine >>>>>> transformation set on the graphics object and one tries to draw a >>>> line >>>>>> with small thickness and round end caps, the end caps appear >>>> jagged. >>>>>> This is because the computation of the length of the array that >>>>>> contains the points on the "pen" with which the decoration is >>>> drawn >>>>>> does not take into account the size of the pen after the >>>> magnification >>>>>> of the affine transformation. So, for example, if the line length >>>> was >>>>>> set to 1, and the transformation was a scaling by 10, the >>>> resulting >>>>>> pen would have a diameter of 10, but only 3 pen points would be >>>>>> computed (pi*untransformedLineWidth), so the end cap looks like a >>>>>> triangle. >>>>>>>> My fix computes an approximation of the circumference of the >>>>>> transformed pen (which is an ellipse) and uses that as the number >>>> of >>>>>> points on the pen. The approximation is crude, but it is simple, >>>>>> faster than alternatives >>>>>> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can >>>> say >>>>>> from observations that it works fairly well. >>>>>>>> There is also icing on the cake, in the form of slight >>>> improvements >>>>>> in performance when the scaling is a zooming out. Example: if the >>>>>> original line width was 100, but g2d.scale(0.1,0.1) was set, then >>>> the >>>>>> resulting line would have a width of 10, so only ~31 points are >>>>>> necessary for the decoration to look like a circle, but without >>>> this >>>>>> patch, about 314 points are computed (and a line is emitted to >>>> each >>>>>> one of them). >>>>>>>> I appreciate any feedback. >>>>>>>> >>>>>>>> Regards, >>>>>>>> Denis Lila. >>>>>>>> From dlila at redhat.com Mon Jul 12 14:10:20 2010 From: dlila at redhat.com (Denis Lila) Date: Mon, 12 Jul 2010 10:10:20 -0400 (EDT) Subject: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines. In-Reply-To: <2030948107.57991278943729076.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <955936656.58131278943820862.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> The no argument constructor becoming private was not something I intended. It was left over from a change I made that didn't work out so well, and it escaped my mind to change it back when I sent the webrev. It's true that it's not used, and we could remove it, but it seems to me like the reason for it, setOutput, and setParameters being there is so that the same object can be used to render to more than one output, using input from different sources. The only benefit this has is saving the creation of some Stroker objects, which probably isn't a big deal, so I think we should remove this functionality from pisces. Then again, if we want to keep it, I think we should make Stroker, Dasher, and Renderer singletons, otherwise, it's hard to see how this functionality can be used properly. Making them singletons would also remove the requirement for client code to not use the object before setOutput and setParameters have been called, and we could make those two methods private (or remove them and move their bodies to a static factory). ----- "Jim Graham" wrote: > Also, the Stroker() constructor, which was marked private in these > webrevs, isn't used - it should probably just be deleted rather than > made private... > > ...jim > > Jim Graham wrote: > > Hi Denis, > > > > You moved some code around without modifying it. This makes it hard > to > > see what changed and what didn't and verify that the changes are > > accurate. Also, it adds diffs to the file that are unrelated to the > > > fixing of the bug. Was there a practical reason for why you moved > the > > code around? In particular I refer to: > > > > - the setup code that deals with "if (joinStyle == JOIN_MITER)" > > > > - the setOutput method - which not only moved, but lost its > javadocs > > > > - computeMiter() and drawMiter() > > > > All of that code "appears" to be unchanged at first glance, but it > is > > hard to tell from the webrevs. Also, a couple of stylistic issues: > > > > - you changed the declarations of isCCW which moved its arguments > over, > > but the continuation lines aren't indented to match > > > > - The two "flavors" of emitCurveTo() should probably be next to each > > > other (i.e. not have emitLineTo() between them or fall between the > two > > flavors of emitLineTo()). > > > > In general I think the changes are OK, but I'm still reviewing them > and > > the above issues sprung to mind on a first pass (and/or they are > > complicating the "contextual" review) so I thought I'd mention them > > > earlier than later... > > > > ...jim > > > > Denis Lila wrote: > >> Hello. > >> > >> I just noticed that approximation of circle arcs by bezier curves > >> had already been implemented in ArcIterator by Jim Graham. > >> It computes the same control points as my solution, but it does so > >> more straightforwardly, without any rotation, so it is faster and > >> clearer. I have updated my solution to include this. > >> > >> The link remains the same. > >> > >> Thanks, > >> Denis. > >> > >> ----- "Denis Lila" wrote: > >> > >>> Hello. > >>> > >>> I think I got this working. The webrev is at: > >>> > http://icedtea.classpath.org/~dlila/webrevs/bezierRoundJoins/webrev/ > >>> (NOTE: this is not a final version. I have included 2 versions > >>> of 2 methods. Only one set should be kept. See below for more.) > >>> > >>> My Changes: > >>> ----------- > >>> 1. > >>> I've made LineSink into an interface, rather than an abstract > >>> class, > >>> because all of its methods were abstract, so it makes more sense > this > >>> way. > >>> > >>> 2. > >>> I've introduced a new interface that extends LineSink called > >>> PathSink, > >>> which allows the curveTo method, so there have been no changes to > >>> Stroker's public interface. When someone wants to create a > Stroker > >>> with a PathSink output, it simply passes its constructor a > PathSink, > >>> so the only changes outside of Stroker are in > PiscesRenderingEngine, > >>> where the methods that handle Path2D and PathConsumer2D objects > >>> create nameless PathSinks instead of nameless LineSinks. > >>> > >>> 3. In Stroker: > >>> I've introduced a method called drawBezRoundJoin, analogous > to > >>> computeRoundJoin. In drawRoundJoin I detect whether the output is > >>> a PathSink. If it is, I call drawBezRoundJoin, otherwise > everything > >>> proceeds as it used to. drawBezRoundJoin uses computeBezierPoints > to > >>> compute the control points. computeBezierPoints computes the > control > >>> points > >>> for an arc of t radians, starting at angle a, with radius r > >>> by computing the control points of an arc of radius 1 of t > radians > >>> that > >>> starts at angle -t/2. This is done by solving the equations > resulting > >>> from the constraints that (P3-P2) and (P1-P0) must be parallel to > the > >>> arc's tangents at P3 and P0 respectively, and that B(1/2)=(1,0). > Then > >>> the > >>> points are scaled by r, and rotated counter clockwise by a+t/2. > >>> Then drawBezRoundJoin emits the curve. > >>> All this is done in a loop which is used to break up large > arcs > >>> into > >>> more than one bezier curve. Through the iterations, the computed > >>> control > >>> points don't change - the only thing that changes is how they're > >>> rotated. > >>> So a good alternative approach would be to do the rotation > outside > >>> of > >>> computeBezierPoints, and call computeBezierPoints once outside of > the > >>> loop, > >>> so that the control points aren't recomputed unnecessarily. > >>> I have included code for this in the methods computeBezierPoints2 > and > >>> drawBezRoundJoin2. This is my favoured approach, since it is > almost > >>> as clear as the other one, and it is faster. > >>> > >>> There is one more optimization that can be made, and I've > included > >>> it > >>> in a comment in line 703. > >>> > >>> I would very much appreciate any comments about any of this, > but > >>> especially > >>> about the idea in line 703 and about > >>> computeBezierPoints2,drawBezRoundJoin2 > >>> vs. computeBezierPoints,drawBezRoundJoin. > >>> > >>> 4. > >>> Stroker used to only have lines, but now it can emit lines > and > >>> curves, so > >>> I needed to change the format of reverse, to not only store > >>> coordinates, but > >>> to also tag them as belonging to a line or a curve. > >>> > >>> > >>> Other Approaches: > >>> ----------------- > >>> 1. > >>> Since what needed to be done was to alter the behaviour of > one > >>> part of Stroker (drawing of round joins/caps) depending on the > type > >>> of the output object, I thought it would be appropriate to make > >>> Stroker > >>> an abstract factory, turn the methods that draw round joins/caps > into > >>> abstract ones, put all the common functionality in concrete > methods > >>> in Stroker, and put all the join/cap drawing methods in > overriding > >>> methods > >>> in concrete children of Stroker (instances of which were returned > >>> by static factories in Stroker). > >>> However, this was a bad approach, because the round cap/join > >>> drawing > >>> methods are private, so the only way to call them in Stroker's > >>> children > >>> from public methods in Stroker is to cast "this". So the code > became > >>> littered with instanceof operators and casts. Not to mention that > >>> Stroker's > >>> public interface had to change, and some functionality was lost: > >>> Stroker > >>> allows changing it's output, so it is possible to use just 1 > Stroker > >>> object > >>> to widen paths going to many different outputs (but not at the > same > >>> time). > >>> This could no longer be supported with this approach. > >>> The way I did it has none of these weaknesses. > >>> > >>> 2. As for algorithms for the circle approximation, I considered > 2: > >>> a. Compute the control points using the constraints that > >>> B(1/3)=A(a+t/3) > >>> and B(2/3) = A(a+2t/3) (i.e. make the arc and the bezier curve > >>> coincide at 2 > >>> evenly spaced points in the arc). This didn't work very well: some > of > >>> the end > >>> caps looked more like triangles. > >>> b. Let B(1/2) = A(a+t/2), and B'(1/2) = A'(a+t/2). This > worked > >>> better, but > >>> still not good enough. > >>> > >>> If anyone knows of any better ways to compute the control points, > >>> please let > >>> me know. > >>> > >>> I'm sorry for the length of this. I tried to make it shorter. > >>> > >>> Thank you very much, > >>> Denis. > >>> > >>> > >>> ----- "Jim Graham" wrote: > >>> > >>>> Hi Denis, > >>>> > >>>> Consider the case of using BasicStroke.createStrokedShape(). How > do > >>>> you > >>>> know how many pixels the resulting path will occupy? You can't > >>> reduce > >>>> to concrete samples if you don't know the transform. > >>>> > >>>> So, for rendering, then you may be correct. But for cases where > the > >>>> path is being asked for then beziers are the only responsible > >>>> solution... > >>>> > >>>> ...jim > >>>> > >>>> Denis Lila wrote: > >>>>> Hello Jim. > >>>>> > >>>>> I thought about checking the output and changing the behaviour > >>>>> depending on whether the output is a PC2D or a LineSink, but I > >>>> didn't > >>>>> implement it because I thought the point was to get rid of the > >>>> sampling > >>>>> at this stage. However, if performance is the issue, then I > guess > >>>> I'll > >>>>> start working on it. > >>>>> > >>>>> Although, I wonder whether it is really worth it. I think most > >>> lines > >>>> drawn > >>>>> won't be wider than about 5 pixels, which means that the > current > >>> way > >>>> will > >>>>> emit about 7 lines, so that's 14 coordinates. 2 bezier quarter > >>>> circles will > >>>>> require 12 coordinates. In terms of storage, there isn't much > >>>> difference, and > >>>>> for lines of width 4 or smaller the current method is more > >>>> efficient. > >>>>> I'm also guessing that it's harder for the rasterizer to deal > with > >>>> bezier > >>>>> curves than with straight lines, so is it possible that > replacing > >>>> the > >>>>> 3.14*lineWidth/2 lines generated by the current method with 2 > >>> bezier > >>>>> quarter circles isn't worth it (for small lineWidths)? > >>>>> > >>>>> Thanks, > >>>>> Denis. > >>>>> > >>>>> ----- "Jim Graham" wrote: > >>>>> > >>>>>> Sigh - that makes sense. One issue is that the resulting > paths > >>> it > >>>>>> generates are much more "verbose" than they need to be. This > >>> would > >>>>>> generally mean that it takes far more storage than it would > >>>> otherwise > >>>>>> need - and it means that if the result needs to be transformed > >>> then > >>>> it > >>>>>> would take many more computations to transform each segment > than > >>>> the > >>>>>> bezier. > >>>>>> > >>>>>> So, perhaps it would be worth having it check the type of the > >>>> output > >>>>>> and > >>>>>> do either a bezier or a bunch of lines depending on if it is a > >>> PC2D > >>>> or > >>>>>> a > >>>>>> LineSink? > >>>>>> > >>>>>> Also, it isn't really that difficult to for Renderer to > include > >>>> its > >>>>>> own > >>>>>> Cubic/Quadratic flattening code, but it might involve more > >>>>>> calculations > >>>>>> than the round-cap code since it would have to be written for > >>>>>> arbitrary > >>>>>> beziers whereas if you know it is a quarter circle then it is > >>>> easier > >>>>>> to > >>>>>> know how far to subdivide... :-( > >>>>>> > >>>>>> ...jim > >>>>>> > >>>>>> Denis Lila wrote: > >>>>>>> So, I have been thinking about this, and I can't see a good > >>>>>>> way to do it that wouldn't involve heavy changes to Pisces. > >>>>>>> > >>>>>>> In order for Stroker to generate Bezier quarter circles, it > >>> would > >>>>>>> have to implement a curveTo method, which means Stroker > should > >>>>>>> start implementing PathConsumer2D and instead of using a > >>> LineSink > >>>>>>> output it would have to use a PathConsumer2D output (either > >>> that, > >>>>>> or > >>>>>>> LineSink should include a curveTo method, but then there > won't > >>>>>> really > >>>>>>> be any difference between a LineSink and a PathConsumer2D. By > >>> the > >>>>>> way, > >>>>>>> LineSink doesn't have any implemented methods, so why is it > an > >>>>>> abstract > >>>>>>> class as opposed to an interface?) > >>>>>>> > >>>>>>> Stroker is used in 3 ways: > >>>>>>> 1. As an implementation of BasicStroke's createStrokedShape > >>>> method. > >>>>>> This > >>>>>>> uses a Path2D object as output. > >>>>>>> 2. As a way of feeding a PathConsumer2D without calling > >>>>>> createStrokedShape > >>>>>>> to generate an intermediate Shape. This uses a PathConsumer2D > >>>>>> output. > >>>>>>> 3. As a way of feeding lines to a Renderer object, which > >>>> generates > >>>>>> alpha > >>>>>>> tiles used for anti-aliasing that are fed to a cache and > >>>> extracted > >>>>>> as needed > >>>>>>> by an AATileGenerator. Obviously, Stroker's output here is a > >>>>>> Renderer. > >>>>>>> 1 and 2 aren't problems, because the underlying output > objects > >>>>>> support > >>>>>>> Bezier curves. 3, however, doesn't, and it seems like > >>> implementing > >>>> a > >>>>>>> curveTo method for Renderer would be very difficult because > the > >>>> way > >>>>>> it > >>>>>>> generates alpha tiles is by scanning the drawn edges with > >>>>>> horizontal > >>>>>>> scan lines, and for each scan line finding the > x-intersections > >>> of > >>>>>> the scan > >>>>>>> lines and the edges. Then it determines the alpha values (I'm > >>> not > >>>>>> too sure > >>>>>>> how it does this). > >>>>>>> In order to implement Bezier curves in Renderer, we would > have > >>> to > >>>>>> have > >>>>>>> a quick way of computing, for each scan line, all its > >>>> intersections > >>>>>> with > >>>>>>> however many Bezier curves are being drawn. > >>>>>>> > >>>>>>> I haven't given much thought to how this could be done, as I > am > >>>> not > >>>>>> very > >>>>>>> familiar with Bezier curves, but it doesn't seem easy enough > to > >>>>>> justify > >>>>>>> fixing such a small bug. > >>>>>>> > >>>>>>> ----- Original Message ----- > >>>>>>> From: "Jim Graham" > >>>>>>> To: "Denis Lila" > >>>>>>> Cc: 2d-dev at openjdk.java.net > >>>>>>> Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada > >>>>>> Eastern > >>>>>>> Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps > on > >>>>>> scaled lines. > >>>>>>> I don't understand - why do we generate sample points based > on > >>>> the > >>>>>> size > >>>>>>> of the cap? Why not generate a pair of bezier > quarter-circles > >>>> and > >>>>>> let > >>>>>>> the rasterizer deal with sampling? > >>>>>>> > >>>>>>> ...jim > >>>>>>> > >>>>>>> Denis Lila wrote: > >>>>>>>> Hello. > >>>>>>>> > >>>>>>>> I think I have a fix for this bug: > >>>>>>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506 > >>>>>>>> > >>>>>>>> Basically, the problem is that if there is a magnifying > affine > >>>>>> transformation set on the graphics object and one tries to draw > a > >>>> line > >>>>>> with small thickness and round end caps, the end caps appear > >>>> jagged. > >>>>>> This is because the computation of the length of the array > that > >>>>>> contains the points on the "pen" with which the decoration is > >>>> drawn > >>>>>> does not take into account the size of the pen after the > >>>> magnification > >>>>>> of the affine transformation. So, for example, if the line > length > >>>> was > >>>>>> set to 1, and the transformation was a scaling by 10, the > >>>> resulting > >>>>>> pen would have a diameter of 10, but only 3 pen points would > be > >>>>>> computed (pi*untransformedLineWidth), so the end cap looks like > a > >>>>>> triangle. > >>>>>>>> My fix computes an approximation of the circumference of the > >>>>>> transformed pen (which is an ellipse) and uses that as the > number > >>>> of > >>>>>> points on the pen. The approximation is crude, but it is > simple, > >>>>>> faster than alternatives > >>>>>> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I > can > >>>> say > >>>>>> from observations that it works fairly well. > >>>>>>>> There is also icing on the cake, in the form of slight > >>>> improvements > >>>>>> in performance when the scaling is a zooming out. Example: if > the > >>>>>> original line width was 100, but g2d.scale(0.1,0.1) was set, > then > >>>> the > >>>>>> resulting line would have a width of 10, so only ~31 points > are > >>>>>> necessary for the decoration to look like a circle, but > without > >>>> this > >>>>>> patch, about 314 points are computed (and a line is emitted to > >>>> each > >>>>>> one of them). > >>>>>>>> I appreciate any feedback. > >>>>>>>> > >>>>>>>> Regards, > >>>>>>>> Denis Lila. > >>>>>>>> From dlila at redhat.com Mon Jul 12 14:22:02 2010 From: dlila at redhat.com (Denis Lila) Date: Mon, 12 Jul 2010 10:22:02 -0400 (EDT) Subject: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines. In-Reply-To: <1855476123.59931278944384085.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <1076160120.60311278944522065.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hello Jim. I'm terribly sorry about that. I fixed it. Now the only highlighted lines in the webrev should be lines I actually changed. Please take another look at it. (link is still the same: http://icedtea.classpath.org/~dlila/webrevs/bezierRoundJoins/webrev/) Thanks, Denis. PS: I added a new method: emitReverse, that goes through the reverse list and emits it. It's used in 2 methods which used to just do it themselves. ----- "Jim Graham" wrote: > Hi Denis, > > You moved some code around without modifying it. This makes it hard > to > see what changed and what didn't and verify that the changes are > accurate. Also, it adds diffs to the file that are unrelated to the > fixing of the bug. Was there a practical reason for why you moved the > > code around? In particular I refer to: > > - the setup code that deals with "if (joinStyle == JOIN_MITER)" > > - the setOutput method - which not only moved, but lost its javadocs > > - computeMiter() and drawMiter() > > All of that code "appears" to be unchanged at first glance, but it is > > hard to tell from the webrevs. Also, a couple of stylistic issues: > > - you changed the declarations of isCCW which moved its arguments > over, > but the continuation lines aren't indented to match > > - The two "flavors" of emitCurveTo() should probably be next to each > other (i.e. not have emitLineTo() between them or fall between the two > > flavors of emitLineTo()). > > In general I think the changes are OK, but I'm still reviewing them > and > the above issues sprung to mind on a first pass (and/or they are > complicating the "contextual" review) so I thought I'd mention them > earlier than later... > > ...jim > > Denis Lila wrote: > > Hello. > > > > I just noticed that approximation of circle arcs by bezier curves > > had already been implemented in ArcIterator by Jim Graham. > > > > It computes the same control points as my solution, but it does so > > more straightforwardly, without any rotation, so it is faster and > > clearer. I have updated my solution to include this. > > > > The link remains the same. > > > > Thanks, > > Denis. > > > > ----- "Denis Lila" wrote: > > > >> Hello. > >> > >> I think I got this working. The webrev is at: > >> > http://icedtea.classpath.org/~dlila/webrevs/bezierRoundJoins/webrev/ > >> (NOTE: this is not a final version. I have included 2 versions > >> of 2 methods. Only one set should be kept. See below for more.) > >> > >> My Changes: > >> ----------- > >> 1. > >> I've made LineSink into an interface, rather than an abstract > >> class, > >> because all of its methods were abstract, so it makes more sense > this > >> way. > >> > >> 2. > >> I've introduced a new interface that extends LineSink called > >> PathSink, > >> which allows the curveTo method, so there have been no changes to > >> Stroker's public interface. When someone wants to create a Stroker > >> with a PathSink output, it simply passes its constructor a > PathSink, > >> so the only changes outside of Stroker are in > PiscesRenderingEngine, > >> where the methods that handle Path2D and PathConsumer2D objects > >> create nameless PathSinks instead of nameless LineSinks. > >> > >> 3. In Stroker: > >> I've introduced a method called drawBezRoundJoin, analogous to > >> computeRoundJoin. In drawRoundJoin I detect whether the output is > >> a PathSink. If it is, I call drawBezRoundJoin, otherwise > everything > >> proceeds as it used to. drawBezRoundJoin uses computeBezierPoints > to > >> compute the control points. computeBezierPoints computes the > control > >> points > >> for an arc of t radians, starting at angle a, with radius r > >> by computing the control points of an arc of radius 1 of t radians > >> that > >> starts at angle -t/2. This is done by solving the equations > resulting > >> from the constraints that (P3-P2) and (P1-P0) must be parallel to > the > >> arc's tangents at P3 and P0 respectively, and that B(1/2)=(1,0). > Then > >> the > >> points are scaled by r, and rotated counter clockwise by a+t/2. > >> Then drawBezRoundJoin emits the curve. > >> All this is done in a loop which is used to break up large > arcs > >> into > >> more than one bezier curve. Through the iterations, the computed > >> control > >> points don't change - the only thing that changes is how they're > >> rotated. > >> So a good alternative approach would be to do the rotation > outside > >> of > >> computeBezierPoints, and call computeBezierPoints once outside of > the > >> loop, > >> so that the control points aren't recomputed unnecessarily. > >> I have included code for this in the methods computeBezierPoints2 > and > >> drawBezRoundJoin2. This is my favoured approach, since it is > almost > >> as clear as the other one, and it is faster. > >> > >> There is one more optimization that can be made, and I've > included > >> it > >> in a comment in line 703. > >> > >> I would very much appreciate any comments about any of this, > but > >> especially > >> about the idea in line 703 and about > >> computeBezierPoints2,drawBezRoundJoin2 > >> vs. computeBezierPoints,drawBezRoundJoin. > >> > >> 4. > >> Stroker used to only have lines, but now it can emit lines and > >> curves, so > >> I needed to change the format of reverse, to not only store > >> coordinates, but > >> to also tag them as belonging to a line or a curve. > >> > >> > >> Other Approaches: > >> ----------------- > >> 1. > >> Since what needed to be done was to alter the behaviour of one > >> part of Stroker (drawing of round joins/caps) depending on the > type > >> of the output object, I thought it would be appropriate to make > >> Stroker > >> an abstract factory, turn the methods that draw round joins/caps > into > >> abstract ones, put all the common functionality in concrete > methods > >> in Stroker, and put all the join/cap drawing methods in overriding > >> methods > >> in concrete children of Stroker (instances of which were returned > >> by static factories in Stroker). > >> However, this was a bad approach, because the round cap/join > >> drawing > >> methods are private, so the only way to call them in Stroker's > >> children > >> from public methods in Stroker is to cast "this". So the code > became > >> littered with instanceof operators and casts. Not to mention that > >> Stroker's > >> public interface had to change, and some functionality was lost: > >> Stroker > >> allows changing it's output, so it is possible to use just 1 > Stroker > >> object > >> to widen paths going to many different outputs (but not at the > same > >> time). > >> This could no longer be supported with this approach. > >> The way I did it has none of these weaknesses. > >> > >> 2. As for algorithms for the circle approximation, I considered 2: > >> a. Compute the control points using the constraints that > >> B(1/3)=A(a+t/3) > >> and B(2/3) = A(a+2t/3) (i.e. make the arc and the bezier curve > >> coincide at 2 > >> evenly spaced points in the arc). This didn't work very well: some > of > >> the end > >> caps looked more like triangles. > >> b. Let B(1/2) = A(a+t/2), and B'(1/2) = A'(a+t/2). This worked > >> better, but > >> still not good enough. > >> > >> If anyone knows of any better ways to compute the control points, > >> please let > >> me know. > >> > >> I'm sorry for the length of this. I tried to make it shorter. > >> > >> Thank you very much, > >> Denis. > >> > >> > >> ----- "Jim Graham" wrote: > >> > >>> Hi Denis, > >>> > >>> Consider the case of using BasicStroke.createStrokedShape(). How > do > >>> you > >>> know how many pixels the resulting path will occupy? You can't > >> reduce > >>> to concrete samples if you don't know the transform. > >>> > >>> So, for rendering, then you may be correct. But for cases where > the > >>> path is being asked for then beziers are the only responsible > >>> solution... > >>> > >>> ...jim > >>> > >>> Denis Lila wrote: > >>>> Hello Jim. > >>>> > >>>> I thought about checking the output and changing the behaviour > >>>> depending on whether the output is a PC2D or a LineSink, but I > >>> didn't > >>>> implement it because I thought the point was to get rid of the > >>> sampling > >>>> at this stage. However, if performance is the issue, then I > guess > >>> I'll > >>>> start working on it. > >>>> > >>>> Although, I wonder whether it is really worth it. I think most > >> lines > >>> drawn > >>>> won't be wider than about 5 pixels, which means that the current > >> way > >>> will > >>>> emit about 7 lines, so that's 14 coordinates. 2 bezier quarter > >>> circles will > >>>> require 12 coordinates. In terms of storage, there isn't much > >>> difference, and > >>>> for lines of width 4 or smaller the current method is more > >>> efficient. > >>>> I'm also guessing that it's harder for the rasterizer to deal > with > >>> bezier > >>>> curves than with straight lines, so is it possible that > replacing > >>> the > >>>> 3.14*lineWidth/2 lines generated by the current method with 2 > >> bezier > >>>> quarter circles isn't worth it (for small lineWidths)? > >>>> > >>>> Thanks, > >>>> Denis. > >>>> > >>>> ----- "Jim Graham" wrote: > >>>> > >>>>> Sigh - that makes sense. One issue is that the resulting paths > >> it > >>>>> generates are much more "verbose" than they need to be. This > >> would > >>>>> generally mean that it takes far more storage than it would > >>> otherwise > >>>>> need - and it means that if the result needs to be transformed > >> then > >>> it > >>>>> would take many more computations to transform each segment > than > >>> the > >>>>> bezier. > >>>>> > >>>>> So, perhaps it would be worth having it check the type of the > >>> output > >>>>> and > >>>>> do either a bezier or a bunch of lines depending on if it is a > >> PC2D > >>> or > >>>>> a > >>>>> LineSink? > >>>>> > >>>>> Also, it isn't really that difficult to for Renderer to include > >>> its > >>>>> own > >>>>> Cubic/Quadratic flattening code, but it might involve more > >>>>> calculations > >>>>> than the round-cap code since it would have to be written for > >>>>> arbitrary > >>>>> beziers whereas if you know it is a quarter circle then it is > >>> easier > >>>>> to > >>>>> know how far to subdivide... :-( > >>>>> > >>>>> ...jim > >>>>> > >>>>> Denis Lila wrote: > >>>>>> So, I have been thinking about this, and I can't see a good > >>>>>> way to do it that wouldn't involve heavy changes to Pisces. > >>>>>> > >>>>>> In order for Stroker to generate Bezier quarter circles, it > >> would > >>>>>> have to implement a curveTo method, which means Stroker should > >>>>>> start implementing PathConsumer2D and instead of using a > >> LineSink > >>>>>> output it would have to use a PathConsumer2D output (either > >> that, > >>>>> or > >>>>>> LineSink should include a curveTo method, but then there won't > >>>>> really > >>>>>> be any difference between a LineSink and a PathConsumer2D. By > >> the > >>>>> way, > >>>>>> LineSink doesn't have any implemented methods, so why is it an > >>>>> abstract > >>>>>> class as opposed to an interface?) > >>>>>> > >>>>>> Stroker is used in 3 ways: > >>>>>> 1. As an implementation of BasicStroke's createStrokedShape > >>> method. > >>>>> This > >>>>>> uses a Path2D object as output. > >>>>>> 2. As a way of feeding a PathConsumer2D without calling > >>>>> createStrokedShape > >>>>>> to generate an intermediate Shape. This uses a PathConsumer2D > >>>>> output. > >>>>>> 3. As a way of feeding lines to a Renderer object, which > >>> generates > >>>>> alpha > >>>>>> tiles used for anti-aliasing that are fed to a cache and > >>> extracted > >>>>> as needed > >>>>>> by an AATileGenerator. Obviously, Stroker's output here is a > >>>>> Renderer. > >>>>>> 1 and 2 aren't problems, because the underlying output objects > >>>>> support > >>>>>> Bezier curves. 3, however, doesn't, and it seems like > >> implementing > >>> a > >>>>>> curveTo method for Renderer would be very difficult because > the > >>> way > >>>>> it > >>>>>> generates alpha tiles is by scanning the drawn edges with > >>>>> horizontal > >>>>>> scan lines, and for each scan line finding the x-intersections > >> of > >>>>> the scan > >>>>>> lines and the edges. Then it determines the alpha values (I'm > >> not > >>>>> too sure > >>>>>> how it does this). > >>>>>> In order to implement Bezier curves in Renderer, we would have > >> to > >>>>> have > >>>>>> a quick way of computing, for each scan line, all its > >>> intersections > >>>>> with > >>>>>> however many Bezier curves are being drawn. > >>>>>> > >>>>>> I haven't given much thought to how this could be done, as I > am > >>> not > >>>>> very > >>>>>> familiar with Bezier curves, but it doesn't seem easy enough > to > >>>>> justify > >>>>>> fixing such a small bug. > >>>>>> > >>>>>> ----- Original Message ----- > >>>>>> From: "Jim Graham" > >>>>>> To: "Denis Lila" > >>>>>> Cc: 2d-dev at openjdk.java.net > >>>>>> Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada > >>>>> Eastern > >>>>>> Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on > >>>>> scaled lines. > >>>>>> I don't understand - why do we generate sample points based on > >>> the > >>>>> size > >>>>>> of the cap? Why not generate a pair of bezier quarter-circles > >>> and > >>>>> let > >>>>>> the rasterizer deal with sampling? > >>>>>> > >>>>>> ...jim > >>>>>> > >>>>>> Denis Lila wrote: > >>>>>>> Hello. > >>>>>>> > >>>>>>> I think I have a fix for this bug: > >>>>>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506 > >>>>>>> > >>>>>>> Basically, the problem is that if there is a magnifying > affine > >>>>> transformation set on the graphics object and one tries to draw > a > >>> line > >>>>> with small thickness and round end caps, the end caps appear > >>> jagged. > >>>>> This is because the computation of the length of the array that > >>>>> contains the points on the "pen" with which the decoration is > >>> drawn > >>>>> does not take into account the size of the pen after the > >>> magnification > >>>>> of the affine transformation. So, for example, if the line > length > >>> was > >>>>> set to 1, and the transformation was a scaling by 10, the > >>> resulting > >>>>> pen would have a diameter of 10, but only 3 pen points would be > >>>>> computed (pi*untransformedLineWidth), so the end cap looks like > a > >>>>> triangle. > >>>>>>> My fix computes an approximation of the circumference of the > >>>>> transformed pen (which is an ellipse) and uses that as the > number > >>> of > >>>>> points on the pen. The approximation is crude, but it is > simple, > >>>>> faster than alternatives > >>>>> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can > >>> say > >>>>> from observations that it works fairly well. > >>>>>>> There is also icing on the cake, in the form of slight > >>> improvements > >>>>> in performance when the scaling is a zooming out. Example: if > the > >>>>> original line width was 100, but g2d.scale(0.1,0.1) was set, > then > >>> the > >>>>> resulting line would have a width of 10, so only ~31 points are > >>>>> necessary for the decoration to look like a circle, but without > >>> this > >>>>> patch, about 314 points are computed (and a line is emitted to > >>> each > >>>>> one of them). > >>>>>>> I appreciate any feedback. > >>>>>>> > >>>>>>> Regards, > >>>>>>> Denis Lila. > >>>>>>> From dlila at redhat.com Mon Jul 12 14:50:25 2010 From: dlila at redhat.com (Denis Lila) Date: Mon, 12 Jul 2010 10:50:25 -0400 (EDT) Subject: [OpenJDK 2D-Dev] X11 uniform scaled wide lines and dashed lines; STROKE_CONTROL in Pisces In-Reply-To: <1187284237.65731278946120849.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <1524388037.66741278946225991.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hello Jim. I think the second way would be better because there would be no repeated code, and it would be easier to implement. Do you think there will be any performance benefit from the first way? Regards, Denis. ----- "Jim Graham" wrote: > Hi Denis, > > It would be ill-advised to normalize the coordinates after flattening. > > The quality would be really bad. > > Perhaps this is a good reason to start looking at updating Pisces to > take curves and flatten at the lowest level? > > Or, I suppose we could get a non-flattened iterator from the source > path, send it through a "normalizing" filter, and then through a > flattening filter (the way many of the existing objects do flattening > is > to just get their regular iterator and run it through an instance of > FlatteningPathIterator so we could do this manually with an > intervening > "NormalizingPathIterator" if normalization is needed)... > > ...jim > > Denis Lila wrote: > > Hello Jim. > > > > Thanks for that. I'll get to work on implementing it. > > > > One thing though, about normalizing the control points of bezier > > curves: pisces never gets any bezier curves as input. It only gets > > lines that are the product of flattening bezier curves. > > > > Pisces receives its input from flattening path iterators which get > it > > from other path iterators. Of course we can't require these to send > out > > normalized points. In order to normalize the control points we need > to > > be able to look at the bezier curves in Pisces, so we can't just > take > > all the input from the flattener. However, pisces can't handle > curves > > (yet, hopefully), so after the normalization, they must be > flattened, and > > this is the problem. I think it's a pretty good idea to do this by > > storing the input form the iterator into pisces (after > normalization), > > creating a nameless path iterator that just iterates through all > that, > > and using this iterator to create a flattening iterator, which then > > is used as before. > > > > Does anyone have any other ideas? > > > > Thank you, > > Denis. > > > > > > ----- "Jim Graham" wrote: > > > >> For AA this is exactly what we do (round to nearest pixel centers > for > >> > >> strokes). Note that this is done prior to any line widening code > is > >> executed. > >> > >> For non-AA we normalize coordinates to, I believe the (0.25, 0.25) > > >> sub-pixel location. This is so that the transitions between > widening > >> of > >> lines occurs evenly (particularly for horizontal and vertical wide > > >> lines). If you round to pixel edges then you have the following > >> progression (note that the line width grows by half on either side > of > >> > >> the original geometry so you have to consider the "line widths" > where > >> > >> you encounter the pixel centers to your left and right (or above > and > >> below) which govern when that column (or row) of pixels first > turns > >> on): > >> > >> width 0.00 => 0.99 nothing drawn (except we kludge this) > >> width 1.00 => 1.00 1 pixel wide (col to left turns on) > >> width 1.01 => 2.99 2 pixels wide (col to right turns on) > >> width 3.00 => 3.00 3 pixels wide (etc.) > >> width 3.01 => 4.99 4 pixels wide > >> > >> Note that it is nearly impossible to get an odd-width line. You > >> basically have to have exactly an integer width to get an odd-width > > >> line. This is because at the odd widths you reach the "half pixel" > > >> locations on both sides of the line at the same time. Due to the > >> "half-open" insideness rules only one of the pixels will be chosen > to > >> be > >> inside this path. Just below these sizes and you fail to hit > either > >> pixel center. Just at the integer size you reach both pixel > centers > >> at > >> the same time. Just slightly larger than that width and now you've > > >> fully enclosed both pixel centers and the line width has to > increase > >> by > >> nearly 2.0 until you reach the next pixel centers. > >> > >> (The kludge I talk about above is that we set a minimum pen width > so > >> that we never fail to draw a line even if the line width is set to > >> 0.0, > >> but the above table was a theoretical description of the absolute > >> rules.) > >> > >> If we rounded them to pixel centers, then the transitions look > like > >> this: > >> > >> width 0.00 => 0.00 nothing drawn (modulo kludge) > >> width 0.01 => 1.99 1 pixel wide (column you are in turns on) > >> width 2.00 => 2.00 2 pixels wide (column to left turns on) > >> width 2.01 => 3.99 3 pixels wide (column to right turns on) > >> width 4.00 => 4.00 4 pixels wide (etc.) > >> width 4.01 => 5.99 5 pixels wide > >> > >> We have a similar effect as above, but biased towards making even > line > >> > >> widths harder. > >> > >> So, by locating lines at (0.25, 0.25) subpixel location we end up > with > >> a > >> very even progression: > >> > >> width 0.00 => 0.50 nothing drawn (modulo kludge) > >> width 0.51 => 1.50 1 pixel wide (column you are in turns on) > >> width 1.51 => 2.50 2 pixel wide (column to left gets added) > >> width 2.51 => 3.50 3 pixel wide (column to right gets added) > >> width 3.51 => 4.50 4 pixel wide (etc.) > >> > >> This gives us nice even and gradual widening of the lines as we > >> increase > >> the line width by sub-pixel amounts and the line widths are fairly > > >> stable around integer widths. > >> > >> Also, note that we don't say "when stroking" as you might want to > >> normalize both strokes and fills so that they continue to match. I > > >> believe that we normalize both strokes and fills for non-AA and we > >> only > >> normalize strokes for AA (and leave AA fills as "pure"). AA is > less > >> problematic with respect to creating gaps if your stroke and fill > >> normalization are not consistent. > >> > >> The rounding equations are along the lines of: > >> > >> v = Math.floor(v + rval) + aval; > >> > >> For center of pixel you use (rval=0.0, aval=0.5) > >> For 0.25,0.25 rounding use (rval=0.25, aval=0.25) > >> For edge of pixel you use (rval=0.5, aval=0.0) > >> > >> Also, we came up with an interesting way of adjusting the control > >> points > >> of quads and cubics if we adjusted their end points, but I don't > know > >> if > >> what we did was really the best idea. For quads we adjust the > control > >> > >> point by the average of the adjustments that we applied to its 2 > end > >> points. For cubics, we move the first control point by the same > >> amount > >> as we moved the starting endpoint and the second control point by > the > >> > >> amount we moved the final endpoint. The jury is out on whether > that > >> is > >> the most aesthetic technique... > >> > >> ...jim > >> > >> Denis Lila wrote: > >>> Regarding VALUE_STROKE_NORMALIZE the API says: > >>> Stroke normalization control hint value -- > geometry > >> should > >>> be normalized to improve uniformity or spacing of > >> lines and > >>> overall aesthetics. Note that different > >> normalization > >>> algorithms may be more successful than others for > >> given > >>> input paths. > >>> > >>> I can only think of one example where VALUE_STROKE_NORMALIZE makes > a > >> visible > >>> difference between the closed source implementation and OpenJDK: > >>> when drawing anti-aliased horizontal or vertical lines of width > 1, > >> Pisces > >>> draws a 2 pixel wide line with half intensity (because integer > >> coordinates > >>> are between pixels). Sun's jdk with VALUE_SROKE_NORMALIZE turned > on > >> draws > >>> a 1 pixel line with full intensity. This could to achieved by > just > >>> checking for normalization and rounding coordinates to the > nearest > >> half > >>> pixel, but this solution seems too simple, and I'm not sure > whether > >> I'm missing > >>> anything. It would also probably cause problems when drawing > >> anti-aliased > >>> short lines (which is done when drawing any sort of curve) > >>> Unless, of course, this rounding was restricted to just > horizontal > >> and > >>> vertical lines. > >>> > >>> Regards, > >>> Denis. From dlila at redhat.com Mon Jul 12 15:05:00 2010 From: dlila at redhat.com (Denis Lila) Date: Mon, 12 Jul 2010 11:05:00 -0400 (EDT) Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <456008296.69901278947010789.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <463962734.70481278947100641.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hello. Is it ok if I do this? I already started working on it on Friday. I think I should be done by tomorrow. But yes, I agree that we should convert to floating point. As for performance, there's also the fact that right now we're trading one double multiplication for 2 casts to long, 1 long multiplication, 1 bit shift of a long, and 1 cast back to an int. I don't know much about how these are done in hardware, but it doesn't seem like they'd be faster than the double multiplication. As for large coordinates, there's a bug report about it (one not reported by me :) ) here: https://bugzilla.redhat.com/show_bug.cgi?id=597227 I submitted a matching bug report on bugs.sun.com (ID 6967436), but I can't find it when I search for it. Denis. ----- "Jim Graham" wrote: > Sigh... > > Pisces could really stand to upgrade to floats/doubles everywhere, for > > several reasons: > > - FPU ops are likely as fast if not faster on modern hardware due to > parallel execution of FP instructions alongside regular instructions. > > - Don't have to worry about getting coordinates larger than 32K (I > don't > think this is well tested, but I imagine that Pisces will not deal > with > it very gracefully). > > - Lots of code is greatly simplified not having to deal with the > semantics of how to do fixed point multiplies, divides, and > conversions. > > I meant to do this during the original integration, but I wanted to > get > the task done as quickly as possible so that we could have an open > source alternative to the closed Ductus code so I left that task for a > > later update. But, now that a lot of work is being done on the code > to > fix it up, it might be better to do the float conversion now so that > the > maintenance is easier and before we end up creating a lot of new fixed > > point code. > > My plate is full right now, but hopefully I can interest someone else > in > doing a cleanup cycle? (Donning my Tom Sawyer hat... ;-) > > ...jim From igor.nekrestyanov at sun.com Mon Jul 12 20:18:54 2010 From: igor.nekrestyanov at sun.com (igor.nekrestyanov at sun.com) Date: Mon, 12 Jul 2010 20:18:54 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/jdk: 6959998: Return of SurfaceData_InitOps point not checked in all cases (parfait found these) Message-ID: <20100712201930.77DF147931@hg.openjdk.java.net> Changeset: e03065fc64e7 Author: igor Date: 2010-07-12 13:16 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/e03065fc64e7 6959998: Return of SurfaceData_InitOps point not checked in all cases (parfait found these) Reviewed-by: prr Contributed-by: ohair ! src/share/native/sun/awt/image/BufImgSurfaceData.c ! src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c ! src/solaris/native/sun/java2d/x11/X11SurfaceData.c ! src/windows/native/sun/java2d/opengl/WGLSurfaceData.c ! src/windows/native/sun/java2d/windows/GDIWindowSurfaceData.cpp From igor.nekrestyanov at sun.com Mon Jul 12 22:11:52 2010 From: igor.nekrestyanov at sun.com (igor.nekrestyanov at sun.com) Date: Mon, 12 Jul 2010 22:11:52 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/jdk: 6968373: FontUtilities static initializer throws AccessControlException Message-ID: <20100712221212.9479847935@hg.openjdk.java.net> Changeset: 2ad69cb576b4 Author: igor Date: 2010-07-12 15:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/2ad69cb576b4 6968373: FontUtilities static initializer throws AccessControlException Reviewed-by: prr ! src/share/classes/sun/font/FontUtilities.java ! test/java/awt/FontClass/FontPrivilege.java From james.graham at oracle.com Tue Jul 13 19:25:57 2010 From: james.graham at oracle.com (Jim Graham) Date: Tue, 13 Jul 2010 12:25:57 -0700 Subject: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines. In-Reply-To: <955936656.58131278943820862.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <955936656.58131278943820862.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C3CBDC5.5030006@oracle.com> Hi Denis, It's been a while since I looked at this specific code, but I believe there may be problems with making them singletons in that we allow rendering from multiple threads and so making the code that uses these facilities single-threaded would be a big issue. If they are expensive to create we could implement synchronized access to a "cache of one" which would take care of 99% of the cases where there really is only one thread running. The way this would work is: public static synchronized Foo getFoo() { Foo f = fooinstance if (f == null) { return new Foo(); } fooinstance = null; return f; } And an associated synchronized method to return a Foo back to the static variable. But, really this is overkill unless we find that these objects are causing serious construction issues. Given how much of their data would need to be updated on each construction, I'm guessing that the actual constructor is in the noise... ...jim On 7/12/2010 7:10 AM, Denis Lila wrote: > The no argument constructor becoming private was not something I > intended. It was left over from a change I made that didn't work out > so well, and it escaped my mind to change it back when I sent the webrev. > > It's true that it's not used, and we could remove it, but it seems to > me like the reason for it, setOutput, and setParameters being there is > so that the same object can be used to render to more than one output, > using input from different sources. > > The only benefit this has is saving the creation of some Stroker objects, > which probably isn't a big deal, so I think we should remove this functionality > from pisces. > > Then again, if we want to keep it, I think we should make Stroker, Dasher, > and Renderer singletons, otherwise, it's hard to see how this functionality > can be used properly. Making them singletons would also remove the requirement > for client code to not use the object before setOutput and setParameters have > been called, and we could make those two methods private (or remove them and > move their bodies to a static factory). > > ----- "Jim Graham" wrote: > >> Also, the Stroker() constructor, which was marked private in these >> webrevs, isn't used - it should probably just be deleted rather than >> made private... >> >> ...jim >> >> Jim Graham wrote: >>> Hi Denis, >>> >>> You moved some code around without modifying it. This makes it hard >> to >>> see what changed and what didn't and verify that the changes are >>> accurate. Also, it adds diffs to the file that are unrelated to the >> >>> fixing of the bug. Was there a practical reason for why you moved >> the >>> code around? In particular I refer to: >>> >>> - the setup code that deals with "if (joinStyle == JOIN_MITER)" >>> >>> - the setOutput method - which not only moved, but lost its >> javadocs >>> >>> - computeMiter() and drawMiter() >>> >>> All of that code "appears" to be unchanged at first glance, but it >> is >>> hard to tell from the webrevs. Also, a couple of stylistic issues: >>> >>> - you changed the declarations of isCCW which moved its arguments >> over, >>> but the continuation lines aren't indented to match >>> >>> - The two "flavors" of emitCurveTo() should probably be next to each >> >>> other (i.e. not have emitLineTo() between them or fall between the >> two >>> flavors of emitLineTo()). >>> >>> In general I think the changes are OK, but I'm still reviewing them >> and >>> the above issues sprung to mind on a first pass (and/or they are >>> complicating the "contextual" review) so I thought I'd mention them >> >>> earlier than later... >>> >>> ...jim >>> >>> Denis Lila wrote: >>>> Hello. >>>> >>>> I just noticed that approximation of circle arcs by bezier curves >>>> had already been implemented in ArcIterator by Jim Graham. >>>> It computes the same control points as my solution, but it does so >>>> more straightforwardly, without any rotation, so it is faster and >>>> clearer. I have updated my solution to include this. >>>> >>>> The link remains the same. >>>> >>>> Thanks, >>>> Denis. >>>> >>>> ----- "Denis Lila" wrote: >>>> >>>>> Hello. >>>>> >>>>> I think I got this working. The webrev is at: >>>>> >> http://icedtea.classpath.org/~dlila/webrevs/bezierRoundJoins/webrev/ >>>>> (NOTE: this is not a final version. I have included 2 versions >>>>> of 2 methods. Only one set should be kept. See below for more.) >>>>> >>>>> My Changes: >>>>> ----------- >>>>> 1. >>>>> I've made LineSink into an interface, rather than an abstract >>>>> class, >>>>> because all of its methods were abstract, so it makes more sense >> this >>>>> way. >>>>> >>>>> 2. >>>>> I've introduced a new interface that extends LineSink called >>>>> PathSink, >>>>> which allows the curveTo method, so there have been no changes to >>>>> Stroker's public interface. When someone wants to create a >> Stroker >>>>> with a PathSink output, it simply passes its constructor a >> PathSink, >>>>> so the only changes outside of Stroker are in >> PiscesRenderingEngine, >>>>> where the methods that handle Path2D and PathConsumer2D objects >>>>> create nameless PathSinks instead of nameless LineSinks. >>>>> >>>>> 3. In Stroker: >>>>> I've introduced a method called drawBezRoundJoin, analogous >> to >>>>> computeRoundJoin. In drawRoundJoin I detect whether the output is >>>>> a PathSink. If it is, I call drawBezRoundJoin, otherwise >> everything >>>>> proceeds as it used to. drawBezRoundJoin uses computeBezierPoints >> to >>>>> compute the control points. computeBezierPoints computes the >> control >>>>> points >>>>> for an arc of t radians, starting at angle a, with radius r >>>>> by computing the control points of an arc of radius 1 of t >> radians >>>>> that >>>>> starts at angle -t/2. This is done by solving the equations >> resulting >>>>> from the constraints that (P3-P2) and (P1-P0) must be parallel to >> the >>>>> arc's tangents at P3 and P0 respectively, and that B(1/2)=(1,0). >> Then >>>>> the >>>>> points are scaled by r, and rotated counter clockwise by a+t/2. >>>>> Then drawBezRoundJoin emits the curve. >>>>> All this is done in a loop which is used to break up large >> arcs >>>>> into >>>>> more than one bezier curve. Through the iterations, the computed >>>>> control >>>>> points don't change - the only thing that changes is how they're >>>>> rotated. >>>>> So a good alternative approach would be to do the rotation >> outside >>>>> of >>>>> computeBezierPoints, and call computeBezierPoints once outside of >> the >>>>> loop, >>>>> so that the control points aren't recomputed unnecessarily. >>>>> I have included code for this in the methods computeBezierPoints2 >> and >>>>> drawBezRoundJoin2. This is my favoured approach, since it is >> almost >>>>> as clear as the other one, and it is faster. >>>>> >>>>> There is one more optimization that can be made, and I've >> included >>>>> it >>>>> in a comment in line 703. >>>>> >>>>> I would very much appreciate any comments about any of this, >> but >>>>> especially >>>>> about the idea in line 703 and about >>>>> computeBezierPoints2,drawBezRoundJoin2 >>>>> vs. computeBezierPoints,drawBezRoundJoin. >>>>> >>>>> 4. >>>>> Stroker used to only have lines, but now it can emit lines >> and >>>>> curves, so >>>>> I needed to change the format of reverse, to not only store >>>>> coordinates, but >>>>> to also tag them as belonging to a line or a curve. >>>>> >>>>> >>>>> Other Approaches: >>>>> ----------------- >>>>> 1. >>>>> Since what needed to be done was to alter the behaviour of >> one >>>>> part of Stroker (drawing of round joins/caps) depending on the >> type >>>>> of the output object, I thought it would be appropriate to make >>>>> Stroker >>>>> an abstract factory, turn the methods that draw round joins/caps >> into >>>>> abstract ones, put all the common functionality in concrete >> methods >>>>> in Stroker, and put all the join/cap drawing methods in >> overriding >>>>> methods >>>>> in concrete children of Stroker (instances of which were returned >>>>> by static factories in Stroker). >>>>> However, this was a bad approach, because the round cap/join >>>>> drawing >>>>> methods are private, so the only way to call them in Stroker's >>>>> children >>>>> from public methods in Stroker is to cast "this". So the code >> became >>>>> littered with instanceof operators and casts. Not to mention that >>>>> Stroker's >>>>> public interface had to change, and some functionality was lost: >>>>> Stroker >>>>> allows changing it's output, so it is possible to use just 1 >> Stroker >>>>> object >>>>> to widen paths going to many different outputs (but not at the >> same >>>>> time). >>>>> This could no longer be supported with this approach. >>>>> The way I did it has none of these weaknesses. >>>>> >>>>> 2. As for algorithms for the circle approximation, I considered >> 2: >>>>> a. Compute the control points using the constraints that >>>>> B(1/3)=A(a+t/3) >>>>> and B(2/3) = A(a+2t/3) (i.e. make the arc and the bezier curve >>>>> coincide at 2 >>>>> evenly spaced points in the arc). This didn't work very well: some >> of >>>>> the end >>>>> caps looked more like triangles. >>>>> b. Let B(1/2) = A(a+t/2), and B'(1/2) = A'(a+t/2). This >> worked >>>>> better, but >>>>> still not good enough. >>>>> >>>>> If anyone knows of any better ways to compute the control points, >>>>> please let >>>>> me know. >>>>> >>>>> I'm sorry for the length of this. I tried to make it shorter. >>>>> >>>>> Thank you very much, >>>>> Denis. >>>>> >>>>> >>>>> ----- "Jim Graham" wrote: >>>>> >>>>>> Hi Denis, >>>>>> >>>>>> Consider the case of using BasicStroke.createStrokedShape(). How >> do >>>>>> you >>>>>> know how many pixels the resulting path will occupy? You can't >>>>> reduce >>>>>> to concrete samples if you don't know the transform. >>>>>> >>>>>> So, for rendering, then you may be correct. But for cases where >> the >>>>>> path is being asked for then beziers are the only responsible >>>>>> solution... >>>>>> >>>>>> ...jim >>>>>> >>>>>> Denis Lila wrote: >>>>>>> Hello Jim. >>>>>>> >>>>>>> I thought about checking the output and changing the behaviour >>>>>>> depending on whether the output is a PC2D or a LineSink, but I >>>>>> didn't >>>>>>> implement it because I thought the point was to get rid of the >>>>>> sampling >>>>>>> at this stage. However, if performance is the issue, then I >> guess >>>>>> I'll >>>>>>> start working on it. >>>>>>> >>>>>>> Although, I wonder whether it is really worth it. I think most >>>>> lines >>>>>> drawn >>>>>>> won't be wider than about 5 pixels, which means that the >> current >>>>> way >>>>>> will >>>>>>> emit about 7 lines, so that's 14 coordinates. 2 bezier quarter >>>>>> circles will >>>>>>> require 12 coordinates. In terms of storage, there isn't much >>>>>> difference, and >>>>>>> for lines of width 4 or smaller the current method is more >>>>>> efficient. >>>>>>> I'm also guessing that it's harder for the rasterizer to deal >> with >>>>>> bezier >>>>>>> curves than with straight lines, so is it possible that >> replacing >>>>>> the >>>>>>> 3.14*lineWidth/2 lines generated by the current method with 2 >>>>> bezier >>>>>>> quarter circles isn't worth it (for small lineWidths)? >>>>>>> >>>>>>> Thanks, >>>>>>> Denis. >>>>>>> >>>>>>> ----- "Jim Graham" wrote: >>>>>>> >>>>>>>> Sigh - that makes sense. One issue is that the resulting >> paths >>>>> it >>>>>>>> generates are much more "verbose" than they need to be. This >>>>> would >>>>>>>> generally mean that it takes far more storage than it would >>>>>> otherwise >>>>>>>> need - and it means that if the result needs to be transformed >>>>> then >>>>>> it >>>>>>>> would take many more computations to transform each segment >> than >>>>>> the >>>>>>>> bezier. >>>>>>>> >>>>>>>> So, perhaps it would be worth having it check the type of the >>>>>> output >>>>>>>> and >>>>>>>> do either a bezier or a bunch of lines depending on if it is a >>>>> PC2D >>>>>> or >>>>>>>> a >>>>>>>> LineSink? >>>>>>>> >>>>>>>> Also, it isn't really that difficult to for Renderer to >> include >>>>>> its >>>>>>>> own >>>>>>>> Cubic/Quadratic flattening code, but it might involve more >>>>>>>> calculations >>>>>>>> than the round-cap code since it would have to be written for >>>>>>>> arbitrary >>>>>>>> beziers whereas if you know it is a quarter circle then it is >>>>>> easier >>>>>>>> to >>>>>>>> know how far to subdivide... :-( >>>>>>>> >>>>>>>> ...jim >>>>>>>> >>>>>>>> Denis Lila wrote: >>>>>>>>> So, I have been thinking about this, and I can't see a good >>>>>>>>> way to do it that wouldn't involve heavy changes to Pisces. >>>>>>>>> >>>>>>>>> In order for Stroker to generate Bezier quarter circles, it >>>>> would >>>>>>>>> have to implement a curveTo method, which means Stroker >> should >>>>>>>>> start implementing PathConsumer2D and instead of using a >>>>> LineSink >>>>>>>>> output it would have to use a PathConsumer2D output (either >>>>> that, >>>>>>>> or >>>>>>>>> LineSink should include a curveTo method, but then there >> won't >>>>>>>> really >>>>>>>>> be any difference between a LineSink and a PathConsumer2D. By >>>>> the >>>>>>>> way, >>>>>>>>> LineSink doesn't have any implemented methods, so why is it >> an >>>>>>>> abstract >>>>>>>>> class as opposed to an interface?) >>>>>>>>> >>>>>>>>> Stroker is used in 3 ways: >>>>>>>>> 1. As an implementation of BasicStroke's createStrokedShape >>>>>> method. >>>>>>>> This >>>>>>>>> uses a Path2D object as output. >>>>>>>>> 2. As a way of feeding a PathConsumer2D without calling >>>>>>>> createStrokedShape >>>>>>>>> to generate an intermediate Shape. This uses a PathConsumer2D >>>>>>>> output. >>>>>>>>> 3. As a way of feeding lines to a Renderer object, which >>>>>> generates >>>>>>>> alpha >>>>>>>>> tiles used for anti-aliasing that are fed to a cache and >>>>>> extracted >>>>>>>> as needed >>>>>>>>> by an AATileGenerator. Obviously, Stroker's output here is a >>>>>>>> Renderer. >>>>>>>>> 1 and 2 aren't problems, because the underlying output >> objects >>>>>>>> support >>>>>>>>> Bezier curves. 3, however, doesn't, and it seems like >>>>> implementing >>>>>> a >>>>>>>>> curveTo method for Renderer would be very difficult because >> the >>>>>> way >>>>>>>> it >>>>>>>>> generates alpha tiles is by scanning the drawn edges with >>>>>>>> horizontal >>>>>>>>> scan lines, and for each scan line finding the >> x-intersections >>>>> of >>>>>>>> the scan >>>>>>>>> lines and the edges. Then it determines the alpha values (I'm >>>>> not >>>>>>>> too sure >>>>>>>>> how it does this). >>>>>>>>> In order to implement Bezier curves in Renderer, we would >> have >>>>> to >>>>>>>> have >>>>>>>>> a quick way of computing, for each scan line, all its >>>>>> intersections >>>>>>>> with >>>>>>>>> however many Bezier curves are being drawn. >>>>>>>>> >>>>>>>>> I haven't given much thought to how this could be done, as I >> am >>>>>> not >>>>>>>> very >>>>>>>>> familiar with Bezier curves, but it doesn't seem easy enough >> to >>>>>>>> justify >>>>>>>>> fixing such a small bug. >>>>>>>>> >>>>>>>>> ----- Original Message ----- >>>>>>>>> From: "Jim Graham" >>>>>>>>> To: "Denis Lila" >>>>>>>>> Cc: 2d-dev at openjdk.java.net >>>>>>>>> Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada >>>>>>>> Eastern >>>>>>>>> Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps >> on >>>>>>>> scaled lines. >>>>>>>>> I don't understand - why do we generate sample points based >> on >>>>>> the >>>>>>>> size >>>>>>>>> of the cap? Why not generate a pair of bezier >> quarter-circles >>>>>> and >>>>>>>> let >>>>>>>>> the rasterizer deal with sampling? >>>>>>>>> >>>>>>>>> ...jim >>>>>>>>> >>>>>>>>> Denis Lila wrote: >>>>>>>>>> Hello. >>>>>>>>>> >>>>>>>>>> I think I have a fix for this bug: >>>>>>>>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506 >>>>>>>>>> >>>>>>>>>> Basically, the problem is that if there is a magnifying >> affine >>>>>>>> transformation set on the graphics object and one tries to draw >> a >>>>>> line >>>>>>>> with small thickness and round end caps, the end caps appear >>>>>> jagged. >>>>>>>> This is because the computation of the length of the array >> that >>>>>>>> contains the points on the "pen" with which the decoration is >>>>>> drawn >>>>>>>> does not take into account the size of the pen after the >>>>>> magnification >>>>>>>> of the affine transformation. So, for example, if the line >> length >>>>>> was >>>>>>>> set to 1, and the transformation was a scaling by 10, the >>>>>> resulting >>>>>>>> pen would have a diameter of 10, but only 3 pen points would >> be >>>>>>>> computed (pi*untransformedLineWidth), so the end cap looks like >> a >>>>>>>> triangle. >>>>>>>>>> My fix computes an approximation of the circumference of the >>>>>>>> transformed pen (which is an ellipse) and uses that as the >> number >>>>>> of >>>>>>>> points on the pen. The approximation is crude, but it is >> simple, >>>>>>>> faster than alternatives >>>>>>>> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I >> can >>>>>> say >>>>>>>> from observations that it works fairly well. >>>>>>>>>> There is also icing on the cake, in the form of slight >>>>>> improvements >>>>>>>> in performance when the scaling is a zooming out. Example: if >> the >>>>>>>> original line width was 100, but g2d.scale(0.1,0.1) was set, >> then >>>>>> the >>>>>>>> resulting line would have a width of 10, so only ~31 points >> are >>>>>>>> necessary for the decoration to look like a circle, but >> without >>>>>> this >>>>>>>> patch, about 314 points are computed (and a line is emitted to >>>>>> each >>>>>>>> one of them). >>>>>>>>>> I appreciate any feedback. >>>>>>>>>> >>>>>>>>>> Regards, >>>>>>>>>> Denis Lila. >>>>>>>>>> From james.graham at oracle.com Tue Jul 13 19:27:27 2010 From: james.graham at oracle.com (Jim Graham) Date: Tue, 13 Jul 2010 12:27:27 -0700 Subject: [OpenJDK 2D-Dev] X11 uniform scaled wide lines and dashed lines; STROKE_CONTROL in Pisces In-Reply-To: <1524388037.66741278946225991.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <1524388037.66741278946225991.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C3CBE1F.4060309@oracle.com> The main issue is the extra overhead of another set of methods to call "through" when getting the geometry. I don't have any gut feel on that other than implementing it and doing performance testing... ...jim On 7/12/2010 7:50 AM, Denis Lila wrote: > Hello Jim. > > I think the second way would be better because there would be no > repeated code, and it would be easier to implement. > Do you think there will be any performance benefit from the first way? > > Regards, > Denis. > > ----- "Jim Graham" wrote: > >> Hi Denis, >> >> It would be ill-advised to normalize the coordinates after flattening. >> >> The quality would be really bad. >> >> Perhaps this is a good reason to start looking at updating Pisces to >> take curves and flatten at the lowest level? >> >> Or, I suppose we could get a non-flattened iterator from the source >> path, send it through a "normalizing" filter, and then through a >> flattening filter (the way many of the existing objects do flattening >> is >> to just get their regular iterator and run it through an instance of >> FlatteningPathIterator so we could do this manually with an >> intervening >> "NormalizingPathIterator" if normalization is needed)... >> >> ...jim >> >> Denis Lila wrote: >>> Hello Jim. >>> >>> Thanks for that. I'll get to work on implementing it. >>> >>> One thing though, about normalizing the control points of bezier >>> curves: pisces never gets any bezier curves as input. It only gets >>> lines that are the product of flattening bezier curves. >>> >>> Pisces receives its input from flattening path iterators which get >> it >>> from other path iterators. Of course we can't require these to send >> out >>> normalized points. In order to normalize the control points we need >> to >>> be able to look at the bezier curves in Pisces, so we can't just >> take >>> all the input from the flattener. However, pisces can't handle >> curves >>> (yet, hopefully), so after the normalization, they must be >> flattened, and >>> this is the problem. I think it's a pretty good idea to do this by >>> storing the input form the iterator into pisces (after >> normalization), >>> creating a nameless path iterator that just iterates through all >> that, >>> and using this iterator to create a flattening iterator, which then >>> is used as before. >>> >>> Does anyone have any other ideas? >>> >>> Thank you, >>> Denis. >>> >>> >>> ----- "Jim Graham" wrote: >>> >>>> For AA this is exactly what we do (round to nearest pixel centers >> for >>>> >>>> strokes). Note that this is done prior to any line widening code >> is >>>> executed. >>>> >>>> For non-AA we normalize coordinates to, I believe the (0.25, 0.25) >> >>>> sub-pixel location. This is so that the transitions between >> widening >>>> of >>>> lines occurs evenly (particularly for horizontal and vertical wide >> >>>> lines). If you round to pixel edges then you have the following >>>> progression (note that the line width grows by half on either side >> of >>>> >>>> the original geometry so you have to consider the "line widths" >> where >>>> >>>> you encounter the pixel centers to your left and right (or above >> and >>>> below) which govern when that column (or row) of pixels first >> turns >>>> on): >>>> >>>> width 0.00 => 0.99 nothing drawn (except we kludge this) >>>> width 1.00 => 1.00 1 pixel wide (col to left turns on) >>>> width 1.01 => 2.99 2 pixels wide (col to right turns on) >>>> width 3.00 => 3.00 3 pixels wide (etc.) >>>> width 3.01 => 4.99 4 pixels wide >>>> >>>> Note that it is nearly impossible to get an odd-width line. You >>>> basically have to have exactly an integer width to get an odd-width >> >>>> line. This is because at the odd widths you reach the "half pixel" >> >>>> locations on both sides of the line at the same time. Due to the >>>> "half-open" insideness rules only one of the pixels will be chosen >> to >>>> be >>>> inside this path. Just below these sizes and you fail to hit >> either >>>> pixel center. Just at the integer size you reach both pixel >> centers >>>> at >>>> the same time. Just slightly larger than that width and now you've >> >>>> fully enclosed both pixel centers and the line width has to >> increase >>>> by >>>> nearly 2.0 until you reach the next pixel centers. >>>> >>>> (The kludge I talk about above is that we set a minimum pen width >> so >>>> that we never fail to draw a line even if the line width is set to >>>> 0.0, >>>> but the above table was a theoretical description of the absolute >>>> rules.) >>>> >>>> If we rounded them to pixel centers, then the transitions look >> like >>>> this: >>>> >>>> width 0.00 => 0.00 nothing drawn (modulo kludge) >>>> width 0.01 => 1.99 1 pixel wide (column you are in turns on) >>>> width 2.00 => 2.00 2 pixels wide (column to left turns on) >>>> width 2.01 => 3.99 3 pixels wide (column to right turns on) >>>> width 4.00 => 4.00 4 pixels wide (etc.) >>>> width 4.01 => 5.99 5 pixels wide >>>> >>>> We have a similar effect as above, but biased towards making even >> line >>>> >>>> widths harder. >>>> >>>> So, by locating lines at (0.25, 0.25) subpixel location we end up >> with >>>> a >>>> very even progression: >>>> >>>> width 0.00 => 0.50 nothing drawn (modulo kludge) >>>> width 0.51 => 1.50 1 pixel wide (column you are in turns on) >>>> width 1.51 => 2.50 2 pixel wide (column to left gets added) >>>> width 2.51 => 3.50 3 pixel wide (column to right gets added) >>>> width 3.51 => 4.50 4 pixel wide (etc.) >>>> >>>> This gives us nice even and gradual widening of the lines as we >>>> increase >>>> the line width by sub-pixel amounts and the line widths are fairly >> >>>> stable around integer widths. >>>> >>>> Also, note that we don't say "when stroking" as you might want to >>>> normalize both strokes and fills so that they continue to match. I >> >>>> believe that we normalize both strokes and fills for non-AA and we >>>> only >>>> normalize strokes for AA (and leave AA fills as "pure"). AA is >> less >>>> problematic with respect to creating gaps if your stroke and fill >>>> normalization are not consistent. >>>> >>>> The rounding equations are along the lines of: >>>> >>>> v = Math.floor(v + rval) + aval; >>>> >>>> For center of pixel you use (rval=0.0, aval=0.5) >>>> For 0.25,0.25 rounding use (rval=0.25, aval=0.25) >>>> For edge of pixel you use (rval=0.5, aval=0.0) >>>> >>>> Also, we came up with an interesting way of adjusting the control >>>> points >>>> of quads and cubics if we adjusted their end points, but I don't >> know >>>> if >>>> what we did was really the best idea. For quads we adjust the >> control >>>> >>>> point by the average of the adjustments that we applied to its 2 >> end >>>> points. For cubics, we move the first control point by the same >>>> amount >>>> as we moved the starting endpoint and the second control point by >> the >>>> >>>> amount we moved the final endpoint. The jury is out on whether >> that >>>> is >>>> the most aesthetic technique... >>>> >>>> ...jim >>>> >>>> Denis Lila wrote: >>>>> Regarding VALUE_STROKE_NORMALIZE the API says: >>>>> Stroke normalization control hint value -- >> geometry >>>> should >>>>> be normalized to improve uniformity or spacing of >>>> lines and >>>>> overall aesthetics. Note that different >>>> normalization >>>>> algorithms may be more successful than others for >>>> given >>>>> input paths. >>>>> >>>>> I can only think of one example where VALUE_STROKE_NORMALIZE makes >> a >>>> visible >>>>> difference between the closed source implementation and OpenJDK: >>>>> when drawing anti-aliased horizontal or vertical lines of width >> 1, >>>> Pisces >>>>> draws a 2 pixel wide line with half intensity (because integer >>>> coordinates >>>>> are between pixels). Sun's jdk with VALUE_SROKE_NORMALIZE turned >> on >>>> draws >>>>> a 1 pixel line with full intensity. This could to achieved by >> just >>>>> checking for normalization and rounding coordinates to the >> nearest >>>> half >>>>> pixel, but this solution seems too simple, and I'm not sure >> whether >>>> I'm missing >>>>> anything. It would also probably cause problems when drawing >>>> anti-aliased >>>>> short lines (which is done when drawing any sort of curve) >>>>> Unless, of course, this rounding was restricted to just >> horizontal >>>> and >>>>> vertical lines. >>>>> >>>>> Regards, >>>>> Denis. From james.graham at oracle.com Tue Jul 13 19:30:37 2010 From: james.graham at oracle.com (Jim Graham) Date: Tue, 13 Jul 2010 12:30:37 -0700 Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <463962734.70481278947100641.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <463962734.70481278947100641.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C3CBEDD.2040201@oracle.com> Hi Denis, float operations are pretty fast and they are usually done in a separate part of the processor so the compiler can schedule a lot of bookkeeping instructions to run in parallel with waiting for the results of the FP instruction. In the end, they often end up being "free" if there are enough bookkeeping instructions (branches, fetching data, etc.) in amongst the data. Given how many alternate instructions you are pointing out for the fixed point code it would be very likely that this would be a "win". The main reason that Pisces is implemented heavily in fixed point is that it was originally written for the mobile platform where there are no FP instructions. We don't have to worry about that on the desktop (any more). I strongly support you converting things to fp if you want to do it... ...jim On 7/12/2010 8:05 AM, Denis Lila wrote: > Hello. > > Is it ok if I do this? I already started working on it on Friday. > I think I should be done by tomorrow. > > But yes, I agree that we should convert to floating point. As for > performance, there's also the fact that right now we're trading > one double multiplication for 2 casts to long, 1 long multiplication, > 1 bit shift of a long, and 1 cast back to an int. I don't know much > about how these are done in hardware, but it doesn't seem like they'd > be faster than the double multiplication. > > As for large coordinates, there's a bug report about it (one not > reported by me :) ) here: https://bugzilla.redhat.com/show_bug.cgi?id=597227 > I submitted a matching bug report on bugs.sun.com (ID 6967436), but I > can't find it when I search for it. > > Denis. > > ----- "Jim Graham" wrote: > >> Sigh... >> >> Pisces could really stand to upgrade to floats/doubles everywhere, for >> >> several reasons: >> >> - FPU ops are likely as fast if not faster on modern hardware due to >> parallel execution of FP instructions alongside regular instructions. >> >> - Don't have to worry about getting coordinates larger than 32K (I >> don't >> think this is well tested, but I imagine that Pisces will not deal >> with >> it very gracefully). >> >> - Lots of code is greatly simplified not having to deal with the >> semantics of how to do fixed point multiplies, divides, and >> conversions. >> >> I meant to do this during the original integration, but I wanted to >> get >> the task done as quickly as possible so that we could have an open >> source alternative to the closed Ductus code so I left that task for a >> >> later update. But, now that a lot of work is being done on the code >> to >> fix it up, it might be better to do the float conversion now so that >> the >> maintenance is easier and before we end up creating a lot of new fixed >> >> point code. >> >> My plate is full right now, but hopefully I can interest someone else >> in >> doing a cleanup cycle? (Donning my Tom Sawyer hat... ;-) >> >> ...jim From dlila at redhat.com Tue Jul 13 19:49:17 2010 From: dlila at redhat.com (Denis Lila) Date: Tue, 13 Jul 2010 15:49:17 -0400 (EDT) Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <4C3CBEDD.2040201@oracle.com> Message-ID: <905179417.192081279050557049.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hello. And, I just finished it. At least it compiled successfully. I'm sure there are a few runtime bugs. I'll try to have a webrev out by today. Regards, Denis. ----- "Jim Graham" wrote: > Hi Denis, > > float operations are pretty fast and they are usually done in a > separate > part of the processor so the compiler can schedule a lot of > bookkeeping > instructions to run in parallel with waiting for the results of the FP > > instruction. In the end, they often end up being "free" if there are > > enough bookkeeping instructions (branches, fetching data, etc.) in > amongst the data. > > Given how many alternate instructions you are pointing out for the > fixed > point code it would be very likely that this would be a "win". > > The main reason that Pisces is implemented heavily in fixed point is > that it was originally written for the mobile platform where there are > > no FP instructions. We don't have to worry about that on the desktop > > (any more). > > I strongly support you converting things to fp if you want to do > it... > > ...jim > > On 7/12/2010 8:05 AM, Denis Lila wrote: > > Hello. > > > > Is it ok if I do this? I already started working on it on Friday. > > I think I should be done by tomorrow. > > > > But yes, I agree that we should convert to floating point. As for > > performance, there's also the fact that right now we're trading > > one double multiplication for 2 casts to long, 1 long > multiplication, > > 1 bit shift of a long, and 1 cast back to an int. I don't know much > > about how these are done in hardware, but it doesn't seem like > they'd > > be faster than the double multiplication. > > > > As for large coordinates, there's a bug report about it (one not > > reported by me :) ) here: > https://bugzilla.redhat.com/show_bug.cgi?id=597227 > > I submitted a matching bug report on bugs.sun.com (ID 6967436), but > I > > can't find it when I search for it. > > > > Denis. > > > > ----- "Jim Graham" wrote: > > > >> Sigh... > >> > >> Pisces could really stand to upgrade to floats/doubles everywhere, > for > >> > >> several reasons: > >> > >> - FPU ops are likely as fast if not faster on modern hardware due > to > >> parallel execution of FP instructions alongside regular > instructions. > >> > >> - Don't have to worry about getting coordinates larger than 32K (I > >> don't > >> think this is well tested, but I imagine that Pisces will not deal > >> with > >> it very gracefully). > >> > >> - Lots of code is greatly simplified not having to deal with the > >> semantics of how to do fixed point multiplies, divides, and > >> conversions. > >> > >> I meant to do this during the original integration, but I wanted > to > >> get > >> the task done as quickly as possible so that we could have an open > >> source alternative to the closed Ductus code so I left that task > for a > >> > >> later update. But, now that a lot of work is being done on the > code > >> to > >> fix it up, it might be better to do the float conversion now so > that > >> the > >> maintenance is easier and before we end up creating a lot of new > fixed > >> > >> point code. > >> > >> My plate is full right now, but hopefully I can interest someone > else > >> in > >> doing a cleanup cycle? (Donning my Tom Sawyer hat... ;-) > >> > >> ...jim From james.graham at oracle.com Wed Jul 14 00:21:36 2010 From: james.graham at oracle.com (Jim Graham) Date: Tue, 13 Jul 2010 17:21:36 -0700 Subject: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines. In-Reply-To: <1076160120.60311278944522065.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <1076160120.60311278944522065.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C3D0310.6040906@oracle.com> Hi Denis, In looking through this code, I can see where it emits the proper join for ccw turns, but it looks like it just emits a round join for cw turns. Is that true? Doesn't this mean that a cw path will always have round joins? Or am I missing something? My expectation was that the code would emit the proper joins for both ccw and cw turns, but it would either place it in the outgoing or the return path depending on whether the turn was ccw, no? I don't see how that happens (but I haven't actually tested the code)... ...jim Denis Lila wrote: > Hello Jim. > > I'm terribly sorry about that. > I fixed it. Now the only highlighted lines in the webrev should be > lines I actually changed. > Please take another look at it. > (link is still the same: http://icedtea.classpath.org/~dlila/webrevs/bezierRoundJoins/webrev/) > > Thanks, > Denis. > > PS: I added a new method: emitReverse, that goes through the reverse list > and emits it. It's used in 2 methods which used to just do it themselves. > > ----- "Jim Graham" wrote: > >> Hi Denis, >> >> You moved some code around without modifying it. This makes it hard >> to >> see what changed and what didn't and verify that the changes are >> accurate. Also, it adds diffs to the file that are unrelated to the >> fixing of the bug. Was there a practical reason for why you moved the >> >> code around? In particular I refer to: >> >> - the setup code that deals with "if (joinStyle == JOIN_MITER)" >> >> - the setOutput method - which not only moved, but lost its javadocs >> >> - computeMiter() and drawMiter() >> >> All of that code "appears" to be unchanged at first glance, but it is >> >> hard to tell from the webrevs. Also, a couple of stylistic issues: >> >> - you changed the declarations of isCCW which moved its arguments >> over, >> but the continuation lines aren't indented to match >> >> - The two "flavors" of emitCurveTo() should probably be next to each >> other (i.e. not have emitLineTo() between them or fall between the two >> >> flavors of emitLineTo()). >> >> In general I think the changes are OK, but I'm still reviewing them >> and >> the above issues sprung to mind on a first pass (and/or they are >> complicating the "contextual" review) so I thought I'd mention them >> earlier than later... >> >> ...jim >> >> Denis Lila wrote: >>> Hello. >>> >>> I just noticed that approximation of circle arcs by bezier curves >>> had already been implemented in ArcIterator by Jim Graham. >>> >>> It computes the same control points as my solution, but it does so >>> more straightforwardly, without any rotation, so it is faster and >>> clearer. I have updated my solution to include this. >>> >>> The link remains the same. >>> >>> Thanks, >>> Denis. >>> >>> ----- "Denis Lila" wrote: >>> >>>> Hello. >>>> >>>> I think I got this working. The webrev is at: >>>> >> http://icedtea.classpath.org/~dlila/webrevs/bezierRoundJoins/webrev/ >>>> (NOTE: this is not a final version. I have included 2 versions >>>> of 2 methods. Only one set should be kept. See below for more.) >>>> >>>> My Changes: >>>> ----------- >>>> 1. >>>> I've made LineSink into an interface, rather than an abstract >>>> class, >>>> because all of its methods were abstract, so it makes more sense >> this >>>> way. >>>> >>>> 2. >>>> I've introduced a new interface that extends LineSink called >>>> PathSink, >>>> which allows the curveTo method, so there have been no changes to >>>> Stroker's public interface. When someone wants to create a Stroker >>>> with a PathSink output, it simply passes its constructor a >> PathSink, >>>> so the only changes outside of Stroker are in >> PiscesRenderingEngine, >>>> where the methods that handle Path2D and PathConsumer2D objects >>>> create nameless PathSinks instead of nameless LineSinks. >>>> >>>> 3. In Stroker: >>>> I've introduced a method called drawBezRoundJoin, analogous to >>>> computeRoundJoin. In drawRoundJoin I detect whether the output is >>>> a PathSink. If it is, I call drawBezRoundJoin, otherwise >> everything >>>> proceeds as it used to. drawBezRoundJoin uses computeBezierPoints >> to >>>> compute the control points. computeBezierPoints computes the >> control >>>> points >>>> for an arc of t radians, starting at angle a, with radius r >>>> by computing the control points of an arc of radius 1 of t radians >>>> that >>>> starts at angle -t/2. This is done by solving the equations >> resulting >>>> from the constraints that (P3-P2) and (P1-P0) must be parallel to >> the >>>> arc's tangents at P3 and P0 respectively, and that B(1/2)=(1,0). >> Then >>>> the >>>> points are scaled by r, and rotated counter clockwise by a+t/2. >>>> Then drawBezRoundJoin emits the curve. >>>> All this is done in a loop which is used to break up large >> arcs >>>> into >>>> more than one bezier curve. Through the iterations, the computed >>>> control >>>> points don't change - the only thing that changes is how they're >>>> rotated. >>>> So a good alternative approach would be to do the rotation >> outside >>>> of >>>> computeBezierPoints, and call computeBezierPoints once outside of >> the >>>> loop, >>>> so that the control points aren't recomputed unnecessarily. >>>> I have included code for this in the methods computeBezierPoints2 >> and >>>> drawBezRoundJoin2. This is my favoured approach, since it is >> almost >>>> as clear as the other one, and it is faster. >>>> >>>> There is one more optimization that can be made, and I've >> included >>>> it >>>> in a comment in line 703. >>>> >>>> I would very much appreciate any comments about any of this, >> but >>>> especially >>>> about the idea in line 703 and about >>>> computeBezierPoints2,drawBezRoundJoin2 >>>> vs. computeBezierPoints,drawBezRoundJoin. >>>> >>>> 4. >>>> Stroker used to only have lines, but now it can emit lines and >>>> curves, so >>>> I needed to change the format of reverse, to not only store >>>> coordinates, but >>>> to also tag them as belonging to a line or a curve. >>>> >>>> >>>> Other Approaches: >>>> ----------------- >>>> 1. >>>> Since what needed to be done was to alter the behaviour of one >>>> part of Stroker (drawing of round joins/caps) depending on the >> type >>>> of the output object, I thought it would be appropriate to make >>>> Stroker >>>> an abstract factory, turn the methods that draw round joins/caps >> into >>>> abstract ones, put all the common functionality in concrete >> methods >>>> in Stroker, and put all the join/cap drawing methods in overriding >>>> methods >>>> in concrete children of Stroker (instances of which were returned >>>> by static factories in Stroker). >>>> However, this was a bad approach, because the round cap/join >>>> drawing >>>> methods are private, so the only way to call them in Stroker's >>>> children >>>> from public methods in Stroker is to cast "this". So the code >> became >>>> littered with instanceof operators and casts. Not to mention that >>>> Stroker's >>>> public interface had to change, and some functionality was lost: >>>> Stroker >>>> allows changing it's output, so it is possible to use just 1 >> Stroker >>>> object >>>> to widen paths going to many different outputs (but not at the >> same >>>> time). >>>> This could no longer be supported with this approach. >>>> The way I did it has none of these weaknesses. >>>> >>>> 2. As for algorithms for the circle approximation, I considered 2: >>>> a. Compute the control points using the constraints that >>>> B(1/3)=A(a+t/3) >>>> and B(2/3) = A(a+2t/3) (i.e. make the arc and the bezier curve >>>> coincide at 2 >>>> evenly spaced points in the arc). This didn't work very well: some >> of >>>> the end >>>> caps looked more like triangles. >>>> b. Let B(1/2) = A(a+t/2), and B'(1/2) = A'(a+t/2). This worked >>>> better, but >>>> still not good enough. >>>> >>>> If anyone knows of any better ways to compute the control points, >>>> please let >>>> me know. >>>> >>>> I'm sorry for the length of this. I tried to make it shorter. >>>> >>>> Thank you very much, >>>> Denis. >>>> >>>> >>>> ----- "Jim Graham" wrote: >>>> >>>>> Hi Denis, >>>>> >>>>> Consider the case of using BasicStroke.createStrokedShape(). How >> do >>>>> you >>>>> know how many pixels the resulting path will occupy? You can't >>>> reduce >>>>> to concrete samples if you don't know the transform. >>>>> >>>>> So, for rendering, then you may be correct. But for cases where >> the >>>>> path is being asked for then beziers are the only responsible >>>>> solution... >>>>> >>>>> ...jim >>>>> >>>>> Denis Lila wrote: >>>>>> Hello Jim. >>>>>> >>>>>> I thought about checking the output and changing the behaviour >>>>>> depending on whether the output is a PC2D or a LineSink, but I >>>>> didn't >>>>>> implement it because I thought the point was to get rid of the >>>>> sampling >>>>>> at this stage. However, if performance is the issue, then I >> guess >>>>> I'll >>>>>> start working on it. >>>>>> >>>>>> Although, I wonder whether it is really worth it. I think most >>>> lines >>>>> drawn >>>>>> won't be wider than about 5 pixels, which means that the current >>>> way >>>>> will >>>>>> emit about 7 lines, so that's 14 coordinates. 2 bezier quarter >>>>> circles will >>>>>> require 12 coordinates. In terms of storage, there isn't much >>>>> difference, and >>>>>> for lines of width 4 or smaller the current method is more >>>>> efficient. >>>>>> I'm also guessing that it's harder for the rasterizer to deal >> with >>>>> bezier >>>>>> curves than with straight lines, so is it possible that >> replacing >>>>> the >>>>>> 3.14*lineWidth/2 lines generated by the current method with 2 >>>> bezier >>>>>> quarter circles isn't worth it (for small lineWidths)? >>>>>> >>>>>> Thanks, >>>>>> Denis. >>>>>> >>>>>> ----- "Jim Graham" wrote: >>>>>> >>>>>>> Sigh - that makes sense. One issue is that the resulting paths >>>> it >>>>>>> generates are much more "verbose" than they need to be. This >>>> would >>>>>>> generally mean that it takes far more storage than it would >>>>> otherwise >>>>>>> need - and it means that if the result needs to be transformed >>>> then >>>>> it >>>>>>> would take many more computations to transform each segment >> than >>>>> the >>>>>>> bezier. >>>>>>> >>>>>>> So, perhaps it would be worth having it check the type of the >>>>> output >>>>>>> and >>>>>>> do either a bezier or a bunch of lines depending on if it is a >>>> PC2D >>>>> or >>>>>>> a >>>>>>> LineSink? >>>>>>> >>>>>>> Also, it isn't really that difficult to for Renderer to include >>>>> its >>>>>>> own >>>>>>> Cubic/Quadratic flattening code, but it might involve more >>>>>>> calculations >>>>>>> than the round-cap code since it would have to be written for >>>>>>> arbitrary >>>>>>> beziers whereas if you know it is a quarter circle then it is >>>>> easier >>>>>>> to >>>>>>> know how far to subdivide... :-( >>>>>>> >>>>>>> ...jim >>>>>>> >>>>>>> Denis Lila wrote: >>>>>>>> So, I have been thinking about this, and I can't see a good >>>>>>>> way to do it that wouldn't involve heavy changes to Pisces. >>>>>>>> >>>>>>>> In order for Stroker to generate Bezier quarter circles, it >>>> would >>>>>>>> have to implement a curveTo method, which means Stroker should >>>>>>>> start implementing PathConsumer2D and instead of using a >>>> LineSink >>>>>>>> output it would have to use a PathConsumer2D output (either >>>> that, >>>>>>> or >>>>>>>> LineSink should include a curveTo method, but then there won't >>>>>>> really >>>>>>>> be any difference between a LineSink and a PathConsumer2D. By >>>> the >>>>>>> way, >>>>>>>> LineSink doesn't have any implemented methods, so why is it an >>>>>>> abstract >>>>>>>> class as opposed to an interface?) >>>>>>>> >>>>>>>> Stroker is used in 3 ways: >>>>>>>> 1. As an implementation of BasicStroke's createStrokedShape >>>>> method. >>>>>>> This >>>>>>>> uses a Path2D object as output. >>>>>>>> 2. As a way of feeding a PathConsumer2D without calling >>>>>>> createStrokedShape >>>>>>>> to generate an intermediate Shape. This uses a PathConsumer2D >>>>>>> output. >>>>>>>> 3. As a way of feeding lines to a Renderer object, which >>>>> generates >>>>>>> alpha >>>>>>>> tiles used for anti-aliasing that are fed to a cache and >>>>> extracted >>>>>>> as needed >>>>>>>> by an AATileGenerator. Obviously, Stroker's output here is a >>>>>>> Renderer. >>>>>>>> 1 and 2 aren't problems, because the underlying output objects >>>>>>> support >>>>>>>> Bezier curves. 3, however, doesn't, and it seems like >>>> implementing >>>>> a >>>>>>>> curveTo method for Renderer would be very difficult because >> the >>>>> way >>>>>>> it >>>>>>>> generates alpha tiles is by scanning the drawn edges with >>>>>>> horizontal >>>>>>>> scan lines, and for each scan line finding the x-intersections >>>> of >>>>>>> the scan >>>>>>>> lines and the edges. Then it determines the alpha values (I'm >>>> not >>>>>>> too sure >>>>>>>> how it does this). >>>>>>>> In order to implement Bezier curves in Renderer, we would have >>>> to >>>>>>> have >>>>>>>> a quick way of computing, for each scan line, all its >>>>> intersections >>>>>>> with >>>>>>>> however many Bezier curves are being drawn. >>>>>>>> >>>>>>>> I haven't given much thought to how this could be done, as I >> am >>>>> not >>>>>>> very >>>>>>>> familiar with Bezier curves, but it doesn't seem easy enough >> to >>>>>>> justify >>>>>>>> fixing such a small bug. >>>>>>>> >>>>>>>> ----- Original Message ----- >>>>>>>> From: "Jim Graham" >>>>>>>> To: "Denis Lila" >>>>>>>> Cc: 2d-dev at openjdk.java.net >>>>>>>> Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada >>>>>>> Eastern >>>>>>>> Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on >>>>>>> scaled lines. >>>>>>>> I don't understand - why do we generate sample points based on >>>>> the >>>>>>> size >>>>>>>> of the cap? Why not generate a pair of bezier quarter-circles >>>>> and >>>>>>> let >>>>>>>> the rasterizer deal with sampling? >>>>>>>> >>>>>>>> ...jim >>>>>>>> >>>>>>>> Denis Lila wrote: >>>>>>>>> Hello. >>>>>>>>> >>>>>>>>> I think I have a fix for this bug: >>>>>>>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506 >>>>>>>>> >>>>>>>>> Basically, the problem is that if there is a magnifying >> affine >>>>>>> transformation set on the graphics object and one tries to draw >> a >>>>> line >>>>>>> with small thickness and round end caps, the end caps appear >>>>> jagged. >>>>>>> This is because the computation of the length of the array that >>>>>>> contains the points on the "pen" with which the decoration is >>>>> drawn >>>>>>> does not take into account the size of the pen after the >>>>> magnification >>>>>>> of the affine transformation. So, for example, if the line >> length >>>>> was >>>>>>> set to 1, and the transformation was a scaling by 10, the >>>>> resulting >>>>>>> pen would have a diameter of 10, but only 3 pen points would be >>>>>>> computed (pi*untransformedLineWidth), so the end cap looks like >> a >>>>>>> triangle. >>>>>>>>> My fix computes an approximation of the circumference of the >>>>>>> transformed pen (which is an ellipse) and uses that as the >> number >>>>> of >>>>>>> points on the pen. The approximation is crude, but it is >> simple, >>>>>>> faster than alternatives >>>>>>> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can >>>>> say >>>>>>> from observations that it works fairly well. >>>>>>>>> There is also icing on the cake, in the form of slight >>>>> improvements >>>>>>> in performance when the scaling is a zooming out. Example: if >> the >>>>>>> original line width was 100, but g2d.scale(0.1,0.1) was set, >> then >>>>> the >>>>>>> resulting line would have a width of 10, so only ~31 points are >>>>>>> necessary for the decoration to look like a circle, but without >>>>> this >>>>>>> patch, about 314 points are computed (and a line is emitted to >>>>> each >>>>>>> one of them). >>>>>>>>> I appreciate any feedback. >>>>>>>>> >>>>>>>>> Regards, >>>>>>>>> Denis Lila. >>>>>>>>> From james.graham at oracle.com Wed Jul 14 00:26:15 2010 From: james.graham at oracle.com (Jim Graham) Date: Tue, 13 Jul 2010 17:26:15 -0700 Subject: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines. In-Reply-To: <4C3D0310.6040906@oracle.com> References: <1076160120.60311278944522065.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> <4C3D0310.6040906@oracle.com> Message-ID: <4C3D0427.2070200@oracle.com> Sorry, ignore this message. I was misinterpreting the field "internalJoins" to mean "joins on the inside of the path (!ccw)". It actually means "implicit joins in the middle of a flattened curve" and I can see why those are always done round, so the code makes sense now (naming of the variable notwithstanding)... ...jim Jim Graham wrote: > Hi Denis, > > In looking through this code, I can see where it emits the proper join > for ccw turns, but it looks like it just emits a round join for cw > turns. Is that true? Doesn't this mean that a cw path will always have > round joins? Or am I missing something? > > My expectation was that the code would emit the proper joins for both > ccw and cw turns, but it would either place it in the outgoing or the > return path depending on whether the turn was ccw, no? I don't see how > that happens (but I haven't actually tested the code)... > > ...jim > > Denis Lila wrote: >> Hello Jim. >> >> I'm terribly sorry about that. >> I fixed it. Now the only highlighted lines in the webrev should be >> lines I actually changed. >> Please take another look at it. >> (link is still the same: >> http://icedtea.classpath.org/~dlila/webrevs/bezierRoundJoins/webrev/) >> >> Thanks, >> Denis. >> >> PS: I added a new method: emitReverse, that goes through the reverse list >> and emits it. It's used in 2 methods which used to just do it themselves. >> >> ----- "Jim Graham" wrote: >> >>> Hi Denis, >>> >>> You moved some code around without modifying it. This makes it hard >>> to see what changed and what didn't and verify that the changes are >>> accurate. Also, it adds diffs to the file that are unrelated to the >>> fixing of the bug. Was there a practical reason for why you moved the >>> >>> code around? In particular I refer to: >>> >>> - the setup code that deals with "if (joinStyle == JOIN_MITER)" >>> >>> - the setOutput method - which not only moved, but lost its javadocs >>> >>> - computeMiter() and drawMiter() >>> >>> All of that code "appears" to be unchanged at first glance, but it is >>> >>> hard to tell from the webrevs. Also, a couple of stylistic issues: >>> >>> - you changed the declarations of isCCW which moved its arguments >>> over, but the continuation lines aren't indented to match >>> >>> - The two "flavors" of emitCurveTo() should probably be next to each >>> other (i.e. not have emitLineTo() between them or fall between the two >>> >>> flavors of emitLineTo()). >>> >>> In general I think the changes are OK, but I'm still reviewing them >>> and the above issues sprung to mind on a first pass (and/or they are >>> complicating the "contextual" review) so I thought I'd mention them >>> earlier than later... >>> >>> ...jim >>> >>> Denis Lila wrote: >>>> Hello. >>>> >>>> I just noticed that approximation of circle arcs by bezier curves >>>> had already been implemented in ArcIterator by Jim Graham. >>>> It computes the same control points as my solution, but it does so >>>> more straightforwardly, without any rotation, so it is faster and >>>> clearer. I have updated my solution to include this. >>>> >>>> The link remains the same. >>>> >>>> Thanks, >>>> Denis. >>>> >>>> ----- "Denis Lila" wrote: >>>> >>>>> Hello. >>>>> >>>>> I think I got this working. The webrev is at: >>>>> >>> http://icedtea.classpath.org/~dlila/webrevs/bezierRoundJoins/webrev/ >>>>> (NOTE: this is not a final version. I have included 2 versions >>>>> of 2 methods. Only one set should be kept. See below for more.) >>>>> >>>>> My Changes: >>>>> ----------- >>>>> 1. >>>>> I've made LineSink into an interface, rather than an abstract >>>>> class, >>>>> because all of its methods were abstract, so it makes more sense >>> this >>>>> way. >>>>> >>>>> 2. >>>>> I've introduced a new interface that extends LineSink called >>>>> PathSink, >>>>> which allows the curveTo method, so there have been no changes to >>>>> Stroker's public interface. When someone wants to create a Stroker >>>>> with a PathSink output, it simply passes its constructor a >>> PathSink, >>>>> so the only changes outside of Stroker are in >>> PiscesRenderingEngine, >>>>> where the methods that handle Path2D and PathConsumer2D objects >>>>> create nameless PathSinks instead of nameless LineSinks. >>>>> >>>>> 3. In Stroker: >>>>> I've introduced a method called drawBezRoundJoin, analogous to >>>>> computeRoundJoin. In drawRoundJoin I detect whether the output is >>>>> a PathSink. If it is, I call drawBezRoundJoin, otherwise >>> everything >>>>> proceeds as it used to. drawBezRoundJoin uses computeBezierPoints >>> to >>>>> compute the control points. computeBezierPoints computes the >>> control >>>>> points >>>>> for an arc of t radians, starting at angle a, with radius r >>>>> by computing the control points of an arc of radius 1 of t radians >>>>> that >>>>> starts at angle -t/2. This is done by solving the equations >>> resulting >>>>> from the constraints that (P3-P2) and (P1-P0) must be parallel to >>> the >>>>> arc's tangents at P3 and P0 respectively, and that B(1/2)=(1,0). >>> Then >>>>> the >>>>> points are scaled by r, and rotated counter clockwise by a+t/2. >>>>> Then drawBezRoundJoin emits the curve. >>>>> All this is done in a loop which is used to break up large >>> arcs >>>>> into >>>>> more than one bezier curve. Through the iterations, the computed >>>>> control >>>>> points don't change - the only thing that changes is how they're >>>>> rotated. >>>>> So a good alternative approach would be to do the rotation >>> outside >>>>> of >>>>> computeBezierPoints, and call computeBezierPoints once outside of >>> the >>>>> loop, >>>>> so that the control points aren't recomputed unnecessarily. >>>>> I have included code for this in the methods computeBezierPoints2 >>> and >>>>> drawBezRoundJoin2. This is my favoured approach, since it is >>> almost >>>>> as clear as the other one, and it is faster. >>>>> >>>>> There is one more optimization that can be made, and I've >>> included >>>>> it >>>>> in a comment in line 703. >>>>> >>>>> I would very much appreciate any comments about any of this, >>> but >>>>> especially >>>>> about the idea in line 703 and about >>>>> computeBezierPoints2,drawBezRoundJoin2 >>>>> vs. computeBezierPoints,drawBezRoundJoin. >>>>> >>>>> 4. >>>>> Stroker used to only have lines, but now it can emit lines and >>>>> curves, so >>>>> I needed to change the format of reverse, to not only store >>>>> coordinates, but >>>>> to also tag them as belonging to a line or a curve. >>>>> >>>>> >>>>> Other Approaches: >>>>> ----------------- >>>>> 1. >>>>> Since what needed to be done was to alter the behaviour of one >>>>> part of Stroker (drawing of round joins/caps) depending on the >>> type >>>>> of the output object, I thought it would be appropriate to make >>>>> Stroker >>>>> an abstract factory, turn the methods that draw round joins/caps >>> into >>>>> abstract ones, put all the common functionality in concrete >>> methods >>>>> in Stroker, and put all the join/cap drawing methods in overriding >>>>> methods >>>>> in concrete children of Stroker (instances of which were returned >>>>> by static factories in Stroker). >>>>> However, this was a bad approach, because the round cap/join >>>>> drawing >>>>> methods are private, so the only way to call them in Stroker's >>>>> children >>>>> from public methods in Stroker is to cast "this". So the code >>> became >>>>> littered with instanceof operators and casts. Not to mention that >>>>> Stroker's >>>>> public interface had to change, and some functionality was lost: >>>>> Stroker >>>>> allows changing it's output, so it is possible to use just 1 >>> Stroker >>>>> object >>>>> to widen paths going to many different outputs (but not at the >>> same >>>>> time). >>>>> This could no longer be supported with this approach. >>>>> The way I did it has none of these weaknesses. >>>>> >>>>> 2. As for algorithms for the circle approximation, I considered 2: >>>>> a. Compute the control points using the constraints that >>>>> B(1/3)=A(a+t/3) >>>>> and B(2/3) = A(a+2t/3) (i.e. make the arc and the bezier curve >>>>> coincide at 2 >>>>> evenly spaced points in the arc). This didn't work very well: some >>> of >>>>> the end >>>>> caps looked more like triangles. >>>>> b. Let B(1/2) = A(a+t/2), and B'(1/2) = A'(a+t/2). This worked >>>>> better, but >>>>> still not good enough. >>>>> >>>>> If anyone knows of any better ways to compute the control points, >>>>> please let >>>>> me know. >>>>> >>>>> I'm sorry for the length of this. I tried to make it shorter. >>>>> >>>>> Thank you very much, >>>>> Denis. >>>>> >>>>> >>>>> ----- "Jim Graham" wrote: >>>>> >>>>>> Hi Denis, >>>>>> >>>>>> Consider the case of using BasicStroke.createStrokedShape(). How >>> do >>>>>> you >>>>>> know how many pixels the resulting path will occupy? You can't >>>>> reduce >>>>>> to concrete samples if you don't know the transform. >>>>>> >>>>>> So, for rendering, then you may be correct. But for cases where >>> the >>>>>> path is being asked for then beziers are the only responsible >>>>>> solution... >>>>>> >>>>>> ...jim >>>>>> >>>>>> Denis Lila wrote: >>>>>>> Hello Jim. >>>>>>> >>>>>>> I thought about checking the output and changing the behaviour >>>>>>> depending on whether the output is a PC2D or a LineSink, but I >>>>>> didn't >>>>>>> implement it because I thought the point was to get rid of the >>>>>> sampling >>>>>>> at this stage. However, if performance is the issue, then I >>> guess >>>>>> I'll >>>>>>> start working on it. >>>>>>> >>>>>>> Although, I wonder whether it is really worth it. I think most >>>>> lines >>>>>> drawn >>>>>>> won't be wider than about 5 pixels, which means that the current >>>>> way >>>>>> will >>>>>>> emit about 7 lines, so that's 14 coordinates. 2 bezier quarter >>>>>> circles will >>>>>>> require 12 coordinates. In terms of storage, there isn't much >>>>>> difference, and >>>>>>> for lines of width 4 or smaller the current method is more >>>>>> efficient. >>>>>>> I'm also guessing that it's harder for the rasterizer to deal >>> with >>>>>> bezier >>>>>>> curves than with straight lines, so is it possible that >>> replacing >>>>>> the >>>>>>> 3.14*lineWidth/2 lines generated by the current method with 2 >>>>> bezier >>>>>>> quarter circles isn't worth it (for small lineWidths)? >>>>>>> >>>>>>> Thanks, >>>>>>> Denis. >>>>>>> >>>>>>> ----- "Jim Graham" wrote: >>>>>>> >>>>>>>> Sigh - that makes sense. One issue is that the resulting paths >>>>> it >>>>>>>> generates are much more "verbose" than they need to be. This >>>>> would >>>>>>>> generally mean that it takes far more storage than it would >>>>>> otherwise >>>>>>>> need - and it means that if the result needs to be transformed >>>>> then >>>>>> it >>>>>>>> would take many more computations to transform each segment >>> than >>>>>> the >>>>>>>> bezier. >>>>>>>> >>>>>>>> So, perhaps it would be worth having it check the type of the >>>>>> output >>>>>>>> and >>>>>>>> do either a bezier or a bunch of lines depending on if it is a >>>>> PC2D >>>>>> or >>>>>>>> a >>>>>>>> LineSink? >>>>>>>> >>>>>>>> Also, it isn't really that difficult to for Renderer to include >>>>>> its >>>>>>>> own >>>>>>>> Cubic/Quadratic flattening code, but it might involve more >>>>>>>> calculations >>>>>>>> than the round-cap code since it would have to be written for >>>>>>>> arbitrary >>>>>>>> beziers whereas if you know it is a quarter circle then it is >>>>>> easier >>>>>>>> to >>>>>>>> know how far to subdivide... :-( >>>>>>>> >>>>>>>> ...jim >>>>>>>> >>>>>>>> Denis Lila wrote: >>>>>>>>> So, I have been thinking about this, and I can't see a good >>>>>>>>> way to do it that wouldn't involve heavy changes to Pisces. >>>>>>>>> >>>>>>>>> In order for Stroker to generate Bezier quarter circles, it >>>>> would >>>>>>>>> have to implement a curveTo method, which means Stroker should >>>>>>>>> start implementing PathConsumer2D and instead of using a >>>>> LineSink >>>>>>>>> output it would have to use a PathConsumer2D output (either >>>>> that, >>>>>>>> or >>>>>>>>> LineSink should include a curveTo method, but then there won't >>>>>>>> really >>>>>>>>> be any difference between a LineSink and a PathConsumer2D. By >>>>> the >>>>>>>> way, >>>>>>>>> LineSink doesn't have any implemented methods, so why is it an >>>>>>>> abstract >>>>>>>>> class as opposed to an interface?) >>>>>>>>> >>>>>>>>> Stroker is used in 3 ways: >>>>>>>>> 1. As an implementation of BasicStroke's createStrokedShape >>>>>> method. >>>>>>>> This >>>>>>>>> uses a Path2D object as output. >>>>>>>>> 2. As a way of feeding a PathConsumer2D without calling >>>>>>>> createStrokedShape >>>>>>>>> to generate an intermediate Shape. This uses a PathConsumer2D >>>>>>>> output. >>>>>>>>> 3. As a way of feeding lines to a Renderer object, which >>>>>> generates >>>>>>>> alpha >>>>>>>>> tiles used for anti-aliasing that are fed to a cache and >>>>>> extracted >>>>>>>> as needed >>>>>>>>> by an AATileGenerator. Obviously, Stroker's output here is a >>>>>>>> Renderer. >>>>>>>>> 1 and 2 aren't problems, because the underlying output objects >>>>>>>> support >>>>>>>>> Bezier curves. 3, however, doesn't, and it seems like >>>>> implementing >>>>>> a >>>>>>>>> curveTo method for Renderer would be very difficult because >>> the >>>>>> way >>>>>>>> it >>>>>>>>> generates alpha tiles is by scanning the drawn edges with >>>>>>>> horizontal >>>>>>>>> scan lines, and for each scan line finding the x-intersections >>>>> of >>>>>>>> the scan >>>>>>>>> lines and the edges. Then it determines the alpha values (I'm >>>>> not >>>>>>>> too sure >>>>>>>>> how it does this). >>>>>>>>> In order to implement Bezier curves in Renderer, we would have >>>>> to >>>>>>>> have >>>>>>>>> a quick way of computing, for each scan line, all its >>>>>> intersections >>>>>>>> with >>>>>>>>> however many Bezier curves are being drawn. >>>>>>>>> >>>>>>>>> I haven't given much thought to how this could be done, as I >>> am >>>>>> not >>>>>>>> very >>>>>>>>> familiar with Bezier curves, but it doesn't seem easy enough >>> to >>>>>>>> justify >>>>>>>>> fixing such a small bug. >>>>>>>>> >>>>>>>>> ----- Original Message ----- >>>>>>>>> From: "Jim Graham" >>>>>>>>> To: "Denis Lila" >>>>>>>>> Cc: 2d-dev at openjdk.java.net >>>>>>>>> Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada >>>>>>>> Eastern >>>>>>>>> Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on >>>>>>>> scaled lines. >>>>>>>>> I don't understand - why do we generate sample points based on >>>>>> the >>>>>>>> size >>>>>>>>> of the cap? Why not generate a pair of bezier quarter-circles >>>>>> and >>>>>>>> let >>>>>>>>> the rasterizer deal with sampling? >>>>>>>>> >>>>>>>>> ...jim >>>>>>>>> >>>>>>>>> Denis Lila wrote: >>>>>>>>>> Hello. >>>>>>>>>> >>>>>>>>>> I think I have a fix for this bug: >>>>>>>>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506 >>>>>>>>>> >>>>>>>>>> Basically, the problem is that if there is a magnifying >>> affine >>>>>>>> transformation set on the graphics object and one tries to draw >>> a >>>>>> line >>>>>>>> with small thickness and round end caps, the end caps appear >>>>>> jagged. >>>>>>>> This is because the computation of the length of the array that >>>>>>>> contains the points on the "pen" with which the decoration is >>>>>> drawn >>>>>>>> does not take into account the size of the pen after the >>>>>> magnification >>>>>>>> of the affine transformation. So, for example, if the line >>> length >>>>>> was >>>>>>>> set to 1, and the transformation was a scaling by 10, the >>>>>> resulting >>>>>>>> pen would have a diameter of 10, but only 3 pen points would be >>>>>>>> computed (pi*untransformedLineWidth), so the end cap looks like >>> a >>>>>>>> triangle. >>>>>>>>>> My fix computes an approximation of the circumference of the >>>>>>>> transformed pen (which is an ellipse) and uses that as the >>> number >>>>>> of >>>>>>>> points on the pen. The approximation is crude, but it is >>> simple, >>>>>>>> faster than alternatives >>>>>>>> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can >>>>>> say >>>>>>>> from observations that it works fairly well. >>>>>>>>>> There is also icing on the cake, in the form of slight >>>>>> improvements >>>>>>>> in performance when the scaling is a zooming out. Example: if >>> the >>>>>>>> original line width was 100, but g2d.scale(0.1,0.1) was set, >>> then >>>>>> the >>>>>>>> resulting line would have a width of 10, so only ~31 points are >>>>>>>> necessary for the decoration to look like a circle, but without >>>>>> this >>>>>>>> patch, about 314 points are computed (and a line is emitted to >>>>>> each >>>>>>>> one of them). >>>>>>>>>> I appreciate any feedback. >>>>>>>>>> >>>>>>>>>> Regards, >>>>>>>>>> Denis Lila. >>>>>>>>>> From james.graham at oracle.com Wed Jul 14 00:34:27 2010 From: james.graham at oracle.com (Jim Graham) Date: Tue, 13 Jul 2010 17:34:27 -0700 Subject: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines. In-Reply-To: <4C3D0427.2070200@oracle.com> References: <1076160120.60311278944522065.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> <4C3D0310.6040906@oracle.com> <4C3D0427.2070200@oracle.com> Message-ID: <4C3D0613.5050302@oracle.com> Argh. Not enough coffee. The variable is "joinSegment", but the comment mentions "internal joins". Either way, that code is only invoked when the upstream path iterator doesn't indicate that a join is needed. BTW, that code is currently not executed because the code upstream from this class is using a regular flattening path iterator and just calling "lineJoin" on every segment, whether it came from the original path or whether it was implicitly calculated from a flattened curve. It won't make a noticeable difference because most joins should work fine for a properly flattened curve, but the logic to always do a round join for implicit vertices will never be invoked the way we are doing it now... ...jim Jim Graham wrote: > Sorry, ignore this message. I was misinterpreting the field > "internalJoins" to mean "joins on the inside of the path (!ccw)". It > actually means "implicit joins in the middle of a flattened curve" and I > can see why those are always done round, so the code makes sense now > (naming of the variable notwithstanding)... > > ...jim > > Jim Graham wrote: >> Hi Denis, >> >> In looking through this code, I can see where it emits the proper join >> for ccw turns, but it looks like it just emits a round join for cw >> turns. Is that true? Doesn't this mean that a cw path will always >> have round joins? Or am I missing something? >> >> My expectation was that the code would emit the proper joins for both >> ccw and cw turns, but it would either place it in the outgoing or the >> return path depending on whether the turn was ccw, no? I don't see >> how that happens (but I haven't actually tested the code)... >> >> ...jim >> >> Denis Lila wrote: >>> Hello Jim. >>> >>> I'm terribly sorry about that. >>> I fixed it. Now the only highlighted lines in the webrev should be >>> lines I actually changed. >>> Please take another look at it. >>> (link is still the same: >>> http://icedtea.classpath.org/~dlila/webrevs/bezierRoundJoins/webrev/) >>> >>> Thanks, >>> Denis. >>> >>> PS: I added a new method: emitReverse, that goes through the reverse >>> list >>> and emits it. It's used in 2 methods which used to just do it >>> themselves. >>> >>> ----- "Jim Graham" wrote: >>> >>>> Hi Denis, >>>> >>>> You moved some code around without modifying it. This makes it hard >>>> to see what changed and what didn't and verify that the changes are >>>> accurate. Also, it adds diffs to the file that are unrelated to the >>>> fixing of the bug. Was there a practical reason for why you moved the >>>> >>>> code around? In particular I refer to: >>>> >>>> - the setup code that deals with "if (joinStyle == JOIN_MITER)" >>>> >>>> - the setOutput method - which not only moved, but lost its javadocs >>>> >>>> - computeMiter() and drawMiter() >>>> >>>> All of that code "appears" to be unchanged at first glance, but it is >>>> >>>> hard to tell from the webrevs. Also, a couple of stylistic issues: >>>> >>>> - you changed the declarations of isCCW which moved its arguments >>>> over, but the continuation lines aren't indented to match >>>> >>>> - The two "flavors" of emitCurveTo() should probably be next to each >>>> other (i.e. not have emitLineTo() between them or fall between the two >>>> >>>> flavors of emitLineTo()). >>>> >>>> In general I think the changes are OK, but I'm still reviewing them >>>> and the above issues sprung to mind on a first pass (and/or they are >>>> complicating the "contextual" review) so I thought I'd mention them >>>> earlier than later... >>>> >>>> ...jim >>>> >>>> Denis Lila wrote: >>>>> Hello. >>>>> >>>>> I just noticed that approximation of circle arcs by bezier curves >>>>> had already been implemented in ArcIterator by Jim Graham. >>>>> It computes the same control points as my solution, but it does so >>>>> more straightforwardly, without any rotation, so it is faster and >>>>> clearer. I have updated my solution to include this. >>>>> >>>>> The link remains the same. >>>>> >>>>> Thanks, >>>>> Denis. >>>>> >>>>> ----- "Denis Lila" wrote: >>>>> >>>>>> Hello. >>>>>> >>>>>> I think I got this working. The webrev is at: >>>>>> >>>> http://icedtea.classpath.org/~dlila/webrevs/bezierRoundJoins/webrev/ >>>>>> (NOTE: this is not a final version. I have included 2 versions >>>>>> of 2 methods. Only one set should be kept. See below for more.) >>>>>> >>>>>> My Changes: >>>>>> ----------- >>>>>> 1. >>>>>> I've made LineSink into an interface, rather than an abstract >>>>>> class, >>>>>> because all of its methods were abstract, so it makes more sense >>>> this >>>>>> way. >>>>>> >>>>>> 2. >>>>>> I've introduced a new interface that extends LineSink called >>>>>> PathSink, >>>>>> which allows the curveTo method, so there have been no changes to >>>>>> Stroker's public interface. When someone wants to create a Stroker >>>>>> with a PathSink output, it simply passes its constructor a >>>> PathSink, >>>>>> so the only changes outside of Stroker are in >>>> PiscesRenderingEngine, >>>>>> where the methods that handle Path2D and PathConsumer2D objects >>>>>> create nameless PathSinks instead of nameless LineSinks. >>>>>> >>>>>> 3. In Stroker: >>>>>> I've introduced a method called drawBezRoundJoin, analogous to >>>>>> computeRoundJoin. In drawRoundJoin I detect whether the output is >>>>>> a PathSink. If it is, I call drawBezRoundJoin, otherwise >>>> everything >>>>>> proceeds as it used to. drawBezRoundJoin uses computeBezierPoints >>>> to >>>>>> compute the control points. computeBezierPoints computes the >>>> control >>>>>> points >>>>>> for an arc of t radians, starting at angle a, with radius r >>>>>> by computing the control points of an arc of radius 1 of t radians >>>>>> that >>>>>> starts at angle -t/2. This is done by solving the equations >>>> resulting >>>>>> from the constraints that (P3-P2) and (P1-P0) must be parallel to >>>> the >>>>>> arc's tangents at P3 and P0 respectively, and that B(1/2)=(1,0). >>>> Then >>>>>> the >>>>>> points are scaled by r, and rotated counter clockwise by a+t/2. >>>>>> Then drawBezRoundJoin emits the curve. >>>>>> All this is done in a loop which is used to break up large >>>> arcs >>>>>> into >>>>>> more than one bezier curve. Through the iterations, the computed >>>>>> control >>>>>> points don't change - the only thing that changes is how they're >>>>>> rotated. >>>>>> So a good alternative approach would be to do the rotation >>>> outside >>>>>> of >>>>>> computeBezierPoints, and call computeBezierPoints once outside of >>>> the >>>>>> loop, >>>>>> so that the control points aren't recomputed unnecessarily. >>>>>> I have included code for this in the methods computeBezierPoints2 >>>> and >>>>>> drawBezRoundJoin2. This is my favoured approach, since it is >>>> almost >>>>>> as clear as the other one, and it is faster. >>>>>> >>>>>> There is one more optimization that can be made, and I've >>>> included >>>>>> it >>>>>> in a comment in line 703. >>>>>> >>>>>> I would very much appreciate any comments about any of this, >>>> but >>>>>> especially >>>>>> about the idea in line 703 and about >>>>>> computeBezierPoints2,drawBezRoundJoin2 >>>>>> vs. computeBezierPoints,drawBezRoundJoin. >>>>>> >>>>>> 4. >>>>>> Stroker used to only have lines, but now it can emit lines and >>>>>> curves, so >>>>>> I needed to change the format of reverse, to not only store >>>>>> coordinates, but >>>>>> to also tag them as belonging to a line or a curve. >>>>>> >>>>>> >>>>>> Other Approaches: >>>>>> ----------------- >>>>>> 1. >>>>>> Since what needed to be done was to alter the behaviour of one >>>>>> part of Stroker (drawing of round joins/caps) depending on the >>>> type >>>>>> of the output object, I thought it would be appropriate to make >>>>>> Stroker >>>>>> an abstract factory, turn the methods that draw round joins/caps >>>> into >>>>>> abstract ones, put all the common functionality in concrete >>>> methods >>>>>> in Stroker, and put all the join/cap drawing methods in overriding >>>>>> methods >>>>>> in concrete children of Stroker (instances of which were returned >>>>>> by static factories in Stroker). >>>>>> However, this was a bad approach, because the round cap/join >>>>>> drawing >>>>>> methods are private, so the only way to call them in Stroker's >>>>>> children >>>>>> from public methods in Stroker is to cast "this". So the code >>>> became >>>>>> littered with instanceof operators and casts. Not to mention that >>>>>> Stroker's >>>>>> public interface had to change, and some functionality was lost: >>>>>> Stroker >>>>>> allows changing it's output, so it is possible to use just 1 >>>> Stroker >>>>>> object >>>>>> to widen paths going to many different outputs (but not at the >>>> same >>>>>> time). >>>>>> This could no longer be supported with this approach. >>>>>> The way I did it has none of these weaknesses. >>>>>> >>>>>> 2. As for algorithms for the circle approximation, I considered 2: >>>>>> a. Compute the control points using the constraints that >>>>>> B(1/3)=A(a+t/3) >>>>>> and B(2/3) = A(a+2t/3) (i.e. make the arc and the bezier curve >>>>>> coincide at 2 >>>>>> evenly spaced points in the arc). This didn't work very well: some >>>> of >>>>>> the end >>>>>> caps looked more like triangles. >>>>>> b. Let B(1/2) = A(a+t/2), and B'(1/2) = A'(a+t/2). This worked >>>>>> better, but >>>>>> still not good enough. >>>>>> >>>>>> If anyone knows of any better ways to compute the control points, >>>>>> please let >>>>>> me know. >>>>>> >>>>>> I'm sorry for the length of this. I tried to make it shorter. >>>>>> >>>>>> Thank you very much, >>>>>> Denis. >>>>>> >>>>>> >>>>>> ----- "Jim Graham" wrote: >>>>>> >>>>>>> Hi Denis, >>>>>>> >>>>>>> Consider the case of using BasicStroke.createStrokedShape(). How >>>> do >>>>>>> you >>>>>>> know how many pixels the resulting path will occupy? You can't >>>>>> reduce >>>>>>> to concrete samples if you don't know the transform. >>>>>>> >>>>>>> So, for rendering, then you may be correct. But for cases where >>>> the >>>>>>> path is being asked for then beziers are the only responsible >>>>>>> solution... >>>>>>> >>>>>>> ...jim >>>>>>> >>>>>>> Denis Lila wrote: >>>>>>>> Hello Jim. >>>>>>>> >>>>>>>> I thought about checking the output and changing the behaviour >>>>>>>> depending on whether the output is a PC2D or a LineSink, but I >>>>>>> didn't >>>>>>>> implement it because I thought the point was to get rid of the >>>>>>> sampling >>>>>>>> at this stage. However, if performance is the issue, then I >>>> guess >>>>>>> I'll >>>>>>>> start working on it. >>>>>>>> >>>>>>>> Although, I wonder whether it is really worth it. I think most >>>>>> lines >>>>>>> drawn >>>>>>>> won't be wider than about 5 pixels, which means that the current >>>>>> way >>>>>>> will >>>>>>>> emit about 7 lines, so that's 14 coordinates. 2 bezier quarter >>>>>>> circles will >>>>>>>> require 12 coordinates. In terms of storage, there isn't much >>>>>>> difference, and >>>>>>>> for lines of width 4 or smaller the current method is more >>>>>>> efficient. >>>>>>>> I'm also guessing that it's harder for the rasterizer to deal >>>> with >>>>>>> bezier >>>>>>>> curves than with straight lines, so is it possible that >>>> replacing >>>>>>> the >>>>>>>> 3.14*lineWidth/2 lines generated by the current method with 2 >>>>>> bezier >>>>>>>> quarter circles isn't worth it (for small lineWidths)? >>>>>>>> >>>>>>>> Thanks, >>>>>>>> Denis. >>>>>>>> >>>>>>>> ----- "Jim Graham" wrote: >>>>>>>> >>>>>>>>> Sigh - that makes sense. One issue is that the resulting paths >>>>>> it >>>>>>>>> generates are much more "verbose" than they need to be. This >>>>>> would >>>>>>>>> generally mean that it takes far more storage than it would >>>>>>> otherwise >>>>>>>>> need - and it means that if the result needs to be transformed >>>>>> then >>>>>>> it >>>>>>>>> would take many more computations to transform each segment >>>> than >>>>>>> the >>>>>>>>> bezier. >>>>>>>>> >>>>>>>>> So, perhaps it would be worth having it check the type of the >>>>>>> output >>>>>>>>> and >>>>>>>>> do either a bezier or a bunch of lines depending on if it is a >>>>>> PC2D >>>>>>> or >>>>>>>>> a >>>>>>>>> LineSink? >>>>>>>>> >>>>>>>>> Also, it isn't really that difficult to for Renderer to include >>>>>>> its >>>>>>>>> own >>>>>>>>> Cubic/Quadratic flattening code, but it might involve more >>>>>>>>> calculations >>>>>>>>> than the round-cap code since it would have to be written for >>>>>>>>> arbitrary >>>>>>>>> beziers whereas if you know it is a quarter circle then it is >>>>>>> easier >>>>>>>>> to >>>>>>>>> know how far to subdivide... :-( >>>>>>>>> >>>>>>>>> ...jim >>>>>>>>> >>>>>>>>> Denis Lila wrote: >>>>>>>>>> So, I have been thinking about this, and I can't see a good >>>>>>>>>> way to do it that wouldn't involve heavy changes to Pisces. >>>>>>>>>> >>>>>>>>>> In order for Stroker to generate Bezier quarter circles, it >>>>>> would >>>>>>>>>> have to implement a curveTo method, which means Stroker should >>>>>>>>>> start implementing PathConsumer2D and instead of using a >>>>>> LineSink >>>>>>>>>> output it would have to use a PathConsumer2D output (either >>>>>> that, >>>>>>>>> or >>>>>>>>>> LineSink should include a curveTo method, but then there won't >>>>>>>>> really >>>>>>>>>> be any difference between a LineSink and a PathConsumer2D. By >>>>>> the >>>>>>>>> way, >>>>>>>>>> LineSink doesn't have any implemented methods, so why is it an >>>>>>>>> abstract >>>>>>>>>> class as opposed to an interface?) >>>>>>>>>> >>>>>>>>>> Stroker is used in 3 ways: >>>>>>>>>> 1. As an implementation of BasicStroke's createStrokedShape >>>>>>> method. >>>>>>>>> This >>>>>>>>>> uses a Path2D object as output. >>>>>>>>>> 2. As a way of feeding a PathConsumer2D without calling >>>>>>>>> createStrokedShape >>>>>>>>>> to generate an intermediate Shape. This uses a PathConsumer2D >>>>>>>>> output. >>>>>>>>>> 3. As a way of feeding lines to a Renderer object, which >>>>>>> generates >>>>>>>>> alpha >>>>>>>>>> tiles used for anti-aliasing that are fed to a cache and >>>>>>> extracted >>>>>>>>> as needed >>>>>>>>>> by an AATileGenerator. Obviously, Stroker's output here is a >>>>>>>>> Renderer. >>>>>>>>>> 1 and 2 aren't problems, because the underlying output objects >>>>>>>>> support >>>>>>>>>> Bezier curves. 3, however, doesn't, and it seems like >>>>>> implementing >>>>>>> a >>>>>>>>>> curveTo method for Renderer would be very difficult because >>>> the >>>>>>> way >>>>>>>>> it >>>>>>>>>> generates alpha tiles is by scanning the drawn edges with >>>>>>>>> horizontal >>>>>>>>>> scan lines, and for each scan line finding the x-intersections >>>>>> of >>>>>>>>> the scan >>>>>>>>>> lines and the edges. Then it determines the alpha values (I'm >>>>>> not >>>>>>>>> too sure >>>>>>>>>> how it does this). >>>>>>>>>> In order to implement Bezier curves in Renderer, we would have >>>>>> to >>>>>>>>> have >>>>>>>>>> a quick way of computing, for each scan line, all its >>>>>>> intersections >>>>>>>>> with >>>>>>>>>> however many Bezier curves are being drawn. >>>>>>>>>> >>>>>>>>>> I haven't given much thought to how this could be done, as I >>>> am >>>>>>> not >>>>>>>>> very >>>>>>>>>> familiar with Bezier curves, but it doesn't seem easy enough >>>> to >>>>>>>>> justify >>>>>>>>>> fixing such a small bug. >>>>>>>>>> >>>>>>>>>> ----- Original Message ----- >>>>>>>>>> From: "Jim Graham" >>>>>>>>>> To: "Denis Lila" >>>>>>>>>> Cc: 2d-dev at openjdk.java.net >>>>>>>>>> Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada >>>>>>>>> Eastern >>>>>>>>>> Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on >>>>>>>>> scaled lines. >>>>>>>>>> I don't understand - why do we generate sample points based on >>>>>>> the >>>>>>>>> size >>>>>>>>>> of the cap? Why not generate a pair of bezier quarter-circles >>>>>>> and >>>>>>>>> let >>>>>>>>>> the rasterizer deal with sampling? >>>>>>>>>> >>>>>>>>>> ...jim >>>>>>>>>> >>>>>>>>>> Denis Lila wrote: >>>>>>>>>>> Hello. >>>>>>>>>>> >>>>>>>>>>> I think I have a fix for this bug: >>>>>>>>>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506 >>>>>>>>>>> >>>>>>>>>>> Basically, the problem is that if there is a magnifying >>>> affine >>>>>>>>> transformation set on the graphics object and one tries to draw >>>> a >>>>>>> line >>>>>>>>> with small thickness and round end caps, the end caps appear >>>>>>> jagged. >>>>>>>>> This is because the computation of the length of the array that >>>>>>>>> contains the points on the "pen" with which the decoration is >>>>>>> drawn >>>>>>>>> does not take into account the size of the pen after the >>>>>>> magnification >>>>>>>>> of the affine transformation. So, for example, if the line >>>> length >>>>>>> was >>>>>>>>> set to 1, and the transformation was a scaling by 10, the >>>>>>> resulting >>>>>>>>> pen would have a diameter of 10, but only 3 pen points would be >>>>>>>>> computed (pi*untransformedLineWidth), so the end cap looks like >>>> a >>>>>>>>> triangle. >>>>>>>>>>> My fix computes an approximation of the circumference of the >>>>>>>>> transformed pen (which is an ellipse) and uses that as the >>>> number >>>>>>> of >>>>>>>>> points on the pen. The approximation is crude, but it is >>>> simple, >>>>>>>>> faster than alternatives >>>>>>>>> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can >>>>>>> say >>>>>>>>> from observations that it works fairly well. >>>>>>>>>>> There is also icing on the cake, in the form of slight >>>>>>> improvements >>>>>>>>> in performance when the scaling is a zooming out. Example: if >>>> the >>>>>>>>> original line width was 100, but g2d.scale(0.1,0.1) was set, >>>> then >>>>>>> the >>>>>>>>> resulting line would have a width of 10, so only ~31 points are >>>>>>>>> necessary for the decoration to look like a circle, but without >>>>>>> this >>>>>>>>> patch, about 314 points are computed (and a line is emitted to >>>>>>> each >>>>>>>>> one of them). >>>>>>>>>>> I appreciate any feedback. >>>>>>>>>>> >>>>>>>>>>> Regards, >>>>>>>>>>> Denis Lila. >>>>>>>>>>> From lana.steuck at oracle.com Wed Jul 14 20:01:51 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Wed, 14 Jul 2010 20:01:51 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d: Added tag jdk7-b100 for changeset b218a53ec7d3 Message-ID: <20100714200151.F254D479A0@hg.openjdk.java.net> Changeset: 4193eaf5f1b8 Author: mikejwre Date: 2010-07-09 19:18 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/rev/4193eaf5f1b8 Added tag jdk7-b100 for changeset b218a53ec7d3 ! .hgtags From lana.steuck at oracle.com Wed Jul 14 20:01:56 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Wed, 14 Jul 2010 20:01:56 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/corba: Added tag jdk7-b100 for changeset a56d734a1e97 Message-ID: <20100714200158.5BAFC479A1@hg.openjdk.java.net> Changeset: 86a239832646 Author: mikejwre Date: 2010-07-09 19:18 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/corba/rev/86a239832646 Added tag jdk7-b100 for changeset a56d734a1e97 ! .hgtags From lana.steuck at oracle.com Wed Jul 14 20:06:40 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Wed, 14 Jul 2010 20:06:40 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/hotspot: 3 new changesets Message-ID: <20100714200651.393CC479A2@hg.openjdk.java.net> Changeset: e13a5c0ed5e2 Author: prr Date: 2010-06-29 16:33 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/e13a5c0ed5e2 6964882: 32 bit JDK does not build on 64 bit Windows platforms Reviewed-by: ohair, valeriep ! make/windows/makefiles/defs.make Changeset: ad1977f08c4d Author: mikejwre Date: 2010-06-30 18:57 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/ad1977f08c4d Merge Changeset: 6c3a919105b6 Author: mikejwre Date: 2010-07-09 19:18 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/6c3a919105b6 Added tag jdk7-b100 for changeset ad1977f08c4d ! .hgtags From lana.steuck at oracle.com Wed Jul 14 20:11:25 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Wed, 14 Jul 2010 20:11:25 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/jaxp: Added tag jdk7-b100 for changeset d524be5ef62e Message-ID: <20100714201126.28CBE479A3@hg.openjdk.java.net> Changeset: 17f62a566a20 Author: mikejwre Date: 2010-07-09 19:18 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxp/rev/17f62a566a20 Added tag jdk7-b100 for changeset d524be5ef62e ! .hgtags From lana.steuck at oracle.com Wed Jul 14 20:11:30 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Wed, 14 Jul 2010 20:11:30 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/jaxws: Added tag jdk7-b100 for changeset bd26d0ce0c3c Message-ID: <20100714201130.41281479A4@hg.openjdk.java.net> Changeset: b55ce2744900 Author: mikejwre Date: 2010-07-09 19:18 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxws/rev/b55ce2744900 Added tag jdk7-b100 for changeset bd26d0ce0c3c ! .hgtags From lana.steuck at oracle.com Wed Jul 14 20:11:38 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Wed, 14 Jul 2010 20:11:38 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/jdk: 5 new changesets Message-ID: <20100714201357.C46C8479A5@hg.openjdk.java.net> Changeset: 861213cb02c3 Author: prr Date: 2010-06-29 16:34 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/861213cb02c3 6964882: 32 bit JDK does not build on 64 bit Windows platforms Reviewed-by: ohair, valeriep ! make/sun/security/mscapi/Makefile ! make/sun/security/pkcs11/Makefile Changeset: 511ddf6938ea Author: mikejwre Date: 2010-06-30 18:57 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/511ddf6938ea Merge Changeset: 820b4e843d51 Author: ohair Date: 2010-07-07 10:21 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/820b4e843d51 6967036: Need to fix links with // in Javadoc comments Reviewed-by: mchung ! src/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java ! src/share/classes/com/sun/security/auth/LdapPrincipal.java ! src/share/classes/com/sun/security/sasl/CramMD5Client.java ! src/share/classes/com/sun/security/sasl/CramMD5Server.java ! src/share/classes/com/sun/security/sasl/ExternalClient.java ! src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java ! src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java ! src/share/classes/java/net/URI.java ! src/share/classes/java/nio/charset/package.html ! src/share/classes/javax/management/remote/JMXServiceURL.java ! src/share/classes/javax/naming/ldap/LdapName.java ! src/share/classes/javax/naming/ldap/Rdn.java ! src/share/classes/javax/net/ssl/SSLContext.java ! src/share/classes/javax/print/DocFlavor.java ! src/share/classes/sun/awt/image/PNGImageDecoder.java Changeset: 93c4e6d14010 Author: mikejwre Date: 2010-07-09 19:18 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/93c4e6d14010 Added tag jdk7-b100 for changeset 820b4e843d51 ! .hgtags Changeset: 539528c5d395 Author: lana Date: 2010-07-14 09:12 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/539528c5d395 Merge From lana.steuck at oracle.com Wed Jul 14 20:18:03 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Wed, 14 Jul 2010 20:18:03 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/langtools: Added tag jdk7-b100 for changeset d1d7595fa824 Message-ID: <20100714201809.A9895479A6@hg.openjdk.java.net> Changeset: 20a8fe72ee7b Author: mikejwre Date: 2010-07-09 19:18 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/20a8fe72ee7b Added tag jdk7-b100 for changeset d1d7595fa824 ! .hgtags From dlila at redhat.com Thu Jul 15 23:49:18 2010 From: dlila at redhat.com (Denis Lila) Date: Thu, 15 Jul 2010 19:49:18 -0400 (EDT) Subject: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines. In-Reply-To: <1021424454.424771279237189972.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <316281134.425161279237758070.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hello Jim. Thanks for reviewing it. That part confused me too, so I skimmed through it and wrote drawBezRoundJoin to just compute the control points for an arc with centre at (x,y), going from (x+omx, y+omy) to (x+mx, y+my). I also took rev into account, but it's late and I don't remember exactly how right now. However, I tested it with many randomly generated polylines and other shapes, and it works. The caps are a bit funny looking for widths 10-17 inclusive (but strangely, not for <=9) but it's not because of how the control points are computed, because when, say, a (5,5) scale is used, everything looks good. I finished converting Stroker and Dasher to floating point arithmetic. I've been working on Renderer for the last 3 days, and I finished it (sort of) but a number of issues have come up. The most important is that I have been unable to make it work with the current algorithm for computing scanline crossings. What it does now is it goes through the drawing surface in strips, and computes crossings for edges in that strip. It does this to save memory. When I simply convert everything to doubles, dashed lines aren't rendered properly. Some angles are skewed, and there are small gaps in the solid segments. It works if I simply compute the crossings for every edge and forget about strips, but if a large GeneralPath is being rendered, this tends to consume too much memory. Regards, Denis. ----- "Jim Graham" wrote: > Argh. Not enough coffee. The variable is "joinSegment", but the > comment mentions "internal joins". Either way, that code is only > invoked when the upstream path iterator doesn't indicate that a join > is > needed. > > BTW, that code is currently not executed because the code upstream > from > this class is using a regular flattening path iterator and just > calling > "lineJoin" on every segment, whether it came from the original path or > > whether it was implicitly calculated from a flattened curve. It won't > > make a noticeable difference because most joins should work fine for a > > properly flattened curve, but the logic to always do a round join for > > implicit vertices will never be invoked the way we are doing it > now... > > ...jim > > Jim Graham wrote: > > Sorry, ignore this message. I was misinterpreting the field > > "internalJoins" to mean "joins on the inside of the path (!ccw)". > It > > actually means "implicit joins in the middle of a flattened curve" > and I > > can see why those are always done round, so the code makes sense now > > > (naming of the variable notwithstanding)... > > > > ...jim > > > > Jim Graham wrote: > >> Hi Denis, > >> > >> In looking through this code, I can see where it emits the proper > join > >> for ccw turns, but it looks like it just emits a round join for cw > > >> turns. Is that true? Doesn't this mean that a cw path will always > > >> have round joins? Or am I missing something? > >> > >> My expectation was that the code would emit the proper joins for > both > >> ccw and cw turns, but it would either place it in the outgoing or > the > >> return path depending on whether the turn was ccw, no? I don't see > > >> how that happens (but I haven't actually tested the code)... > >> > >> ...jim > >> > >> Denis Lila wrote: > >>> Hello Jim. > >>> > >>> I'm terribly sorry about that. > >>> I fixed it. Now the only highlighted lines in the webrev should > be > >>> lines I actually changed. > >>> Please take another look at it. > >>> (link is still the same: > >>> > http://icedtea.classpath.org/~dlila/webrevs/bezierRoundJoins/webrev/) > >>> > >>> Thanks, > >>> Denis. > >>> > >>> PS: I added a new method: emitReverse, that goes through the > reverse > >>> list > >>> and emits it. It's used in 2 methods which used to just do it > >>> themselves. > >>> > >>> ----- "Jim Graham" wrote: > >>> > >>>> Hi Denis, > >>>> > >>>> You moved some code around without modifying it. This makes it > hard > >>>> to see what changed and what didn't and verify that the changes > are > >>>> accurate. Also, it adds diffs to the file that are unrelated to > the > >>>> fixing of the bug. Was there a practical reason for why you > moved the > >>>> > >>>> code around? In particular I refer to: > >>>> > >>>> - the setup code that deals with "if (joinStyle == JOIN_MITER)" > >>>> > >>>> - the setOutput method - which not only moved, but lost its > javadocs > >>>> > >>>> - computeMiter() and drawMiter() > >>>> > >>>> All of that code "appears" to be unchanged at first glance, but > it is > >>>> > >>>> hard to tell from the webrevs. Also, a couple of stylistic > issues: > >>>> > >>>> - you changed the declarations of isCCW which moved its > arguments > >>>> over, but the continuation lines aren't indented to match > >>>> > >>>> - The two "flavors" of emitCurveTo() should probably be next to > each > >>>> other (i.e. not have emitLineTo() between them or fall between > the two > >>>> > >>>> flavors of emitLineTo()). > >>>> > >>>> In general I think the changes are OK, but I'm still reviewing > them > >>>> and the above issues sprung to mind on a first pass (and/or they > are > >>>> complicating the "contextual" review) so I thought I'd mention > them > >>>> earlier than later... > >>>> > >>>> ...jim > >>>> > >>>> Denis Lila wrote: > >>>>> Hello. > >>>>> > >>>>> I just noticed that approximation of circle arcs by bezier > curves > >>>>> had already been implemented in ArcIterator by Jim Graham. > >>>>> It computes the same control points as my solution, but it does > so > >>>>> more straightforwardly, without any rotation, so it is faster > and > >>>>> clearer. I have updated my solution to include this. > >>>>> > >>>>> The link remains the same. > >>>>> > >>>>> Thanks, > >>>>> Denis. > >>>>> > >>>>> ----- "Denis Lila" wrote: > >>>>> > >>>>>> Hello. > >>>>>> > >>>>>> I think I got this working. The webrev is at: > >>>>>> > >>>> > http://icedtea.classpath.org/~dlila/webrevs/bezierRoundJoins/webrev/ > >>>>>> (NOTE: this is not a final version. I have included 2 versions > >>>>>> of 2 methods. Only one set should be kept. See below for > more.) > >>>>>> > >>>>>> My Changes: > >>>>>> ----------- > >>>>>> 1. > >>>>>> I've made LineSink into an interface, rather than an > abstract > >>>>>> class, > >>>>>> because all of its methods were abstract, so it makes more > sense > >>>> this > >>>>>> way. > >>>>>> > >>>>>> 2. > >>>>>> I've introduced a new interface that extends LineSink > called > >>>>>> PathSink, > >>>>>> which allows the curveTo method, so there have been no changes > to > >>>>>> Stroker's public interface. When someone wants to create a > Stroker > >>>>>> with a PathSink output, it simply passes its constructor a > >>>> PathSink, > >>>>>> so the only changes outside of Stroker are in > >>>> PiscesRenderingEngine, > >>>>>> where the methods that handle Path2D and PathConsumer2D > objects > >>>>>> create nameless PathSinks instead of nameless LineSinks. > >>>>>> > >>>>>> 3. In Stroker: > >>>>>> I've introduced a method called drawBezRoundJoin, analogous > to > >>>>>> computeRoundJoin. In drawRoundJoin I detect whether the output > is > >>>>>> a PathSink. If it is, I call drawBezRoundJoin, otherwise > >>>> everything > >>>>>> proceeds as it used to. drawBezRoundJoin uses > computeBezierPoints > >>>> to > >>>>>> compute the control points. computeBezierPoints computes the > >>>> control > >>>>>> points > >>>>>> for an arc of t radians, starting at angle a, with radius r > >>>>>> by computing the control points of an arc of radius 1 of t > radians > >>>>>> that > >>>>>> starts at angle -t/2. This is done by solving the equations > >>>> resulting > >>>>>> from the constraints that (P3-P2) and (P1-P0) must be parallel > to > >>>> the > >>>>>> arc's tangents at P3 and P0 respectively, and that > B(1/2)=(1,0). > >>>> Then > >>>>>> the > >>>>>> points are scaled by r, and rotated counter clockwise by > a+t/2. > >>>>>> Then drawBezRoundJoin emits the curve. > >>>>>> All this is done in a loop which is used to break up large > >>>> arcs > >>>>>> into > >>>>>> more than one bezier curve. Through the iterations, the > computed > >>>>>> control > >>>>>> points don't change - the only thing that changes is how > they're > >>>>>> rotated. > >>>>>> So a good alternative approach would be to do the rotation > >>>> outside > >>>>>> of > >>>>>> computeBezierPoints, and call computeBezierPoints once outside > of > >>>> the > >>>>>> loop, > >>>>>> so that the control points aren't recomputed unnecessarily. > >>>>>> I have included code for this in the methods > computeBezierPoints2 > >>>> and > >>>>>> drawBezRoundJoin2. This is my favoured approach, since it is > >>>> almost > >>>>>> as clear as the other one, and it is faster. > >>>>>> > >>>>>> There is one more optimization that can be made, and I've > >>>> included > >>>>>> it > >>>>>> in a comment in line 703. > >>>>>> > >>>>>> I would very much appreciate any comments about any of > this, > >>>> but > >>>>>> especially > >>>>>> about the idea in line 703 and about > >>>>>> computeBezierPoints2,drawBezRoundJoin2 > >>>>>> vs. computeBezierPoints,drawBezRoundJoin. > >>>>>> > >>>>>> 4. > >>>>>> Stroker used to only have lines, but now it can emit lines > and > >>>>>> curves, so > >>>>>> I needed to change the format of reverse, to not only store > >>>>>> coordinates, but > >>>>>> to also tag them as belonging to a line or a curve. > >>>>>> > >>>>>> > >>>>>> Other Approaches: > >>>>>> ----------------- > >>>>>> 1. > >>>>>> Since what needed to be done was to alter the behaviour of > one > >>>>>> part of Stroker (drawing of round joins/caps) depending on the > >>>> type > >>>>>> of the output object, I thought it would be appropriate to > make > >>>>>> Stroker > >>>>>> an abstract factory, turn the methods that draw round > joins/caps > >>>> into > >>>>>> abstract ones, put all the common functionality in concrete > >>>> methods > >>>>>> in Stroker, and put all the join/cap drawing methods in > overriding > >>>>>> methods > >>>>>> in concrete children of Stroker (instances of which were > returned > >>>>>> by static factories in Stroker). > >>>>>> However, this was a bad approach, because the round > cap/join > >>>>>> drawing > >>>>>> methods are private, so the only way to call them in Stroker's > >>>>>> children > >>>>>> from public methods in Stroker is to cast "this". So the code > >>>> became > >>>>>> littered with instanceof operators and casts. Not to mention > that > >>>>>> Stroker's > >>>>>> public interface had to change, and some functionality was > lost: > >>>>>> Stroker > >>>>>> allows changing it's output, so it is possible to use just 1 > >>>> Stroker > >>>>>> object > >>>>>> to widen paths going to many different outputs (but not at the > >>>> same > >>>>>> time). > >>>>>> This could no longer be supported with this approach. > >>>>>> The way I did it has none of these weaknesses. > >>>>>> > >>>>>> 2. As for algorithms for the circle approximation, I considered > 2: > >>>>>> a. Compute the control points using the constraints that > >>>>>> B(1/3)=A(a+t/3) > >>>>>> and B(2/3) = A(a+2t/3) (i.e. make the arc and the bezier curve > >>>>>> coincide at 2 > >>>>>> evenly spaced points in the arc). This didn't work very well: > some > >>>> of > >>>>>> the end > >>>>>> caps looked more like triangles. > >>>>>> b. Let B(1/2) = A(a+t/2), and B'(1/2) = A'(a+t/2). This > worked > >>>>>> better, but > >>>>>> still not good enough. > >>>>>> > >>>>>> If anyone knows of any better ways to compute the control > points, > >>>>>> please let > >>>>>> me know. > >>>>>> > >>>>>> I'm sorry for the length of this. I tried to make it shorter. > >>>>>> > >>>>>> Thank you very much, > >>>>>> Denis. > >>>>>> > >>>>>> > >>>>>> ----- "Jim Graham" wrote: > >>>>>> > >>>>>>> Hi Denis, > >>>>>>> > >>>>>>> Consider the case of using BasicStroke.createStrokedShape(). > How > >>>> do > >>>>>>> you > >>>>>>> know how many pixels the resulting path will occupy? You > can't > >>>>>> reduce > >>>>>>> to concrete samples if you don't know the transform. > >>>>>>> > >>>>>>> So, for rendering, then you may be correct. But for cases > where > >>>> the > >>>>>>> path is being asked for then beziers are the only responsible > >>>>>>> solution... > >>>>>>> > >>>>>>> ...jim > >>>>>>> > >>>>>>> Denis Lila wrote: > >>>>>>>> Hello Jim. > >>>>>>>> > >>>>>>>> I thought about checking the output and changing the > behaviour > >>>>>>>> depending on whether the output is a PC2D or a LineSink, but > I > >>>>>>> didn't > >>>>>>>> implement it because I thought the point was to get rid of > the > >>>>>>> sampling > >>>>>>>> at this stage. However, if performance is the issue, then I > >>>> guess > >>>>>>> I'll > >>>>>>>> start working on it. > >>>>>>>> > >>>>>>>> Although, I wonder whether it is really worth it. I think > most > >>>>>> lines > >>>>>>> drawn > >>>>>>>> won't be wider than about 5 pixels, which means that the > current > >>>>>> way > >>>>>>> will > >>>>>>>> emit about 7 lines, so that's 14 coordinates. 2 bezier > quarter > >>>>>>> circles will > >>>>>>>> require 12 coordinates. In terms of storage, there isn't > much > >>>>>>> difference, and > >>>>>>>> for lines of width 4 or smaller the current method is more > >>>>>>> efficient. > >>>>>>>> I'm also guessing that it's harder for the rasterizer to > deal > >>>> with > >>>>>>> bezier > >>>>>>>> curves than with straight lines, so is it possible that > >>>> replacing > >>>>>>> the > >>>>>>>> 3.14*lineWidth/2 lines generated by the current method with > 2 > >>>>>> bezier > >>>>>>>> quarter circles isn't worth it (for small lineWidths)? > >>>>>>>> > >>>>>>>> Thanks, > >>>>>>>> Denis. > >>>>>>>> > >>>>>>>> ----- "Jim Graham" wrote: > >>>>>>>> > >>>>>>>>> Sigh - that makes sense. One issue is that the resulting > paths > >>>>>> it > >>>>>>>>> generates are much more "verbose" than they need to be. > This > >>>>>> would > >>>>>>>>> generally mean that it takes far more storage than it would > >>>>>>> otherwise > >>>>>>>>> need - and it means that if the result needs to be > transformed > >>>>>> then > >>>>>>> it > >>>>>>>>> would take many more computations to transform each segment > >>>> than > >>>>>>> the > >>>>>>>>> bezier. > >>>>>>>>> > >>>>>>>>> So, perhaps it would be worth having it check the type of > the > >>>>>>> output > >>>>>>>>> and > >>>>>>>>> do either a bezier or a bunch of lines depending on if it is > a > >>>>>> PC2D > >>>>>>> or > >>>>>>>>> a > >>>>>>>>> LineSink? > >>>>>>>>> > >>>>>>>>> Also, it isn't really that difficult to for Renderer to > include > >>>>>>> its > >>>>>>>>> own > >>>>>>>>> Cubic/Quadratic flattening code, but it might involve more > >>>>>>>>> calculations > >>>>>>>>> than the round-cap code since it would have to be written > for > >>>>>>>>> arbitrary > >>>>>>>>> beziers whereas if you know it is a quarter circle then it > is > >>>>>>> easier > >>>>>>>>> to > >>>>>>>>> know how far to subdivide... :-( > >>>>>>>>> > >>>>>>>>> ...jim > >>>>>>>>> > >>>>>>>>> Denis Lila wrote: > >>>>>>>>>> So, I have been thinking about this, and I can't see a > good > >>>>>>>>>> way to do it that wouldn't involve heavy changes to > Pisces. > >>>>>>>>>> > >>>>>>>>>> In order for Stroker to generate Bezier quarter circles, > it > >>>>>> would > >>>>>>>>>> have to implement a curveTo method, which means Stroker > should > >>>>>>>>>> start implementing PathConsumer2D and instead of using a > >>>>>> LineSink > >>>>>>>>>> output it would have to use a PathConsumer2D output > (either > >>>>>> that, > >>>>>>>>> or > >>>>>>>>>> LineSink should include a curveTo method, but then there > won't > >>>>>>>>> really > >>>>>>>>>> be any difference between a LineSink and a PathConsumer2D. > By > >>>>>> the > >>>>>>>>> way, > >>>>>>>>>> LineSink doesn't have any implemented methods, so why is it > an > >>>>>>>>> abstract > >>>>>>>>>> class as opposed to an interface?) > >>>>>>>>>> > >>>>>>>>>> Stroker is used in 3 ways: > >>>>>>>>>> 1. As an implementation of BasicStroke's > createStrokedShape > >>>>>>> method. > >>>>>>>>> This > >>>>>>>>>> uses a Path2D object as output. > >>>>>>>>>> 2. As a way of feeding a PathConsumer2D without calling > >>>>>>>>> createStrokedShape > >>>>>>>>>> to generate an intermediate Shape. This uses a > PathConsumer2D > >>>>>>>>> output. > >>>>>>>>>> 3. As a way of feeding lines to a Renderer object, which > >>>>>>> generates > >>>>>>>>> alpha > >>>>>>>>>> tiles used for anti-aliasing that are fed to a cache and > >>>>>>> extracted > >>>>>>>>> as needed > >>>>>>>>>> by an AATileGenerator. Obviously, Stroker's output here is > a > >>>>>>>>> Renderer. > >>>>>>>>>> 1 and 2 aren't problems, because the underlying output > objects > >>>>>>>>> support > >>>>>>>>>> Bezier curves. 3, however, doesn't, and it seems like > >>>>>> implementing > >>>>>>> a > >>>>>>>>>> curveTo method for Renderer would be very difficult > because > >>>> the > >>>>>>> way > >>>>>>>>> it > >>>>>>>>>> generates alpha tiles is by scanning the drawn edges with > >>>>>>>>> horizontal > >>>>>>>>>> scan lines, and for each scan line finding the > x-intersections > >>>>>> of > >>>>>>>>> the scan > >>>>>>>>>> lines and the edges. Then it determines the alpha values > (I'm > >>>>>> not > >>>>>>>>> too sure > >>>>>>>>>> how it does this). > >>>>>>>>>> In order to implement Bezier curves in Renderer, we would > have > >>>>>> to > >>>>>>>>> have > >>>>>>>>>> a quick way of computing, for each scan line, all its > >>>>>>> intersections > >>>>>>>>> with > >>>>>>>>>> however many Bezier curves are being drawn. > >>>>>>>>>> > >>>>>>>>>> I haven't given much thought to how this could be done, as > I > >>>> am > >>>>>>> not > >>>>>>>>> very > >>>>>>>>>> familiar with Bezier curves, but it doesn't seem easy > enough > >>>> to > >>>>>>>>> justify > >>>>>>>>>> fixing such a small bug. > >>>>>>>>>> > >>>>>>>>>> ----- Original Message ----- > >>>>>>>>>> From: "Jim Graham" > >>>>>>>>>> To: "Denis Lila" > >>>>>>>>>> Cc: 2d-dev at openjdk.java.net > >>>>>>>>>> Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 > US/Canada > >>>>>>>>> Eastern > >>>>>>>>>> Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps > on > >>>>>>>>> scaled lines. > >>>>>>>>>> I don't understand - why do we generate sample points based > on > >>>>>>> the > >>>>>>>>> size > >>>>>>>>>> of the cap? Why not generate a pair of bezier > quarter-circles > >>>>>>> and > >>>>>>>>> let > >>>>>>>>>> the rasterizer deal with sampling? > >>>>>>>>>> > >>>>>>>>>> ...jim > >>>>>>>>>> > >>>>>>>>>> Denis Lila wrote: > >>>>>>>>>>> Hello. > >>>>>>>>>>> > >>>>>>>>>>> I think I have a fix for this bug: > >>>>>>>>>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506 > >>>>>>>>>>> > >>>>>>>>>>> Basically, the problem is that if there is a magnifying > >>>> affine > >>>>>>>>> transformation set on the graphics object and one tries to > draw > >>>> a > >>>>>>> line > >>>>>>>>> with small thickness and round end caps, the end caps > appear > >>>>>>> jagged. > >>>>>>>>> This is because the computation of the length of the array > that > >>>>>>>>> contains the points on the "pen" with which the decoration > is > >>>>>>> drawn > >>>>>>>>> does not take into account the size of the pen after the > >>>>>>> magnification > >>>>>>>>> of the affine transformation. So, for example, if the line > >>>> length > >>>>>>> was > >>>>>>>>> set to 1, and the transformation was a scaling by 10, the > >>>>>>> resulting > >>>>>>>>> pen would have a diameter of 10, but only 3 pen points would > be > >>>>>>>>> computed (pi*untransformedLineWidth), so the end cap looks > like > >>>> a > >>>>>>>>> triangle. > >>>>>>>>>>> My fix computes an approximation of the circumference of > the > >>>>>>>>> transformed pen (which is an ellipse) and uses that as the > >>>> number > >>>>>>> of > >>>>>>>>> points on the pen. The approximation is crude, but it is > >>>> simple, > >>>>>>>>> faster than alternatives > >>>>>>>>> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I > can > >>>>>>> say > >>>>>>>>> from observations that it works fairly well. > >>>>>>>>>>> There is also icing on the cake, in the form of slight > >>>>>>> improvements > >>>>>>>>> in performance when the scaling is a zooming out. Example: > if > >>>> the > >>>>>>>>> original line width was 100, but g2d.scale(0.1,0.1) was > set, > >>>> then > >>>>>>> the > >>>>>>>>> resulting line would have a width of 10, so only ~31 points > are > >>>>>>>>> necessary for the decoration to look like a circle, but > without > >>>>>>> this > >>>>>>>>> patch, about 314 points are computed (and a line is emitted > to > >>>>>>> each > >>>>>>>>> one of them). > >>>>>>>>>>> I appreciate any feedback. > >>>>>>>>>>> > >>>>>>>>>>> Regards, > >>>>>>>>>>> Denis Lila. > >>>>>>>>>>> From dlila at redhat.com Tue Jul 20 00:10:03 2010 From: dlila at redhat.com (Denis Lila) Date: Mon, 19 Jul 2010 20:10:03 -0400 (EDT) Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <1182254711.610371279584459594.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <1727574358.610451279584603027.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hello again. I know I promised this last week, and I'm sorry it's late, but some nasty bugs popped up. The webrev is at: http://icedtea.classpath.org/~dlila/webrevs/floatingPoint/webrev/ I took this opportunity to make some changes that aren't related to floating point conversion, since this effort wasn't really directed at solving any one particular bug, but towards general refactoring and improving of Pisces (although it does solve a certain bug). 1. I removed some write-only variables in Renderer and Stroker. 2. I removed Dasher and Stroker's ability for the same object to be used with more than one output, transform, width, etc. Jim Graham said we should consider removing the no argument constructor for Dasher in a previous e-mail (which is equivalent to doing what I've done since you can't have this functionality without a no argument constructor and methods like setParameters and setOutput). I thought this was a good idea because this functionality was never being used, it clutters things up (among other things, it necessitates making the clients call setOutput and setParameters before the object can be used. This sort of thing is not a good idea since methods should be as self-contained as possible), and even if it is used, all it does is save us the creation of some objects. Since a huge number of these objects would never be needed and since they are not very expensive to create (Stroker is the biggest, and it has about 38 members), this is a premature optimization. 3. (2) allowed me to declare a whole bunch of members final (things like output, lineWidth, transformation matrix entries and anything that can't change). 4. I changed the crossing sorting algorithm in Renderer from bubble sort to insertion sort. Not a huge difference, but mine is shorter, it should perform slightly better, and I think it the algorithm is easier to understand. 5. I inserted comments on things which used to confuse me. Please check these - when reading code, there is nothing worse than a wrong explanation in a comment. 6. I removed the if(false &&... block in Renderer. I tried to make it work some time ago, but it was complicated and more trouble than it was worth - it would only be used when filling a rectangle, and not even a rectangle that was part of some path. The rectangle had to be the only thing being rendered. This is fast enough without being treated as a special case. I think that's it... As for testing: I tested this fairly thoroughly. I used dashed strokes, various affine transformations, lines longer than 2^16, and complicated GeneralPaths. Everything looks good. I also did some performance measurements. Everything is faster than it used to be, although AA rendering is still much slower than closed source java. One of the problems here is that when rendering large objects, the strips in Renderer:_endRendering will be small, and _endRenderer's complexity, not taking into account methods it calls, is O(numStrips*numEdges), because for every strip it has to go through what's left of the edge list. A better way to iterate through edges that are in a strip is needed. NOTE: I did not make changes (2) and (3) to Renderer.java because I don't have time today, and I wanted to put out something fairly polished as soon as possible. Also, I think Renderer needs quite a bit more refactoring than just that. In particular the way it stores and iterates through edges, scalines, and crossings needs to be improved. Right now it is too error-prone, and many variables have a far larger scope than they should. I would very much appreciate it if anyone could look over my changes, or comment on the last two paragraphs above. Thank you, Denis. ----- "Denis Lila" wrote: > Hello. > > And, I just finished it. At least it compiled successfully. I'm sure > there > are a few runtime bugs. I'll try to have a webrev out by today. > > Regards, > Denis. > > ----- "Jim Graham" wrote: > > > Hi Denis, > > > > float operations are pretty fast and they are usually done in a > > separate > > part of the processor so the compiler can schedule a lot of > > bookkeeping > > instructions to run in parallel with waiting for the results of the > FP > > > > instruction. In the end, they often end up being "free" if there > are > > > > enough bookkeeping instructions (branches, fetching data, etc.) in > > amongst the data. > > > > Given how many alternate instructions you are pointing out for the > > fixed > > point code it would be very likely that this would be a "win". > > > > The main reason that Pisces is implemented heavily in fixed point is > > that it was originally written for the mobile platform where there > are > > > > no FP instructions. We don't have to worry about that on the > desktop > > > > (any more). > > > > I strongly support you converting things to fp if you want to do > > it... > > > > ...jim > > > > On 7/12/2010 8:05 AM, Denis Lila wrote: > > > Hello. > > > > > > Is it ok if I do this? I already started working on it on Friday. > > > I think I should be done by tomorrow. > > > > > > But yes, I agree that we should convert to floating point. As for > > > performance, there's also the fact that right now we're trading > > > one double multiplication for 2 casts to long, 1 long > > multiplication, > > > 1 bit shift of a long, and 1 cast back to an int. I don't know > much > > > about how these are done in hardware, but it doesn't seem like > > they'd > > > be faster than the double multiplication. > > > > > > As for large coordinates, there's a bug report about it (one not > > > reported by me :) ) here: > > https://bugzilla.redhat.com/show_bug.cgi?id=597227 > > > I submitted a matching bug report on bugs.sun.com (ID 6967436), > but > > I > > > can't find it when I search for it. > > > > > > Denis. > > > > > > ----- "Jim Graham" wrote: > > > > > >> Sigh... > > >> > > >> Pisces could really stand to upgrade to floats/doubles > everywhere, > > for > > >> > > >> several reasons: > > >> > > >> - FPU ops are likely as fast if not faster on modern hardware due > > to > > >> parallel execution of FP instructions alongside regular > > instructions. > > >> > > >> - Don't have to worry about getting coordinates larger than 32K > (I > > >> don't > > >> think this is well tested, but I imagine that Pisces will not > deal > > >> with > > >> it very gracefully). > > >> > > >> - Lots of code is greatly simplified not having to deal with the > > >> semantics of how to do fixed point multiplies, divides, and > > >> conversions. > > >> > > >> I meant to do this during the original integration, but I wanted > > to > > >> get > > >> the task done as quickly as possible so that we could have an > open > > >> source alternative to the closed Ductus code so I left that task > > for a > > >> > > >> later update. But, now that a lot of work is being done on the > > code > > >> to > > >> fix it up, it might be better to do the float conversion now so > > that > > >> the > > >> maintenance is easier and before we end up creating a lot of new > > fixed > > >> > > >> point code. > > >> > > >> My plate is full right now, but hopefully I can interest someone > > else > > >> in > > >> doing a cleanup cycle? (Donning my Tom Sawyer hat... ;-) > > >> > > >> ...jim From james.graham at oracle.com Wed Jul 21 03:46:16 2010 From: james.graham at oracle.com (Jim Graham) Date: Tue, 20 Jul 2010 20:46:16 -0700 Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <1727574358.610451279584603027.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <1727574358.610451279584603027.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C466D88.9010801@oracle.com> Hi Denis, This is awesome! Thanks for doing this. I agree with all of your comments below. Here are some thoughts on the new code: Dasher.java: 91 - is there a reason to copy the dash array? Theoretically if this object were used in an arbitrary fashion it is good sense to protect against data changing out from under it, but in practice we only ever feed it the array that came from a BasicStroke object which was already protected from arbitrary changes and is copied every time we fetch it so this is one more unfortunately extra fetch that isn't needed in practice. (Ideally we'd instrument an extractor for BasicStroke so we could get the raw array without the defensive copy in getDashArray()...) 169 - if origLen reaches the end of the dash exactly (the "==" case) then shouldn't you flip the dashOn variable? That would happen if you drop through to the following code (i.e. change the test to just "<"), but it would require a bit more calculation. If you leave the phase equal to the dash size (which is what happens now in the "==" case) then the next time through the if will fail and you will end up with a second goTo to the same coordinates that the previous dash ended on before flipping the dashOn variable and circling back - which is a waste of a bunch of calculations. Or was there some bookkeeping issue that arose when the "==" case dropped through? PiscesRenderingEngine.java 248 - is the normalize parameter used yet? Not a complaint - I just didn't see it getting used and wanted to make sure I didn't miss something. 257-261 - both Stroker and Dasher grab the t4 values into local variables. Hotspot might cover up this sin if the T4 stays in the young generation, but for a long path the T4 may move into an older generation and take more to collect. Maybe it would be worth just passing in the 4 values to the Stroker and Dasher constructors rather than encapsulating them in a T4 that is immediately stripped and ignored? 367 - you left a stats printing call in here. Renderer.java: I note some confusion below over comparing subpixel values to pixel values. Perhaps a convention where all subpixel values would be in variables with "sub" in their name or something like that would make it more maintainable (and correct in the short term). 47,48 - any reason to move these fields around? (Not a complaint - just wondering if you had a reason.) 129 - note this could overflow, but I imagine that the bounds came from a device clip which means there would have to be some drawable created that was larger than MAX_INT/SUB_POS_XY. If that is true then it probably isn't worth worrying about, but a comment might help point that out. 157 - Personally I'd call close before I started working on the new data, but that's just my coding layout style. Also, does close() always do the "right thing" if no path has been created yet? For one thing it looks like it always results in a call to "lineTo" no matter what which I'm guessing "happens to" fall into the short-circuit for horizontal lines in lineTo, but I haven't verified it. In fact I think I see a problem in that firstOrientation is not set to 0 and so if you have 2 moveto's in a row then the second one will call close() and find that the orientations don't match and increment flips. That isn't a critical problem since flips is only used to allocate memory, but it would allocate more than needed in that case. (not to mention emitting unnecessary linetos) Suggestion - set firstOrientation to 0 in moveto and test for firstOrientation==0 in close() so that close() doesn't add any geometry to something that has no deflections yet. 171 - Aren't x0,y0 stored as subpix values? You would then be comparing a subpix value to a non-subpix value. Perhaps if the subpix calls are moved to the top of the function I think this should work OK? 194,197 - Shouldn't these be constants, or based on the SUB_POS_XY? ---- Warning: potential can of worms ---- BTW, I never traced this through to see why it was needed, but I've seen a lot of renderers get afraid of vertices on pixel boundaries for similar reasons, but most of them are wrong because they miss the fact that the last coordinate on a line should be ignored by the scanline counts because of the rule of "any pixel on a horizontal edge should be outside the path if the area right below it is outside". Basically, we fill from x0 up to but not including x1 and also from y0 up to but not including y1. Thus, only y0 would trigger a scanline increment and y1 would never do so. If the following segment immediately heads up then both of those segments would "end" on the same scanline and be ignored. If the following segment continues down then the first does not trigger a scanline crossing, but the second does. If we can make sure the bookkeeping is done that way in the rest of the Renderer then we can get rid of this fudge factor entirely. I discuss some of these changes below, but in the end, 5 or 6 methods would need their math updated to make this work right and I'm not sure if I've described it well enough for you to make all the needed changes. Perhaps this could be a follow-on project, but it would greatly simplify a lot of the code in here. ---- End can of worms ---- 216 - if you save the sx0,sy0 before subpix'ing them then you don't have to "unsubpix" them here. (Though you still need the subpix sy0 for line 209 - or you could just call subpix on it for that line and at least you'd save 1 call to sub/unsub). 236,237 - here is what I was talking about above (can of worms). minY and maxY should probably both be ceil'd and then maxY would be the first scanline "not" processed and then the problem above about double crossings at the scanlines wouldn't be an issue. 243 - "minY >= maxY" if the above is done (can of worms). 262 - "y < maxY" if the above is done (can of worms). 256,264 - casting to int is problematic. It truncates towards 0 which means negatives are ceil'd and positives are floor'd. It would be best to use floor here instead. On the other hand, if negative numbers are always "off the left side of the drawable" then this is moot. 317,318 - blech (can of worms) - looks like more math designed for the "minY up to and including maxY" approach - I far prefer the "minY up to, but not including maxY" approach as mentioned above. ;-) _endRendering(), setCrossingsExtents, computeCrossingsForEdge (already mentioned above), computeBounds, and renderStrip() would all need to be updated for that. How comfortable do you feel with that conversion? 597 - you deleted the call to arraycopy? D'oh! (Actually, Arrays.newSize() is faster than "allocate and copy" so it couldn't hurt to switch to it here. Also, expanding by 10% seems a little conservative for large edge lists. I'd rather see "double, but never more than 10*INIT_EDGES" or something like that. This may be more "limited memory on mobile" thinking here. 611 - (can of worms) "ceil >= ceil" if the above scanline crossing change is done. OK, enough for now on harping on the can of worms. 721 - Arrays.sort() Stroker.java - I didn't get to this file yet. I'm going to send these comments along so you can take a look at them and then review Stroker tomorrow... ...jim Denis Lila wrote: > Hello again. > > I know I promised this last week, and I'm sorry it's late, but some nasty > bugs popped up. The webrev is at: > http://icedtea.classpath.org/~dlila/webrevs/floatingPoint/webrev/ > > I took this opportunity to make some changes that aren't related to floating > point conversion, since this effort wasn't really directed at solving any one > particular bug, but towards general refactoring and improving of Pisces (although > it does solve a certain bug). > 1. > I removed some write-only variables in Renderer and Stroker. > > 2. > I removed Dasher and Stroker's ability for the same object to be used with > more than one output, transform, width, etc. Jim Graham said we should consider > removing the no argument constructor for Dasher in a previous e-mail (which > is equivalent to doing what I've done since you can't have this functionality > without a no argument constructor and methods like setParameters and setOutput). > I thought this was a good idea because this functionality was never being used, > it clutters things up (among other things, it necessitates making the clients > call setOutput and setParameters before the object can be used. This sort of > thing is not a good idea since methods should be as self-contained as possible), > and even if it is used, all it does is save us the creation of some objects. Since > a huge number of these objects would never be needed and since they are not > very expensive to create (Stroker is the biggest, and it has about 38 members), > this is a premature optimization. > > 3. > (2) allowed me to declare a whole bunch of members final (things like output, > lineWidth, transformation matrix entries and anything that can't change). > > 4. > I changed the crossing sorting algorithm in Renderer from bubble sort to > insertion sort. Not a huge difference, but mine is shorter, it should perform > slightly better, and I think it the algorithm is easier to understand. > > 5. > I inserted comments on things which used to confuse me. Please check these - > when reading code, there is nothing worse than a wrong explanation in a comment. > > 6. > I removed the if(false &&... block in Renderer. I tried to make it work some > time ago, but it was complicated and more trouble than it was worth - it would > only be used when filling a rectangle, and not even a rectangle that was part of > some path. The rectangle had to be the only thing being rendered. This is fast enough > without being treated as a special case. > > I think that's it... > As for testing: I tested this fairly thoroughly. I used dashed strokes, various > affine transformations, lines longer than 2^16, and complicated GeneralPaths. > Everything looks good. > > I also did some performance measurements. Everything is faster than it used to be, > although AA rendering is still much slower than closed source java. One of the > problems here is that when rendering large objects, the strips in Renderer:_endRendering > will be small, and _endRenderer's complexity, not taking into account methods it calls, > is O(numStrips*numEdges), because for every strip it has to go through what's left of the edge > list. A better way to iterate through edges that are in a strip is needed. > > NOTE: I did not make changes (2) and (3) to Renderer.java because I don't have time > today, and I wanted to put out something fairly polished as soon as possible. Also, > I think Renderer needs quite a bit more refactoring than just that. In particular the > way it stores and iterates through edges, scalines, and crossings needs to be improved. > Right now it is too error-prone, and many variables have a far larger scope than > they should. > > I would very much appreciate it if anyone could look over my changes, or comment > on the last two paragraphs above. > > Thank you, > Denis. > > ----- "Denis Lila" wrote: > >> Hello. >> >> And, I just finished it. At least it compiled successfully. I'm sure >> there >> are a few runtime bugs. I'll try to have a webrev out by today. >> >> Regards, >> Denis. >> >> ----- "Jim Graham" wrote: >> >>> Hi Denis, >>> >>> float operations are pretty fast and they are usually done in a >>> separate >>> part of the processor so the compiler can schedule a lot of >>> bookkeeping >>> instructions to run in parallel with waiting for the results of the >> FP >>> instruction. In the end, they often end up being "free" if there >> are >>> enough bookkeeping instructions (branches, fetching data, etc.) in >>> amongst the data. >>> >>> Given how many alternate instructions you are pointing out for the >>> fixed >>> point code it would be very likely that this would be a "win". >>> >>> The main reason that Pisces is implemented heavily in fixed point is >>> that it was originally written for the mobile platform where there >> are >>> no FP instructions. We don't have to worry about that on the >> desktop >>> (any more). >>> >>> I strongly support you converting things to fp if you want to do >>> it... >>> >>> ...jim >>> >>> On 7/12/2010 8:05 AM, Denis Lila wrote: >>>> Hello. >>>> >>>> Is it ok if I do this? I already started working on it on Friday. >>>> I think I should be done by tomorrow. >>>> >>>> But yes, I agree that we should convert to floating point. As for >>>> performance, there's also the fact that right now we're trading >>>> one double multiplication for 2 casts to long, 1 long >>> multiplication, >>>> 1 bit shift of a long, and 1 cast back to an int. I don't know >> much >>>> about how these are done in hardware, but it doesn't seem like >>> they'd >>>> be faster than the double multiplication. >>>> >>>> As for large coordinates, there's a bug report about it (one not >>>> reported by me :) ) here: >>> https://bugzilla.redhat.com/show_bug.cgi?id=597227 >>>> I submitted a matching bug report on bugs.sun.com (ID 6967436), >> but >>> I >>>> can't find it when I search for it. >>>> >>>> Denis. >>>> >>>> ----- "Jim Graham" wrote: >>>> >>>>> Sigh... >>>>> >>>>> Pisces could really stand to upgrade to floats/doubles >> everywhere, >>> for >>>>> several reasons: >>>>> >>>>> - FPU ops are likely as fast if not faster on modern hardware due >>> to >>>>> parallel execution of FP instructions alongside regular >>> instructions. >>>>> - Don't have to worry about getting coordinates larger than 32K >> (I >>>>> don't >>>>> think this is well tested, but I imagine that Pisces will not >> deal >>>>> with >>>>> it very gracefully). >>>>> >>>>> - Lots of code is greatly simplified not having to deal with the >>>>> semantics of how to do fixed point multiplies, divides, and >>>>> conversions. >>>>> >>>>> I meant to do this during the original integration, but I wanted >>> to >>>>> get >>>>> the task done as quickly as possible so that we could have an >> open >>>>> source alternative to the closed Ductus code so I left that task >>> for a >>>>> later update. But, now that a lot of work is being done on the >>> code >>>>> to >>>>> fix it up, it might be better to do the float conversion now so >>> that >>>>> the >>>>> maintenance is easier and before we end up creating a lot of new >>> fixed >>>>> point code. >>>>> >>>>> My plate is full right now, but hopefully I can interest someone >>> else >>>>> in >>>>> doing a cleanup cycle? (Donning my Tom Sawyer hat... ;-) >>>>> >>>>> ...jim From dlila at redhat.com Wed Jul 21 16:12:25 2010 From: dlila at redhat.com (Denis Lila) Date: Wed, 21 Jul 2010 12:12:25 -0400 (EDT) Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <1047706895.755771279728419235.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <2089377119.756191279728745826.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hello Jim. Thank you very much for taking the time to read through this. > 91 - is there a reason to copy the dash array? Theoretically if this > object were used in an arbitrary fashion it is good sense to protect > against data changing out from under it, but in practice we only ever > feed it the array that came from a BasicStroke object which was already > protected from arbitrary changes and is copied every time we fetch it so > this is one more unfortunately extra fetch that isn't needed in > practice. (Ideally we'd instrument an extractor for BasicStroke so we > could get the raw array without the defensive copy in > getDashArray()...) You're right, I suppose there isn't. It's just the way it was being done before, and it didn't occur to me to change it. I will, in the next version of this patch. > 169 - if origLen reaches the end of the dash exactly (the "==" case) > then shouldn't you flip the dashOn variable? That would happen if you > drop through to the following code (i.e. change the test to just "<"), > but it would require a bit more calculation. If you leave the phase > equal to the dash size (which is what happens now in the "==" case) then > the next time through the if will fail and you will end up with a second > goTo to the same coordinates that the previous dash ended on before > flipping the dashOn variable and circling back - which is a waste of a > bunch of calculations. Or was there some bookkeeping issue that arose > when the "==" case dropped through? You're right, I should. I can't just replace <= with == though, because the results will be the same: in the equal case origLen will become 0, and on the next iteration, the (origLen < dash[idx]-phase) will be true, and we will do a goTo(x1,y1), which is what we just did in the previous iteration (unless dash[idx] is 0, in which case the results will be even worse). The best solution to this is to just do a nested check for the == case. > 248 - is the normalize parameter used yet? Not a complaint - I just > didn't see it getting used and wanted to make sure I didn't miss > something. No, no yet. That's next week's work :) > 257-261 - both Stroker and Dasher grab the t4 values into local > variables. Hotspot might cover up this sin if the T4 stays in the young > generation, but for a long path the T4 may move into an older generation > and take more to collect. Maybe it would be worth just passing in the 4 > values to the Stroker and Dasher constructors rather than encapsulating > them in a T4 that is immediately stripped and ignored? Definitely. I never liked using the Transform4 class, and I almost removed it in this patch (but didn't because I didn't want to change that much). This is all the reason I need to remove it. Nothing ever uses Transform4 anyway, except to just unpack the matrix entries, so all we get from it is slightly reduced parameter lists. > 367 - you left a stats printing call in here. Oops... sorry about that. > I note some confusion below over comparing subpixel values to pixel > values. Perhaps a convention where all subpixel values would be in > variables with "sub" in their name or something like that would make it > more maintainable (and correct in the short term). That's a good idea. I'll do that. > 47,48 - any reason to move these fields around? (Not a complaint - just > wondering if you had a reason.) No, no reason. It happened accidentally - I made many changes to this file before settling on this, and at one point these variables weren't even there (replaced by Math.floor and Math.ceil calls that I thought did equivalent things to the various bit operations these are used for. After running into some bugs, I reintroduced them to keep the changes as small as possible and eliminate these as bug sources). > 129 - note this could overflow, but I imagine that the bounds came from > a device clip which means there would have to be some drawable created > that was larger than MAX_INT/SUB_POS_XY. If that is true then it > probably isn't worth worrying about, but a comment might help point that out. That's true. In fact, there are a few other places where ints could overflow if the clip passed in to Renderer is large enough. I'll try to comment on them all. > 157 - Personally I'd call close before I started working on the new > data, but that's just my coding layout style. Also, does close() always > do the "right thing" if no path has been created yet? For one thing it > looks like it always results in a call to "lineTo" no matter what which > I'm guessing "happens to" fall into the short-circuit for horizontal > lines in lineTo, but I haven't verified it. In fact I think I see a > problem in that firstOrientation is not set to 0 and so if you have 2 > moveto's in a row then the second one will call close() and find that > the orientations don't match and increment flips. That isn't a critical > problem since flips is only used to allocate memory, but it would > allocate more than needed in that case. (not to mention emitting > unnecessary linetos) Suggestion - set firstOrientation to 0 in moveto > and test for firstOrientation==0 in close() so that close() doesn't add > any geometry to something that has no deflections yet. Good idea - I'll do that. > 171 - Aren't x0,y0 stored as subpix values? You would then be comparing > a subpix value to a non-subpix value. Perhaps if the subpix calls are > moved to the top of the function I think this should work OK? That's true, they are. This is very puzzling. If a horizontal line is added, when the crossings for it are being computed, dxBydy should be NaN, and wouldn't an error be thrown when we try to cast to an int in the call to addCrossing? > 194,197 - Shouldn't these be constants, or based on the SUB_POS_XY? I suppose I should make a biasing constant. I don't think they should be based on SUB_POS_XY though, because the biasing is done to subpixel coordinates so there is no danger that if our supersampling is fine enough the biasing will make the coordinates jump over some scan line. > 216 - if you save the sx0,sy0 before subpix'ing them then you don't have > to "unsubpix" them here. (Though you still need the subpix sy0 for line > 209 - or you could just call subpix on it for that line and at least > you'd save 1 call to sub/unsub). Ok. I'll just save subpixed and unsubpixed versions of sx0, sy0. That should eliminate all sx0,sy0 related calls to tosubpix and topix except in moveTo. > 256,264 - casting to int is problematic. It truncates towards 0 which > means negatives are ceil'd and positives are floor'd. It would be best > to use floor here instead. On the other hand, if negative numbers are > always "off the left side of the drawable" then this is moot. That's why I left it at int casting. Do you still think I should change it to floor? > 597 - you deleted the call to arraycopy? D'oh! (Actually, > Arrays.newSize() is faster than "allocate and copy" so it couldn't hurt > to switch to it here. Also, expanding by 10% seems a little > conservative for large edge lists. I'd rather see "double, but never > more than 10*INIT_EDGES" or something like that. This may be more > "limited memory on mobile" thinking here. Ah, sorry about that. Before making the patch I was going through the files to remove any println calls used for debugging and things of that nature. I must have pushed dd one too many times. Speaking of which, is there a good way to edit and build openJDK from eclipse? Then this sort of embarrassing error could be avoided (including the printStats() call). As for Arrays.newSize()... I can't find it here: http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/Arrays.html Is this a new function added in 7? > 721 - Arrays.sort() I thought about using this, but I did some measurements, and it turns out that Arrays.sort() is a bit slower if the portion of the array being sorted has fewer than about 70 elements. On the other hand, when there are fewer than 70 elements the difference is negligible, and we only really need performance as "flips" becomes larger, in which case the difference between insertion sort and quicksort starts growing pretty quickly. Ok, I'll use Arrays.sort() > How comfortable do you feel with that conversion? I'll try to do it and include it in a new patch along with, hopefully, a better way to iterate through strips, and especially crossings. Right now all the iteration state is saved in global variables. This is... not good. I spent far too much time last week on bugs caused by this sort of thing. Ideally, any members that can't be put at the top of a class (like our edge and crossing data) should be put in classes of their own. Do you have any ideas about how to iterate through edges in a strip without going through every edge? I was thinking of maybe using some sort of tree to split the drawing surface, but I haven't given it much thought. Thanks again, Denis. ----- "Jim Graham" wrote: > Hi Denis, > > This is awesome! Thanks for doing this. > > I agree with all of your comments below. Here are some thoughts on > the > new code: > ---- Warning: potential can of worms ---- > BTW, I never traced this through to see why it was needed, but I've seen > a lot of renderers get afraid of vertices on pixel boundaries for > similar reasons, but most of them are wrong because they miss the fact > that the last coordinate on a line should be ignored by the scanline > counts because of the rule of "any pixel on a horizontal edge should be > outside the path if the area right below it is outside". Basically, we > fill from x0 up to but not including x1 and also from y0 up to but not > including y1. Thus, only y0 would trigger a scanline increment and y1 > would never do so. If the following segment immediately heads up then > both of those segments would "end" on the same scanline and be ignored. > If the following segment continues down then the first does not > trigger a scanline crossing, but the second does. If we can make sure > the bookkeeping is done that way in the rest of the Renderer then we can > get rid of this fudge factor entirely. I discuss some of these changes > below, but in the end, 5 or 6 methods would need their math updated to > make this work right and I'm not sure if I've described it well enough > for you to make all the needed changes. Perhaps this could be a > follow-on project, but it would greatly simplify a lot of the code in > here. > ---- End can of worms ---- > > > 236,237 - here is what I was talking about above (can of worms). minY > and maxY should probably both be ceil'd and then maxY would be the first > scanline "not" processed and then the problem above about double > crossings at the scanlines wouldn't be an issue. > > 243 - "minY >= maxY" if the above is done (can of worms). > > 262 - "y < maxY" if the above is done (can of worms). > > 317,318 - blech (can of worms) - looks like more math designed for the > "minY up to and including maxY" approach - I far prefer the "minY up to, > but not including maxY" approach as mentioned above. ;-) > _endRendering(), setCrossingsExtents, computeCrossingsForEdge (already > mentioned above), computeBounds, and renderStrip() would all need to be > updated for that. How comfortable do you feel with that conversion? > > 611 - (can of worms) "ceil >= ceil" if the above scanline crossing > change is done. OK, enough for now on harping on the can of worms. > > > Stroker.java > > - I didn't get to this file yet. I'm going to send these comments > along > so you can take a look at them and then review Stroker tomorrow... > > ...jim > > Denis Lila wrote: > > Hello again. > > > > I know I promised this last week, and I'm sorry it's late, but some > nasty > > bugs popped up. The webrev is at: > > http://icedtea.classpath.org/~dlila/webrevs/floatingPoint/webrev/ > > > > I took this opportunity to make some changes that aren't related to > floating > > point conversion, since this effort wasn't really directed at > solving any one > > particular bug, but towards general refactoring and improving of > Pisces (although > > it does solve a certain bug). > > 1. > > I removed some write-only variables in Renderer and Stroker. > > > > 2. > > I removed Dasher and Stroker's ability for the same object to be > used with > > more than one output, transform, width, etc. Jim Graham said we > should consider > > removing the no argument constructor for Dasher in a previous e-mail > (which > > is equivalent to doing what I've done since you can't have this > functionality > > without a no argument constructor and methods like setParameters and > setOutput). > > I thought this was a good idea because this functionality was never > being used, > > it clutters things up (among other things, it necessitates making > the clients > > call setOutput and setParameters before the object can be used. This > sort of > > thing is not a good idea since methods should be as self-contained > as possible), > > and even if it is used, all it does is save us the creation of some > objects. Since > > a huge number of these objects would never be needed and since they > are not > > very expensive to create (Stroker is the biggest, and it has about > 38 members), > > this is a premature optimization. > > > > 3. > > (2) allowed me to declare a whole bunch of members final (things > like output, > > lineWidth, transformation matrix entries and anything that can't > change). > > > > 4. > > I changed the crossing sorting algorithm in Renderer from bubble > sort to > > insertion sort. Not a huge difference, but mine is shorter, it > should perform > > slightly better, and I think it the algorithm is easier to > understand. > > > > 5. > > I inserted comments on things which used to confuse me. Please > check these - > > when reading code, there is nothing worse than a wrong explanation > in a comment. > > > > 6. > > I removed the if(false &&... block in Renderer. I tried to make > it work some > > time ago, but it was complicated and more trouble than it was worth > - it would > > only be used when filling a rectangle, and not even a rectangle that > was part of > > some path. The rectangle had to be the only thing being rendered. > This is fast enough > > without being treated as a special case. > > > > I think that's it... > > As for testing: I tested this fairly thoroughly. I used dashed > strokes, various > > affine transformations, lines longer than 2^16, and complicated > GeneralPaths. > > Everything looks good. > > > > I also did some performance measurements. Everything is faster than > it used to be, > > although AA rendering is still much slower than closed source java. > One of the > > problems here is that when rendering large objects, the strips in > Renderer:_endRendering > > will be small, and _endRenderer's complexity, not taking into > account methods it calls, > > is O(numStrips*numEdges), because for every strip it has to go > through what's left of the edge > > list. A better way to iterate through edges that are in a strip is > needed. > > > > NOTE: I did not make changes (2) and (3) to Renderer.java because I > don't have time > > today, and I wanted to put out something fairly polished as soon as > possible. Also, > > I think Renderer needs quite a bit more refactoring than just that. > In particular the > > way it stores and iterates through edges, scalines, and crossings > needs to be improved. > > Right now it is too error-prone, and many variables have a far > larger scope than > > they should. > > > > I would very much appreciate it if anyone could look over my > changes, or comment > > on the last two paragraphs above. > > > > Thank you, > > Denis. > > > > ----- "Denis Lila" wrote: > > > >> Hello. > >> > >> And, I just finished it. At least it compiled successfully. I'm > sure > >> there > >> are a few runtime bugs. I'll try to have a webrev out by today. > >> > >> Regards, > >> Denis. > >> > >> ----- "Jim Graham" wrote: > >> > >>> Hi Denis, > >>> > >>> float operations are pretty fast and they are usually done in a > >>> separate > >>> part of the processor so the compiler can schedule a lot of > >>> bookkeeping > >>> instructions to run in parallel with waiting for the results of > the > >> FP > >>> instruction. In the end, they often end up being "free" if there > >> are > >>> enough bookkeeping instructions (branches, fetching data, etc.) > in > >>> amongst the data. > >>> > >>> Given how many alternate instructions you are pointing out for > the > >>> fixed > >>> point code it would be very likely that this would be a "win". > >>> > >>> The main reason that Pisces is implemented heavily in fixed point > is > >>> that it was originally written for the mobile platform where > there > >> are > >>> no FP instructions. We don't have to worry about that on the > >> desktop > >>> (any more). > >>> > >>> I strongly support you converting things to fp if you want to do > >>> it... > >>> > >>> ...jim > >>> > >>> On 7/12/2010 8:05 AM, Denis Lila wrote: > >>>> Hello. > >>>> > >>>> Is it ok if I do this? I already started working on it on > Friday. > >>>> I think I should be done by tomorrow. > >>>> > >>>> But yes, I agree that we should convert to floating point. As > for > >>>> performance, there's also the fact that right now we're trading > >>>> one double multiplication for 2 casts to long, 1 long > >>> multiplication, > >>>> 1 bit shift of a long, and 1 cast back to an int. I don't know > >> much > >>>> about how these are done in hardware, but it doesn't seem like > >>> they'd > >>>> be faster than the double multiplication. > >>>> > >>>> As for large coordinates, there's a bug report about it (one not > >>>> reported by me :) ) here: > >>> https://bugzilla.redhat.com/show_bug.cgi?id=597227 > >>>> I submitted a matching bug report on bugs.sun.com (ID 6967436), > >> but > >>> I > >>>> can't find it when I search for it. > >>>> > >>>> Denis. > >>>> > >>>> ----- "Jim Graham" wrote: > >>>> > >>>>> Sigh... > >>>>> > >>>>> Pisces could really stand to upgrade to floats/doubles > >> everywhere, > >>> for > >>>>> several reasons: > >>>>> > >>>>> - FPU ops are likely as fast if not faster on modern hardware > due > >>> to > >>>>> parallel execution of FP instructions alongside regular > >>> instructions. > >>>>> - Don't have to worry about getting coordinates larger than 32K > >> (I > >>>>> don't > >>>>> think this is well tested, but I imagine that Pisces will not > >> deal > >>>>> with > >>>>> it very gracefully). > >>>>> > >>>>> - Lots of code is greatly simplified not having to deal with > the > >>>>> semantics of how to do fixed point multiplies, divides, and > >>>>> conversions. > >>>>> > >>>>> I meant to do this during the original integration, but I > wanted > >>> to > >>>>> get > >>>>> the task done as quickly as possible so that we could have an > >> open > >>>>> source alternative to the closed Ductus code so I left that > task > >>> for a > >>>>> later update. But, now that a lot of work is being done on the > >>> code > >>>>> to > >>>>> fix it up, it might be better to do the float conversion now so > >>> that > >>>>> the > >>>>> maintenance is easier and before we end up creating a lot of > new > >>> fixed > >>>>> point code. > >>>>> > >>>>> My plate is full right now, but hopefully I can interest > someone > >>> else > >>>>> in > >>>>> doing a cleanup cycle? (Donning my Tom Sawyer hat... ;-) > >>>>> > >>>>> ...jim From james.graham at oracle.com Wed Jul 21 17:55:20 2010 From: james.graham at oracle.com (Jim Graham) Date: Wed, 21 Jul 2010 10:55:20 -0700 Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <2089377119.756191279728745826.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <2089377119.756191279728745826.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C473488.3000901@oracle.com> Denis Lila wrote: > Hello Jim. > > Thank you very much for taking the time to read through this. > >> 169 - if origLen reaches the end of the dash exactly (the "==" case) > > You're right, I should. I can't just replace <= with == though, > because the results will be the same: in the equal case origLen will > become 0, and on the next iteration, the (origLen < dash[idx]-phase) will > be true, and we will do a goTo(x1,y1), which is what we just did in the > previous iteration (unless dash[idx] is 0, in which case the results > will be even worse). The best solution to this is to just do a nested > check for the == case. Ah, right - because there is no "break" when origLen becomes zero. Sounds like you're on it. >> 171 - Aren't x0,y0 stored as subpix values? You would then be comparing >> a subpix value to a non-subpix value. Perhaps if the subpix calls are >> moved to the top of the function I think this should work OK? > > That's true, they are. This is very puzzling. If a horizontal line is > added, when the crossings for it are being computed, dxBydy should be NaN, and > wouldn't an error be thrown when we try to cast to an int in the call to addCrossing? I'm not sure - I didn't trace it through very far - I just noted that the values were likely in different "resolutions". >> 194,197 - Shouldn't these be constants, or based on the SUB_POS_XY? > > I suppose I should make a biasing constant. I don't think they should be based > on SUB_POS_XY though, because the biasing is done to subpixel coordinates so > there is no danger that if our supersampling is fine enough the biasing will > make the coordinates jump over some scan line. I'm guessing you punted on my "can of worms" suggestion then. ;-) >> 216 - if you save the sx0,sy0 before subpix'ing them then you don't have >> to "unsubpix" them here. (Though you still need the subpix sy0 for line >> 209 - or you could just call subpix on it for that line and at least >> you'd save 1 call to sub/unsub). > > Ok. I'll just save subpixed and unsubpixed versions of sx0, sy0. That should > eliminate all sx0,sy0 related calls to tosubpix and topix except in moveTo. and lineTo. You may only need 3 of those values, though, if I remember my code reading well enough. >> 256,264 - casting to int is problematic. It truncates towards 0 which >> means negatives are ceil'd and positives are floor'd. It would be best >> to use floor here instead. On the other hand, if negative numbers are >> always "off the left side of the drawable" then this is moot. > > That's why I left it at int casting. Do you still think I should change it > to floor? If you mean floor, I think it best to use floor. Unless you can prove that negatives aren't really an issue and that the strange truncation on them won't be numerically a problem - but I don't think it is worth it for this code. > Speaking of which, is there a good way to edit and build openJDK from eclipse? > Then this sort of embarrassing error could be avoided (including the printStats() call). I don't use Eclipse, sorry. :-( > As for Arrays.newSize()... I can't find it here: > http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/Arrays.html > Is this a new function added in 7? Sorry, make that Arrays.copyOf(..., newSize). I tried to type the name from memory and got it wrong. >> 721 - Arrays.sort() > > I thought about using this, but I did some measurements, and it turns out that > Arrays.sort() is a bit slower if the portion of the array being sorted has fewer > than about 70 elements. I wonder what the typical number of elements is. Is this sorting crossings per line? Then simple primitives like circles should only have 2 per line, right? Is it worth testing for really small numbers of elements (much lower than 70) and doing a manual sort? Or am I misunderstanding what is being sorted there? >> How comfortable do you feel with that conversion? > > I'll try to do it and include it in a new patch along with, hopefully, a better way > to iterate through strips, and especially crossings. Right now all the iteration > state is saved in global variables. This is... not good. I spent far too much time last > week on bugs caused by this sort of thing. Ideally, any members that can't be put at > the top of a class (like our edge and crossing data) should be put in classes of their own. That sounds good, but also consider doing it in separate stages to reduce churn in the code reviewing (and you then have revs to go back and test which stage caused a probem if we find a bug later): - first get all on floats - then change strip management - then change to open coordinate intervals - (or vice versa) > Do you have any ideas about how to iterate through edges in a strip without going through > every edge? I was thinking of maybe using some sort of tree to split the drawing surface, > but I haven't given it much thought. If you look for something like the native code for sun/java2d/pipe/ShapeSpanIterator.c you will see the way I typically like to do edge setup and enumeration. That code uses the "half open interval" approach for both X and Y intervals. I then sort the edge list by "leading Y" and then move through the edges using the following manner (kind of like an inch worm eating the edges, maintaining a pointer to the beginning and end of an "active list" of edges that are in play at any given time by virtue of having their Y range intersect the current sampling Y). Note that I use an array of edges and then a parallel array of pointers into the edges so that I can sort just the pointers and avoid moving tons of edge data around. Also, later when I eliminate edges from the active list I just move their pointers into and out of view rather than having to copy the edge data. It is harder to do an array of pointers in Java, though - perhaps an array of indices? Here is some basic pseudocode: start with lo and hi pointing at index 0 in edge list. until edge list is exhausted { process edges between lo and hi (empty on first pass) scan from hi to lo and toss any edges that are exhausted (compacting remaining pointers towards hi) keep incrementing hi to accept any new edges coming into play process edges between lo and hi to increment to the next Y (note that new edges from previous step may not need any processing in this stage if their starting Y equals the next Y to be sampled) } Gradually lo and hi make their way through the list. The edges above hi are always sorted in order of when they may come into play as we move downward in Y. The edges between lo and hi are also usually kept sorted by their current X so that the stage that processes them into spans can just run through them. The edges below lo are usually random garbage because no care was taken during the "pruning" step to worry about what happens to the pointer table down there as lo is incremented (the algorithm only ever looks up the array of pointers). I hope that helps... ...jim From dlila at redhat.com Wed Jul 21 19:28:41 2010 From: dlila at redhat.com (Denis Lila) Date: Wed, 21 Jul 2010 15:28:41 -0400 (EDT) Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <630230326.771101279738744411.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <2006474692.773851279740521068.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> > >> 721 - Arrays.sort() > > > > I thought about using this, but I did some measurements, and it > turns out that > > Arrays.sort() is a bit slower if the portion of the array being > sorted has fewer > > than about 70 elements. > > I wonder what the typical number of elements is. Is this sorting > crossings per line? Then simple primitives like circles should only > have 2 per line, right? Is it worth testing for really small numbers of > elements (much lower than 70) and doing a manual sort? Or am I > misunderstanding what is being sorted there? That's correct. For every scan line, we're sorting the crossings on that scan line, so filling a circle would have 2 per line (drawing it would have 4 per line (for most lines, anyway)). I'm not sure if it's worth it. On one hand, the performance benefits would be minimal (because for small numbers of elements, just about anything will be fast and even if insertionSort is 200% faster than quicksort it won't make much difference). On the other hand, checking for, say crossingIndices[i] - start < 50 doesn't cost us much, and I already implemented and tested insertionSort. I think we should just use Arrays.sort all the time, just to keep the file as small as possible. > If you look for something like the native code for > sun/java2d/pipe/ShapeSpanIterator.c you will see the way I typically > like to do edge setup and enumeration. > > That code uses the "half open interval" approach for both X and Y > intervals. > > I then sort the edge list by "leading Y" and then move through the > edges > using the following manner (kind of like an inch worm eating the > edges, > maintaining a pointer to the beginning and end of an "active list" of > > edges that are in play at any given time by virtue of having their Y > range intersect the current sampling Y). Note that I use an array of > > edges and then a parallel array of pointers into the edges so that I > can > sort just the pointers and avoid moving tons of edge data around. > Also, > later when I eliminate edges from the active list I just move their > pointers into and out of view rather than having to copy the edge > data. > It is harder to do an array of pointers in Java, though - perhaps an > > array of indices? Here is some basic pseudocode: > > start with lo and hi pointing at index 0 in edge list. > until edge list is exhausted { > process edges between lo and hi (empty on first pass) > scan from hi to lo and toss any edges that are exhausted > (compacting remaining pointers towards hi) > keep incrementing hi to accept any new edges coming into play > process edges between lo and hi to increment to the next Y > (note that new edges from previous step may not > need any processing in this stage if their starting > Y equals the next Y to be sampled) > } > > Gradually lo and hi make their way through the list. The edges above > hi > are always sorted in order of when they may come into play as we move > > downward in Y. The edges between lo and hi are also usually kept > sorted > by their current X so that the stage that processes them into spans > can > just run through them. The edges below lo are usually random garbage > > because no care was taken during the "pruning" step to worry about > what > happens to the pointer table down there as lo is incremented (the > algorithm only ever looks up the array of pointers). > > I hope that helps... That does help. Thanks a lot, Denis. From dlila at redhat.com Mon Jul 26 21:18:34 2010 From: dlila at redhat.com (Denis Lila) Date: Mon, 26 Jul 2010 17:18:34 -0400 (EDT) Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <662426040.1058031280178903737.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <1700716646.1058491280179114719.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hello Jim. I implemented your "can of worms" idea. It works, and it got rid of the biasing. I wasn't able to send a webrev, but there are many changes and a side by side comparison would probably be useless, so I just attached the file. I hope this is ok. I also implemented a "better" iterating structure for the lines and the strips and crossings. I think it is better in every way, except performance. The new file is more than 200 lines smaller than the old one. The only members of Renderer are now the AA variables and the position variables (sx*, sy*, x*, y*). What I've done is I added an EdgeList class, which encapsulates all the edge related variables in the old Renderer. At first, I had an Edge class in addition to the EdgeList class, and while this was much nicer, it turned out to be too expensive (see last paragraph). I've also added a ScanLineIterator, so instead of _endRendering iterating through strips, and then calling renderStrip() which iterates through the scanlines in that strip, and then through the crossings in that scanline, what happens now is that _endRendering uses the Iterator to iterate through each scanline, get get its crossings and iterate through them to accumulate the alpha. By the way, a ScanLine is a type defined by an interface which exports methods for getting the y coord of the line, the number of crossings in it, the ith crossing, and a method for sorting its crossings. The class that implements ScanLine is ScanLineIterator itself. I made a ScanLine class, but I was afraid performance would suffer because of all the object creations (this turned out not to be an issue, after I switched to the current way, and remeasured things). I did not switch back because this is only slightly worse. As for performance: I wrote a simple program that tries to draw a dashed path that consists of about 160 dashed lines of width 1 and length 30000, going from the centre of the frame to some point. On my machine, this takes about 4.9 seconds in openjdk6, and 26 seconds using the attached file. Back when I was using the Edge class it took about 39 seconds. Everything without hundres of thousands of edges is not much slower I have not changed any of the algorithms. ScanLineIterator still goes through strips of the same size and computes crossings in every strip using the same method as before, so I don't know why it's so slow. It can't be because of anything happening in _endRendering, because there are only about 9000 scanlines and for each of them I've just added a few calls to one line getters (which used to be direct accesses into arrays). Thanks, Denis. ----- "Jim Graham" wrote: > Denis Lila wrote: > > Hello Jim. > > > > Thank you very much for taking the time to read through this. > > > >> 169 - if origLen reaches the end of the dash exactly (the "==" > case) > > > > You're right, I should. I can't just replace <= with == though, > > because the results will be the same: in the equal case origLen > will > > become 0, and on the next iteration, the (origLen < dash[idx]-phase) > will > > be true, and we will do a goTo(x1,y1), which is what we just did in > the > > previous iteration (unless dash[idx] is 0, in which case the results > > > will be even worse). The best solution to this is to just do a > nested > > check for the == case. > > Ah, right - because there is no "break" when origLen becomes zero. > Sounds like you're on it. > > >> 171 - Aren't x0,y0 stored as subpix values? You would then be > comparing > >> a subpix value to a non-subpix value. Perhaps if the subpix calls > are > >> moved to the top of the function I think this should work OK? > > > > That's true, they are. This is very puzzling. If a horizontal > line is > > added, when the crossings for it are being computed, dxBydy should > be NaN, and > > wouldn't an error be thrown when we try to cast to an int in the > call to addCrossing? > > I'm not sure - I didn't trace it through very far - I just noted that > > the values were likely in different "resolutions". > > >> 194,197 - Shouldn't these be constants, or based on the > SUB_POS_XY? > > > > I suppose I should make a biasing constant. I don't think they > should be based > > on SUB_POS_XY though, because the biasing is done to subpixel > coordinates so > > there is no danger that if our supersampling is fine enough the > biasing will > > make the coordinates jump over some scan line. > > I'm guessing you punted on my "can of worms" suggestion then. ;-) > > >> 216 - if you save the sx0,sy0 before subpix'ing them then you don't > have > >> to "unsubpix" them here. (Though you still need the subpix sy0 for > line > >> 209 - or you could just call subpix on it for that line and at > least > >> you'd save 1 call to sub/unsub). > > > > Ok. I'll just save subpixed and unsubpixed versions of sx0, sy0. > That should > > eliminate all sx0,sy0 related calls to tosubpix and topix except in > moveTo. > > and lineTo. You may only need 3 of those values, though, if I > remember > my code reading well enough. > > >> 256,264 - casting to int is problematic. It truncates towards 0 > which > >> means negatives are ceil'd and positives are floor'd. It would be > best > >> to use floor here instead. On the other hand, if negative numbers > are > >> always "off the left side of the drawable" then this is moot. > > > > That's why I left it at int casting. Do you still think I should > change it > > to floor? > > If you mean floor, I think it best to use floor. Unless you can prove > > that negatives aren't really an issue and that the strange truncation > on > them won't be numerically a problem - but I don't think it is worth it > > for this code. > > > Speaking of which, is there a good way to edit and build openJDK > from eclipse? > > Then this sort of embarrassing error could be avoided (including the > printStats() call). > > I don't use Eclipse, sorry. :-( > > > As for Arrays.newSize()... I can't find it here: > > > http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/Arrays.html > > Is this a new function added in 7? > > Sorry, make that Arrays.copyOf(..., newSize). I tried to type the > name > from memory and got it wrong. > > >> 721 - Arrays.sort() > > > > I thought about using this, but I did some measurements, and it > turns out that > > Arrays.sort() is a bit slower if the portion of the array being > sorted has fewer > > than about 70 elements. > > I wonder what the typical number of elements is. Is this sorting > crossings per line? Then simple primitives like circles should only > have 2 per line, right? Is it worth testing for really small numbers > of > elements (much lower than 70) and doing a manual sort? Or am I > misunderstanding what is being sorted there? > > >> How comfortable do you feel with that conversion? > > > > I'll try to do it and include it in a new patch along with, > hopefully, a better way > > to iterate through strips, and especially crossings. Right now all > the iteration > > state is saved in global variables. This is... not good. I spent far > too much time last > > week on bugs caused by this sort of thing. Ideally, any members that > can't be put at > > the top of a class (like our edge and crossing data) should be put > in classes of their own. > > That sounds good, but also consider doing it in separate stages to > reduce churn in the code reviewing (and you then have revs to go back > > and test which stage caused a probem if we find a bug later): > > - first get all on floats > - then change strip management > - then change to open coordinate intervals > - (or vice versa) > > > Do you have any ideas about how to iterate through edges in a strip > without going through > > every edge? I was thinking of maybe using some sort of tree to split > the drawing surface, > > but I haven't given it much thought. > > If you look for something like the native code for > sun/java2d/pipe/ShapeSpanIterator.c you will see the way I typically > like to do edge setup and enumeration. > > That code uses the "half open interval" approach for both X and Y > intervals. > > I then sort the edge list by "leading Y" and then move through the > edges > using the following manner (kind of like an inch worm eating the > edges, > maintaining a pointer to the beginning and end of an "active list" of > > edges that are in play at any given time by virtue of having their Y > range intersect the current sampling Y). Note that I use an array of > > edges and then a parallel array of pointers into the edges so that I > can > sort just the pointers and avoid moving tons of edge data around. > Also, > later when I eliminate edges from the active list I just move their > pointers into and out of view rather than having to copy the edge > data. > It is harder to do an array of pointers in Java, though - perhaps an > > array of indices? Here is some basic pseudocode: > > start with lo and hi pointing at index 0 in edge list. > until edge list is exhausted { > process edges between lo and hi (empty on first pass) > scan from hi to lo and toss any edges that are exhausted > (compacting remaining pointers towards hi) > keep incrementing hi to accept any new edges coming into play > process edges between lo and hi to increment to the next Y > (note that new edges from previous step may not > need any processing in this stage if their starting > Y equals the next Y to be sampled) > } > > Gradually lo and hi make their way through the list. The edges above > hi > are always sorted in order of when they may come into play as we move > > downward in Y. The edges between lo and hi are also usually kept > sorted > by their current X so that the stage that processes them into spans > can > just run through them. The edges below lo are usually random garbage > > because no care was taken during the "pruning" step to worry about > what > happens to the pointer table down there as lo is incremented (the > algorithm only ever looks up the array of pointers). > > I hope that helps... > > ...jim -------------- next part -------------- A non-text attachment was scrubbed... Name: Renderer.java Type: text/x-java Size: 21636 bytes Desc: not available URL: From dlila at redhat.com Tue Jul 27 01:05:43 2010 From: dlila at redhat.com (Denis Lila) Date: Mon, 26 Jul 2010 21:05:43 -0400 (EDT) Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <414334842.1067071280192536799.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <680063819.1067181280192743208.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hello again. This attachmet is a "can of worms" implementation without all the fancy (and slow) iteration. It also includes all of the other suggestions you sent in your first review of Dasher and Renderer last week (most importantly, the firstOrientation issue, horizontal lines filtering, and adding prefixes to variable names to make it clear whether they refer to pixels, or subpixels). Regards, Denis. ----- "Denis Lila" wrote: > Hello Jim. > > I implemented your "can of worms" idea. It works, and it got rid of > the biasing. > I wasn't able to send a webrev, but there are many changes and a side > by side > comparison would probably be useless, so I just attached the file. I > hope this is > ok. > > I also implemented a "better" iterating structure for the lines and > the > strips and crossings. I think it is better in every way, except > performance. > The new file is more than 200 lines smaller than the old one. The only > members of Renderer are now the AA variables and the position > variables > (sx*, sy*, x*, y*). > What I've done is I added an EdgeList class, which encapsulates all > the edge > related variables in the old Renderer. At first, I had an Edge class > in addition > to the EdgeList class, and while this was much nicer, it turned out to > be too > expensive (see last paragraph). > I've also added a ScanLineIterator, so instead of _endRendering > iterating > through strips, and then calling renderStrip() which iterates through > the > scanlines in that strip, and then through the crossings in that > scanline, > what happens now is that _endRendering uses the Iterator to > iterate through each scanline, get get its crossings and iterate > through them > to accumulate the alpha. By the way, a ScanLine is a type defined by > an > interface which exports methods for getting the y coord of the line, > the > number of crossings in it, the ith crossing, and a method for sorting > its crossings. > The class that implements ScanLine is ScanLineIterator itself. I made > a > ScanLine class, but I was afraid performance would suffer because of > all the > object creations (this turned out not to be an issue, after I switched > to the > current way, and remeasured things). I did not switch back because > this is > only slightly worse. > > As for performance: I wrote a simple program that tries to draw a > dashed path > that consists of about 160 dashed lines of width 1 and length 30000, > going > from the centre of the frame to some point. On my machine, this takes > about 4.9 > seconds in openjdk6, and 26 seconds using the attached file. Back when > I was using > the Edge class it took about 39 seconds. Everything without hundres of > thousands of > edges is not much slower > I have not changed any of the algorithms. ScanLineIterator still goes > through > strips of the same size and computes crossings in every strip using > the same > method as before, so I don't know why it's so slow. It can't be > because of anything > happening in _endRendering, because there are only about 9000 > scanlines and for each > of them I've just added a few calls to one line getters (which used to > be direct > accesses into arrays). > > Thanks, > Denis. > > ----- "Jim Graham" wrote: > > > Denis Lila wrote: > > > Hello Jim. > > > > > > Thank you very much for taking the time to read through this. > > > > > >> 169 - if origLen reaches the end of the dash exactly (the "==" > > case) > > > > > > You're right, I should. I can't just replace <= with == > though, > > > because the results will be the same: in the equal case origLen > > will > > > become 0, and on the next iteration, the (origLen < > dash[idx]-phase) > > will > > > be true, and we will do a goTo(x1,y1), which is what we just did > in > > the > > > previous iteration (unless dash[idx] is 0, in which case the > results > > > > > will be even worse). The best solution to this is to just do a > > nested > > > check for the == case. > > > > Ah, right - because there is no "break" when origLen becomes zero. > > Sounds like you're on it. > > > > >> 171 - Aren't x0,y0 stored as subpix values? You would then be > > comparing > > >> a subpix value to a non-subpix value. Perhaps if the subpix > calls > > are > > >> moved to the top of the function I think this should work OK? > > > > > > That's true, they are. This is very puzzling. If a horizontal > > line is > > > added, when the crossings for it are being computed, dxBydy should > > be NaN, and > > > wouldn't an error be thrown when we try to cast to an int in the > > call to addCrossing? > > > > I'm not sure - I didn't trace it through very far - I just noted > that > > > > the values were likely in different "resolutions". > > > > >> 194,197 - Shouldn't these be constants, or based on the > > SUB_POS_XY? > > > > > > I suppose I should make a biasing constant. I don't think they > > should be based > > > on SUB_POS_XY though, because the biasing is done to subpixel > > coordinates so > > > there is no danger that if our supersampling is fine enough the > > biasing will > > > make the coordinates jump over some scan line. > > > > I'm guessing you punted on my "can of worms" suggestion then. ;-) > > > > >> 216 - if you save the sx0,sy0 before subpix'ing them then you > don't > > have > > >> to "unsubpix" them here. (Though you still need the subpix sy0 > for > > line > > >> 209 - or you could just call subpix on it for that line and at > > least > > >> you'd save 1 call to sub/unsub). > > > > > > Ok. I'll just save subpixed and unsubpixed versions of sx0, > sy0. > > That should > > > eliminate all sx0,sy0 related calls to tosubpix and topix except > in > > moveTo. > > > > and lineTo. You may only need 3 of those values, though, if I > > remember > > my code reading well enough. > > > > >> 256,264 - casting to int is problematic. It truncates towards 0 > > which > > >> means negatives are ceil'd and positives are floor'd. It would > be > > best > > >> to use floor here instead. On the other hand, if negative > numbers > > are > > >> always "off the left side of the drawable" then this is moot. > > > > > > That's why I left it at int casting. Do you still think I > should > > change it > > > to floor? > > > > If you mean floor, I think it best to use floor. Unless you can > prove > > > > that negatives aren't really an issue and that the strange > truncation > > on > > them won't be numerically a problem - but I don't think it is worth > it > > > > for this code. > > > > > Speaking of which, is there a good way to edit and build openJDK > > from eclipse? > > > Then this sort of embarrassing error could be avoided (including > the > > printStats() call). > > > > I don't use Eclipse, sorry. :-( > > > > > As for Arrays.newSize()... I can't find it here: > > > > > > http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/Arrays.html > > > Is this a new function added in 7? > > > > Sorry, make that Arrays.copyOf(..., newSize). I tried to type the > > name > > from memory and got it wrong. > > > > >> 721 - Arrays.sort() > > > > > > I thought about using this, but I did some measurements, and > it > > turns out that > > > Arrays.sort() is a bit slower if the portion of the array being > > sorted has fewer > > > than about 70 elements. > > > > I wonder what the typical number of elements is. Is this sorting > > crossings per line? Then simple primitives like circles should only > > have 2 per line, right? Is it worth testing for really small > numbers > > of > > elements (much lower than 70) and doing a manual sort? Or am I > > misunderstanding what is being sorted there? > > > > >> How comfortable do you feel with that conversion? > > > > > > I'll try to do it and include it in a new patch along with, > > hopefully, a better way > > > to iterate through strips, and especially crossings. Right now all > > the iteration > > > state is saved in global variables. This is... not good. I spent > far > > too much time last > > > week on bugs caused by this sort of thing. Ideally, any members > that > > can't be put at > > > the top of a class (like our edge and crossing data) should be put > > in classes of their own. > > > > That sounds good, but also consider doing it in separate stages to > > reduce churn in the code reviewing (and you then have revs to go > back > > > > and test which stage caused a probem if we find a bug later): > > > > - first get all on floats > > - then change strip management > > - then change to open coordinate intervals > > - (or vice versa) > > > > > Do you have any ideas about how to iterate through edges in a > strip > > without going through > > > every edge? I was thinking of maybe using some sort of tree to > split > > the drawing surface, > > > but I haven't given it much thought. > > > > If you look for something like the native code for > > sun/java2d/pipe/ShapeSpanIterator.c you will see the way I typically > > like to do edge setup and enumeration. > > > > That code uses the "half open interval" approach for both X and Y > > intervals. > > > > I then sort the edge list by "leading Y" and then move through the > > edges > > using the following manner (kind of like an inch worm eating the > > edges, > > maintaining a pointer to the beginning and end of an "active list" > of > > > > edges that are in play at any given time by virtue of having their Y > > range intersect the current sampling Y). Note that I use an array > of > > > > edges and then a parallel array of pointers into the edges so that I > > can > > sort just the pointers and avoid moving tons of edge data around. > > Also, > > later when I eliminate edges from the active list I just move their > > pointers into and out of view rather than having to copy the edge > > data. > > It is harder to do an array of pointers in Java, though - perhaps > an > > > > array of indices? Here is some basic pseudocode: > > > > start with lo and hi pointing at index 0 in edge list. > > until edge list is exhausted { > > process edges between lo and hi (empty on first pass) > > scan from hi to lo and toss any edges that are exhausted > > (compacting remaining pointers towards hi) > > keep incrementing hi to accept any new edges coming into play > > process edges between lo and hi to increment to the next Y > > (note that new edges from previous step may not > > need any processing in this stage if their starting > > Y equals the next Y to be sampled) > > } > > > > Gradually lo and hi make their way through the list. The edges > above > > hi > > are always sorted in order of when they may come into play as we > move > > > > downward in Y. The edges between lo and hi are also usually kept > > sorted > > by their current X so that the stage that processes them into spans > > can > > just run through them. The edges below lo are usually random > garbage > > > > because no care was taken during the "pruning" step to worry about > > what > > happens to the pointer table down there as lo is incremented (the > > algorithm only ever looks up the array of pointers). > > > > I hope that helps... > > > > ...jim -------------- next part -------------- A non-text attachment was scrubbed... Name: Renderer.java Type: text/x-java Size: 24859 bytes Desc: not available URL: From james.graham at oracle.com Tue Jul 27 23:20:13 2010 From: james.graham at oracle.com (Jim Graham) Date: Tue, 27 Jul 2010 16:20:13 -0700 Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <680063819.1067181280192743208.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <680063819.1067181280192743208.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C4F69AD.7050605@oracle.com> Hi Denis, I'll try to get through both versions and see if I can find anything that was hurting performance with your EdgeLists. I'm guessing that this version was created because of the performance issues you found with the EdgeList version? Does this perform more closely to the existing code than the EdgeList version? ...jim Denis Lila wrote: > Hello again. > > This attachmet is a "can of worms" implementation without all the fancy (and slow) > iteration. It also includes all of the other suggestions you sent in your first > review of Dasher and Renderer last week (most importantly, the firstOrientation > issue, horizontal lines filtering, and adding prefixes to variable names to make > it clear whether they refer to pixels, or subpixels). > > Regards, > Denis. > > ----- "Denis Lila" wrote: > >> Hello Jim. >> >> I implemented your "can of worms" idea. It works, and it got rid of >> the biasing. >> I wasn't able to send a webrev, but there are many changes and a side >> by side >> comparison would probably be useless, so I just attached the file. I >> hope this is >> ok. >> >> I also implemented a "better" iterating structure for the lines and >> the >> strips and crossings. I think it is better in every way, except >> performance. >> The new file is more than 200 lines smaller than the old one. The only >> members of Renderer are now the AA variables and the position >> variables >> (sx*, sy*, x*, y*). >> What I've done is I added an EdgeList class, which encapsulates all >> the edge >> related variables in the old Renderer. At first, I had an Edge class >> in addition >> to the EdgeList class, and while this was much nicer, it turned out to >> be too >> expensive (see last paragraph). >> I've also added a ScanLineIterator, so instead of _endRendering >> iterating >> through strips, and then calling renderStrip() which iterates through >> the >> scanlines in that strip, and then through the crossings in that >> scanline, >> what happens now is that _endRendering uses the Iterator to >> iterate through each scanline, get get its crossings and iterate >> through them >> to accumulate the alpha. By the way, a ScanLine is a type defined by >> an >> interface which exports methods for getting the y coord of the line, >> the >> number of crossings in it, the ith crossing, and a method for sorting >> its crossings. >> The class that implements ScanLine is ScanLineIterator itself. I made >> a >> ScanLine class, but I was afraid performance would suffer because of >> all the >> object creations (this turned out not to be an issue, after I switched >> to the >> current way, and remeasured things). I did not switch back because >> this is >> only slightly worse. >> >> As for performance: I wrote a simple program that tries to draw a >> dashed path >> that consists of about 160 dashed lines of width 1 and length 30000, >> going >> from the centre of the frame to some point. On my machine, this takes >> about 4.9 >> seconds in openjdk6, and 26 seconds using the attached file. Back when >> I was using >> the Edge class it took about 39 seconds. Everything without hundres of >> thousands of >> edges is not much slower >> I have not changed any of the algorithms. ScanLineIterator still goes >> through >> strips of the same size and computes crossings in every strip using >> the same >> method as before, so I don't know why it's so slow. It can't be >> because of anything >> happening in _endRendering, because there are only about 9000 >> scanlines and for each >> of them I've just added a few calls to one line getters (which used to >> be direct >> accesses into arrays). >> >> Thanks, >> Denis. >> >> ----- "Jim Graham" wrote: >> >>> Denis Lila wrote: >>>> Hello Jim. >>>> >>>> Thank you very much for taking the time to read through this. >>>> >>>>> 169 - if origLen reaches the end of the dash exactly (the "==" >>> case) >>>> You're right, I should. I can't just replace <= with == >> though, >>>> because the results will be the same: in the equal case origLen >>> will >>>> become 0, and on the next iteration, the (origLen < >> dash[idx]-phase) >>> will >>>> be true, and we will do a goTo(x1,y1), which is what we just did >> in >>> the >>>> previous iteration (unless dash[idx] is 0, in which case the >> results >>>> will be even worse). The best solution to this is to just do a >>> nested >>>> check for the == case. >>> Ah, right - because there is no "break" when origLen becomes zero. >>> Sounds like you're on it. >>> >>>>> 171 - Aren't x0,y0 stored as subpix values? You would then be >>> comparing >>>>> a subpix value to a non-subpix value. Perhaps if the subpix >> calls >>> are >>>>> moved to the top of the function I think this should work OK? >>>> That's true, they are. This is very puzzling. If a horizontal >>> line is >>>> added, when the crossings for it are being computed, dxBydy should >>> be NaN, and >>>> wouldn't an error be thrown when we try to cast to an int in the >>> call to addCrossing? >>> >>> I'm not sure - I didn't trace it through very far - I just noted >> that >>> the values were likely in different "resolutions". >>> >>>>> 194,197 - Shouldn't these be constants, or based on the >>> SUB_POS_XY? >>>> I suppose I should make a biasing constant. I don't think they >>> should be based >>>> on SUB_POS_XY though, because the biasing is done to subpixel >>> coordinates so >>>> there is no danger that if our supersampling is fine enough the >>> biasing will >>>> make the coordinates jump over some scan line. >>> I'm guessing you punted on my "can of worms" suggestion then. ;-) >>> >>>>> 216 - if you save the sx0,sy0 before subpix'ing them then you >> don't >>> have >>>>> to "unsubpix" them here. (Though you still need the subpix sy0 >> for >>> line >>>>> 209 - or you could just call subpix on it for that line and at >>> least >>>>> you'd save 1 call to sub/unsub). >>>> Ok. I'll just save subpixed and unsubpixed versions of sx0, >> sy0. >>> That should >>>> eliminate all sx0,sy0 related calls to tosubpix and topix except >> in >>> moveTo. >>> >>> and lineTo. You may only need 3 of those values, though, if I >>> remember >>> my code reading well enough. >>> >>>>> 256,264 - casting to int is problematic. It truncates towards 0 >>> which >>>>> means negatives are ceil'd and positives are floor'd. It would >> be >>> best >>>>> to use floor here instead. On the other hand, if negative >> numbers >>> are >>>>> always "off the left side of the drawable" then this is moot. >>>> That's why I left it at int casting. Do you still think I >> should >>> change it >>>> to floor? >>> If you mean floor, I think it best to use floor. Unless you can >> prove >>> that negatives aren't really an issue and that the strange >> truncation >>> on >>> them won't be numerically a problem - but I don't think it is worth >> it >>> for this code. >>> >>>> Speaking of which, is there a good way to edit and build openJDK >>> from eclipse? >>>> Then this sort of embarrassing error could be avoided (including >> the >>> printStats() call). >>> >>> I don't use Eclipse, sorry. :-( >>> >>>> As for Arrays.newSize()... I can't find it here: >>>> >> http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/Arrays.html >>>> Is this a new function added in 7? >>> Sorry, make that Arrays.copyOf(..., newSize). I tried to type the >>> name >>> from memory and got it wrong. >>> >>>>> 721 - Arrays.sort() >>>> I thought about using this, but I did some measurements, and >> it >>> turns out that >>>> Arrays.sort() is a bit slower if the portion of the array being >>> sorted has fewer >>>> than about 70 elements. >>> I wonder what the typical number of elements is. Is this sorting >>> crossings per line? Then simple primitives like circles should only >>> have 2 per line, right? Is it worth testing for really small >> numbers >>> of >>> elements (much lower than 70) and doing a manual sort? Or am I >>> misunderstanding what is being sorted there? >>> >>>>> How comfortable do you feel with that conversion? >>>> I'll try to do it and include it in a new patch along with, >>> hopefully, a better way >>>> to iterate through strips, and especially crossings. Right now all >>> the iteration >>>> state is saved in global variables. This is... not good. I spent >> far >>> too much time last >>>> week on bugs caused by this sort of thing. Ideally, any members >> that >>> can't be put at >>>> the top of a class (like our edge and crossing data) should be put >>> in classes of their own. >>> >>> That sounds good, but also consider doing it in separate stages to >>> reduce churn in the code reviewing (and you then have revs to go >> back >>> and test which stage caused a probem if we find a bug later): >>> >>> - first get all on floats >>> - then change strip management >>> - then change to open coordinate intervals >>> - (or vice versa) >>> >>>> Do you have any ideas about how to iterate through edges in a >> strip >>> without going through >>>> every edge? I was thinking of maybe using some sort of tree to >> split >>> the drawing surface, >>>> but I haven't given it much thought. >>> If you look for something like the native code for >>> sun/java2d/pipe/ShapeSpanIterator.c you will see the way I typically >>> like to do edge setup and enumeration. >>> >>> That code uses the "half open interval" approach for both X and Y >>> intervals. >>> >>> I then sort the edge list by "leading Y" and then move through the >>> edges >>> using the following manner (kind of like an inch worm eating the >>> edges, >>> maintaining a pointer to the beginning and end of an "active list" >> of >>> edges that are in play at any given time by virtue of having their Y >>> range intersect the current sampling Y). Note that I use an array >> of >>> edges and then a parallel array of pointers into the edges so that I >>> can >>> sort just the pointers and avoid moving tons of edge data around. >>> Also, >>> later when I eliminate edges from the active list I just move their >>> pointers into and out of view rather than having to copy the edge >>> data. >>> It is harder to do an array of pointers in Java, though - perhaps >> an >>> array of indices? Here is some basic pseudocode: >>> >>> start with lo and hi pointing at index 0 in edge list. >>> until edge list is exhausted { >>> process edges between lo and hi (empty on first pass) >>> scan from hi to lo and toss any edges that are exhausted >>> (compacting remaining pointers towards hi) >>> keep incrementing hi to accept any new edges coming into play >>> process edges between lo and hi to increment to the next Y >>> (note that new edges from previous step may not >>> need any processing in this stage if their starting >>> Y equals the next Y to be sampled) >>> } >>> >>> Gradually lo and hi make their way through the list. The edges >> above >>> hi >>> are always sorted in order of when they may come into play as we >> move >>> downward in Y. The edges between lo and hi are also usually kept >>> sorted >>> by their current X so that the stage that processes them into spans >>> can >>> just run through them. The edges below lo are usually random >> garbage >>> because no care was taken during the "pruning" step to worry about >>> what >>> happens to the pointer table down there as lo is incremented (the >>> algorithm only ever looks up the array of pointers). >>> >>> I hope that helps... >>> >>> ...jim From dlila at redhat.com Wed Jul 28 12:51:39 2010 From: dlila at redhat.com (Denis Lila) Date: Wed, 28 Jul 2010 08:51:39 -0400 (EDT) Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <4C4F69AD.7050605@oracle.com> Message-ID: <2047519078.1182671280321499690.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hello Jim. This one performs almost identically to what is already there in openjdk6 and 7, since it's exactly what I sent for review last week, but with all the changes you suggested implemented. I would actually like to ask you to not look at either one of them. First of all, there is an ArrayIndexOutOfBoundsException possible in emitRow. And secondly, even if there wasn't, last night I implemented your algorithm from ShapeSpanIterator.c to iterate through the edges. I have yet to debug it, but it makes everything much, much simpler, and it should make it far faster, so we get the best of both worlds. Thanks, Denis. ----- "Jim Graham" wrote: > Hi Denis, > > I'll try to get through both versions and see if I can find anything > that was hurting performance with your EdgeLists. I'm guessing that > this version was created because of the performance issues you found > with the EdgeList version? Does this perform more closely to the > existing code than the EdgeList version? > > ...jim > > Denis Lila wrote: > > Hello again. > > > > This attachmet is a "can of worms" implementation without all the > fancy (and slow) > > iteration. It also includes all of the other suggestions you sent in > your first > > review of Dasher and Renderer last week (most importantly, the > firstOrientation > > issue, horizontal lines filtering, and adding prefixes to variable > names to make > > it clear whether they refer to pixels, or subpixels). > > > > Regards, > > Denis. > > > > ----- "Denis Lila" wrote: > > > >> Hello Jim. > >> > >> I implemented your "can of worms" idea. It works, and it got rid > of > >> the biasing. > >> I wasn't able to send a webrev, but there are many changes and a > side > >> by side > >> comparison would probably be useless, so I just attached the file. > I > >> hope this is > >> ok. > >> > >> I also implemented a "better" iterating structure for the lines > and > >> the > >> strips and crossings. I think it is better in every way, except > >> performance. > >> The new file is more than 200 lines smaller than the old one. The > only > >> members of Renderer are now the AA variables and the position > >> variables > >> (sx*, sy*, x*, y*). > >> What I've done is I added an EdgeList class, which encapsulates > all > >> the edge > >> related variables in the old Renderer. At first, I had an Edge > class > >> in addition > >> to the EdgeList class, and while this was much nicer, it turned out > to > >> be too > >> expensive (see last paragraph). > >> I've also added a ScanLineIterator, so instead of _endRendering > >> iterating > >> through strips, and then calling renderStrip() which iterates > through > >> the > >> scanlines in that strip, and then through the crossings in that > >> scanline, > >> what happens now is that _endRendering uses the Iterator > to > >> iterate through each scanline, get get its crossings and iterate > >> through them > >> to accumulate the alpha. By the way, a ScanLine is a type defined > by > >> an > >> interface which exports methods for getting the y coord of the > line, > >> the > >> number of crossings in it, the ith crossing, and a method for > sorting > >> its crossings. > >> The class that implements ScanLine is ScanLineIterator itself. I > made > >> a > >> ScanLine class, but I was afraid performance would suffer because > of > >> all the > >> object creations (this turned out not to be an issue, after I > switched > >> to the > >> current way, and remeasured things). I did not switch back because > >> this is > >> only slightly worse. > >> > >> As for performance: I wrote a simple program that tries to draw a > >> dashed path > >> that consists of about 160 dashed lines of width 1 and length > 30000, > >> going > >> from the centre of the frame to some point. On my machine, this > takes > >> about 4.9 > >> seconds in openjdk6, and 26 seconds using the attached file. Back > when > >> I was using > >> the Edge class it took about 39 seconds. Everything without hundres > of > >> thousands of > >> edges is not much slower > >> I have not changed any of the algorithms. ScanLineIterator still > goes > >> through > >> strips of the same size and computes crossings in every strip > using > >> the same > >> method as before, so I don't know why it's so slow. It can't be > >> because of anything > >> happening in _endRendering, because there are only about 9000 > >> scanlines and for each > >> of them I've just added a few calls to one line getters (which used > to > >> be direct > >> accesses into arrays). > >> > >> Thanks, > >> Denis. > >> > >> ----- "Jim Graham" wrote: > >> > >>> Denis Lila wrote: > >>>> Hello Jim. > >>>> > >>>> Thank you very much for taking the time to read through this. > >>>> > >>>>> 169 - if origLen reaches the end of the dash exactly (the "==" > >>> case) > >>>> You're right, I should. I can't just replace <= with == > >> though, > >>>> because the results will be the same: in the equal case origLen > >>> will > >>>> become 0, and on the next iteration, the (origLen < > >> dash[idx]-phase) > >>> will > >>>> be true, and we will do a goTo(x1,y1), which is what we just did > >> in > >>> the > >>>> previous iteration (unless dash[idx] is 0, in which case the > >> results > >>>> will be even worse). The best solution to this is to just do a > >>> nested > >>>> check for the == case. > >>> Ah, right - because there is no "break" when origLen becomes > zero. > >>> Sounds like you're on it. > >>> > >>>>> 171 - Aren't x0,y0 stored as subpix values? You would then be > >>> comparing > >>>>> a subpix value to a non-subpix value. Perhaps if the subpix > >> calls > >>> are > >>>>> moved to the top of the function I think this should work OK? > >>>> That's true, they are. This is very puzzling. If a > horizontal > >>> line is > >>>> added, when the crossings for it are being computed, dxBydy > should > >>> be NaN, and > >>>> wouldn't an error be thrown when we try to cast to an int in the > >>> call to addCrossing? > >>> > >>> I'm not sure - I didn't trace it through very far - I just noted > >> that > >>> the values were likely in different "resolutions". > >>> > >>>>> 194,197 - Shouldn't these be constants, or based on the > >>> SUB_POS_XY? > >>>> I suppose I should make a biasing constant. I don't think > they > >>> should be based > >>>> on SUB_POS_XY though, because the biasing is done to subpixel > >>> coordinates so > >>>> there is no danger that if our supersampling is fine enough the > >>> biasing will > >>>> make the coordinates jump over some scan line. > >>> I'm guessing you punted on my "can of worms" suggestion then. > ;-) > >>> > >>>>> 216 - if you save the sx0,sy0 before subpix'ing them then you > >> don't > >>> have > >>>>> to "unsubpix" them here. (Though you still need the subpix sy0 > >> for > >>> line > >>>>> 209 - or you could just call subpix on it for that line and at > >>> least > >>>>> you'd save 1 call to sub/unsub). > >>>> Ok. I'll just save subpixed and unsubpixed versions of sx0, > >> sy0. > >>> That should > >>>> eliminate all sx0,sy0 related calls to tosubpix and topix except > >> in > >>> moveTo. > >>> > >>> and lineTo. You may only need 3 of those values, though, if I > >>> remember > >>> my code reading well enough. > >>> > >>>>> 256,264 - casting to int is problematic. It truncates towards > 0 > >>> which > >>>>> means negatives are ceil'd and positives are floor'd. It would > >> be > >>> best > >>>>> to use floor here instead. On the other hand, if negative > >> numbers > >>> are > >>>>> always "off the left side of the drawable" then this is moot. > >>>> That's why I left it at int casting. Do you still think I > >> should > >>> change it > >>>> to floor? > >>> If you mean floor, I think it best to use floor. Unless you can > >> prove > >>> that negatives aren't really an issue and that the strange > >> truncation > >>> on > >>> them won't be numerically a problem - but I don't think it is > worth > >> it > >>> for this code. > >>> > >>>> Speaking of which, is there a good way to edit and build openJDK > >>> from eclipse? > >>>> Then this sort of embarrassing error could be avoided (including > >> the > >>> printStats() call). > >>> > >>> I don't use Eclipse, sorry. :-( > >>> > >>>> As for Arrays.newSize()... I can't find it here: > >>>> > >> > http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/Arrays.html > >>>> Is this a new function added in 7? > >>> Sorry, make that Arrays.copyOf(..., newSize). I tried to type > the > >>> name > >>> from memory and got it wrong. > >>> > >>>>> 721 - Arrays.sort() > >>>> I thought about using this, but I did some measurements, and > >> it > >>> turns out that > >>>> Arrays.sort() is a bit slower if the portion of the array being > >>> sorted has fewer > >>>> than about 70 elements. > >>> I wonder what the typical number of elements is. Is this sorting > >>> crossings per line? Then simple primitives like circles should > only > >>> have 2 per line, right? Is it worth testing for really small > >> numbers > >>> of > >>> elements (much lower than 70) and doing a manual sort? Or am I > >>> misunderstanding what is being sorted there? > >>> > >>>>> How comfortable do you feel with that conversion? > >>>> I'll try to do it and include it in a new patch along with, > >>> hopefully, a better way > >>>> to iterate through strips, and especially crossings. Right now > all > >>> the iteration > >>>> state is saved in global variables. This is... not good. I spent > >> far > >>> too much time last > >>>> week on bugs caused by this sort of thing. Ideally, any members > >> that > >>> can't be put at > >>>> the top of a class (like our edge and crossing data) should be > put > >>> in classes of their own. > >>> > >>> That sounds good, but also consider doing it in separate stages > to > >>> reduce churn in the code reviewing (and you then have revs to go > >> back > >>> and test which stage caused a probem if we find a bug later): > >>> > >>> - first get all on floats > >>> - then change strip management > >>> - then change to open coordinate intervals > >>> - (or vice versa) > >>> > >>>> Do you have any ideas about how to iterate through edges in a > >> strip > >>> without going through > >>>> every edge? I was thinking of maybe using some sort of tree to > >> split > >>> the drawing surface, > >>>> but I haven't given it much thought. > >>> If you look for something like the native code for > >>> sun/java2d/pipe/ShapeSpanIterator.c you will see the way I > typically > >>> like to do edge setup and enumeration. > >>> > >>> That code uses the "half open interval" approach for both X and Y > >>> intervals. > >>> > >>> I then sort the edge list by "leading Y" and then move through > the > >>> edges > >>> using the following manner (kind of like an inch worm eating the > >>> edges, > >>> maintaining a pointer to the beginning and end of an "active > list" > >> of > >>> edges that are in play at any given time by virtue of having their > Y > >>> range intersect the current sampling Y). Note that I use an > array > >> of > >>> edges and then a parallel array of pointers into the edges so that > I > >>> can > >>> sort just the pointers and avoid moving tons of edge data around. > >>> Also, > >>> later when I eliminate edges from the active list I just move > their > >>> pointers into and out of view rather than having to copy the edge > >>> data. > >>> It is harder to do an array of pointers in Java, though - > perhaps > >> an > >>> array of indices? Here is some basic pseudocode: > >>> > >>> start with lo and hi pointing at index 0 in edge list. > >>> until edge list is exhausted { > >>> process edges between lo and hi (empty on first pass) > >>> scan from hi to lo and toss any edges that are exhausted > >>> (compacting remaining pointers towards hi) > >>> keep incrementing hi to accept any new edges coming into > play > >>> process edges between lo and hi to increment to the next Y > >>> (note that new edges from previous step may not > >>> need any processing in this stage if their starting > >>> Y equals the next Y to be sampled) > >>> } > >>> > >>> Gradually lo and hi make their way through the list. The edges > >> above > >>> hi > >>> are always sorted in order of when they may come into play as we > >> move > >>> downward in Y. The edges between lo and hi are also usually kept > >>> sorted > >>> by their current X so that the stage that processes them into > spans > >>> can > >>> just run through them. The edges below lo are usually random > >> garbage > >>> because no care was taken during the "pruning" step to worry > about > >>> what > >>> happens to the pointer table down there as lo is incremented (the > >>> algorithm only ever looks up the array of pointers). > >>> > >>> I hope that helps... > >>> > >>> ...jim From james.graham at oracle.com Wed Jul 28 21:19:34 2010 From: james.graham at oracle.com (Jim Graham) Date: Wed, 28 Jul 2010 14:19:34 -0700 Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <2047519078.1182671280321499690.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <2047519078.1182671280321499690.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C509EE6.1040008@oracle.com> Woohoo, Denis! I look forward to seeing the new version! ...jim On 7/28/2010 5:51 AM, Denis Lila wrote: > Hello Jim. > > This one performs almost identically to what is already there > in openjdk6 and 7, since it's exactly what I sent for review > last week, but with all the changes you suggested implemented. > > I would actually like to ask you to not look at either one of > them. First of all, there is an ArrayIndexOutOfBoundsException > possible in emitRow. > And secondly, even if there wasn't, last night I implemented > your algorithm from ShapeSpanIterator.c to iterate through > the edges. I have yet to debug it, but it makes everything much, > much simpler, and it should make it far faster, so we get the best > of both worlds. > > Thanks, > Denis. > > ----- "Jim Graham" wrote: > >> Hi Denis, >> >> I'll try to get through both versions and see if I can find anything >> that was hurting performance with your EdgeLists. I'm guessing that >> this version was created because of the performance issues you found >> with the EdgeList version? Does this perform more closely to the >> existing code than the EdgeList version? >> >> ...jim >> >> Denis Lila wrote: >>> Hello again. >>> >>> This attachmet is a "can of worms" implementation without all the >> fancy (and slow) >>> iteration. It also includes all of the other suggestions you sent in >> your first >>> review of Dasher and Renderer last week (most importantly, the >> firstOrientation >>> issue, horizontal lines filtering, and adding prefixes to variable >> names to make >>> it clear whether they refer to pixels, or subpixels). >>> >>> Regards, >>> Denis. >>> >>> ----- "Denis Lila" wrote: >>> >>>> Hello Jim. >>>> >>>> I implemented your "can of worms" idea. It works, and it got rid >> of >>>> the biasing. >>>> I wasn't able to send a webrev, but there are many changes and a >> side >>>> by side >>>> comparison would probably be useless, so I just attached the file. >> I >>>> hope this is >>>> ok. >>>> >>>> I also implemented a "better" iterating structure for the lines >> and >>>> the >>>> strips and crossings. I think it is better in every way, except >>>> performance. >>>> The new file is more than 200 lines smaller than the old one. The >> only >>>> members of Renderer are now the AA variables and the position >>>> variables >>>> (sx*, sy*, x*, y*). >>>> What I've done is I added an EdgeList class, which encapsulates >> all >>>> the edge >>>> related variables in the old Renderer. At first, I had an Edge >> class >>>> in addition >>>> to the EdgeList class, and while this was much nicer, it turned out >> to >>>> be too >>>> expensive (see last paragraph). >>>> I've also added a ScanLineIterator, so instead of _endRendering >>>> iterating >>>> through strips, and then calling renderStrip() which iterates >> through >>>> the >>>> scanlines in that strip, and then through the crossings in that >>>> scanline, >>>> what happens now is that _endRendering uses the Iterator >> to >>>> iterate through each scanline, get get its crossings and iterate >>>> through them >>>> to accumulate the alpha. By the way, a ScanLine is a type defined >> by >>>> an >>>> interface which exports methods for getting the y coord of the >> line, >>>> the >>>> number of crossings in it, the ith crossing, and a method for >> sorting >>>> its crossings. >>>> The class that implements ScanLine is ScanLineIterator itself. I >> made >>>> a >>>> ScanLine class, but I was afraid performance would suffer because >> of >>>> all the >>>> object creations (this turned out not to be an issue, after I >> switched >>>> to the >>>> current way, and remeasured things). I did not switch back because >>>> this is >>>> only slightly worse. >>>> >>>> As for performance: I wrote a simple program that tries to draw a >>>> dashed path >>>> that consists of about 160 dashed lines of width 1 and length >> 30000, >>>> going >>>> from the centre of the frame to some point. On my machine, this >> takes >>>> about 4.9 >>>> seconds in openjdk6, and 26 seconds using the attached file. Back >> when >>>> I was using >>>> the Edge class it took about 39 seconds. Everything without hundres >> of >>>> thousands of >>>> edges is not much slower >>>> I have not changed any of the algorithms. ScanLineIterator still >> goes >>>> through >>>> strips of the same size and computes crossings in every strip >> using >>>> the same >>>> method as before, so I don't know why it's so slow. It can't be >>>> because of anything >>>> happening in _endRendering, because there are only about 9000 >>>> scanlines and for each >>>> of them I've just added a few calls to one line getters (which used >> to >>>> be direct >>>> accesses into arrays). >>>> >>>> Thanks, >>>> Denis. >>>> >>>> ----- "Jim Graham" wrote: >>>> >>>>> Denis Lila wrote: >>>>>> Hello Jim. >>>>>> >>>>>> Thank you very much for taking the time to read through this. >>>>>> >>>>>>> 169 - if origLen reaches the end of the dash exactly (the "==" >>>>> case) >>>>>> You're right, I should. I can't just replace<= with == >>>> though, >>>>>> because the results will be the same: in the equal case origLen >>>>> will >>>>>> become 0, and on the next iteration, the (origLen< >>>> dash[idx]-phase) >>>>> will >>>>>> be true, and we will do a goTo(x1,y1), which is what we just did >>>> in >>>>> the >>>>>> previous iteration (unless dash[idx] is 0, in which case the >>>> results >>>>>> will be even worse). The best solution to this is to just do a >>>>> nested >>>>>> check for the == case. >>>>> Ah, right - because there is no "break" when origLen becomes >> zero. >>>>> Sounds like you're on it. >>>>> >>>>>>> 171 - Aren't x0,y0 stored as subpix values? You would then be >>>>> comparing >>>>>>> a subpix value to a non-subpix value. Perhaps if the subpix >>>> calls >>>>> are >>>>>>> moved to the top of the function I think this should work OK? >>>>>> That's true, they are. This is very puzzling. If a >> horizontal >>>>> line is >>>>>> added, when the crossings for it are being computed, dxBydy >> should >>>>> be NaN, and >>>>>> wouldn't an error be thrown when we try to cast to an int in the >>>>> call to addCrossing? >>>>> >>>>> I'm not sure - I didn't trace it through very far - I just noted >>>> that >>>>> the values were likely in different "resolutions". >>>>> >>>>>>> 194,197 - Shouldn't these be constants, or based on the >>>>> SUB_POS_XY? >>>>>> I suppose I should make a biasing constant. I don't think >> they >>>>> should be based >>>>>> on SUB_POS_XY though, because the biasing is done to subpixel >>>>> coordinates so >>>>>> there is no danger that if our supersampling is fine enough the >>>>> biasing will >>>>>> make the coordinates jump over some scan line. >>>>> I'm guessing you punted on my "can of worms" suggestion then. >> ;-) >>>>> >>>>>>> 216 - if you save the sx0,sy0 before subpix'ing them then you >>>> don't >>>>> have >>>>>>> to "unsubpix" them here. (Though you still need the subpix sy0 >>>> for >>>>> line >>>>>>> 209 - or you could just call subpix on it for that line and at >>>>> least >>>>>>> you'd save 1 call to sub/unsub). >>>>>> Ok. I'll just save subpixed and unsubpixed versions of sx0, >>>> sy0. >>>>> That should >>>>>> eliminate all sx0,sy0 related calls to tosubpix and topix except >>>> in >>>>> moveTo. >>>>> >>>>> and lineTo. You may only need 3 of those values, though, if I >>>>> remember >>>>> my code reading well enough. >>>>> >>>>>>> 256,264 - casting to int is problematic. It truncates towards >> 0 >>>>> which >>>>>>> means negatives are ceil'd and positives are floor'd. It would >>>> be >>>>> best >>>>>>> to use floor here instead. On the other hand, if negative >>>> numbers >>>>> are >>>>>>> always "off the left side of the drawable" then this is moot. >>>>>> That's why I left it at int casting. Do you still think I >>>> should >>>>> change it >>>>>> to floor? >>>>> If you mean floor, I think it best to use floor. Unless you can >>>> prove >>>>> that negatives aren't really an issue and that the strange >>>> truncation >>>>> on >>>>> them won't be numerically a problem - but I don't think it is >> worth >>>> it >>>>> for this code. >>>>> >>>>>> Speaking of which, is there a good way to edit and build openJDK >>>>> from eclipse? >>>>>> Then this sort of embarrassing error could be avoided (including >>>> the >>>>> printStats() call). >>>>> >>>>> I don't use Eclipse, sorry. :-( >>>>> >>>>>> As for Arrays.newSize()... I can't find it here: >>>>>> >>>> >> http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/Arrays.html >>>>>> Is this a new function added in 7? >>>>> Sorry, make that Arrays.copyOf(..., newSize). I tried to type >> the >>>>> name >>>>> from memory and got it wrong. >>>>> >>>>>>> 721 - Arrays.sort() >>>>>> I thought about using this, but I did some measurements, and >>>> it >>>>> turns out that >>>>>> Arrays.sort() is a bit slower if the portion of the array being >>>>> sorted has fewer >>>>>> than about 70 elements. >>>>> I wonder what the typical number of elements is. Is this sorting >>>>> crossings per line? Then simple primitives like circles should >> only >>>>> have 2 per line, right? Is it worth testing for really small >>>> numbers >>>>> of >>>>> elements (much lower than 70) and doing a manual sort? Or am I >>>>> misunderstanding what is being sorted there? >>>>> >>>>>>> How comfortable do you feel with that conversion? >>>>>> I'll try to do it and include it in a new patch along with, >>>>> hopefully, a better way >>>>>> to iterate through strips, and especially crossings. Right now >> all >>>>> the iteration >>>>>> state is saved in global variables. This is... not good. I spent >>>> far >>>>> too much time last >>>>>> week on bugs caused by this sort of thing. Ideally, any members >>>> that >>>>> can't be put at >>>>>> the top of a class (like our edge and crossing data) should be >> put >>>>> in classes of their own. >>>>> >>>>> That sounds good, but also consider doing it in separate stages >> to >>>>> reduce churn in the code reviewing (and you then have revs to go >>>> back >>>>> and test which stage caused a probem if we find a bug later): >>>>> >>>>> - first get all on floats >>>>> - then change strip management >>>>> - then change to open coordinate intervals >>>>> - (or vice versa) >>>>> >>>>>> Do you have any ideas about how to iterate through edges in a >>>> strip >>>>> without going through >>>>>> every edge? I was thinking of maybe using some sort of tree to >>>> split >>>>> the drawing surface, >>>>>> but I haven't given it much thought. >>>>> If you look for something like the native code for >>>>> sun/java2d/pipe/ShapeSpanIterator.c you will see the way I >> typically >>>>> like to do edge setup and enumeration. >>>>> >>>>> That code uses the "half open interval" approach for both X and Y >>>>> intervals. >>>>> >>>>> I then sort the edge list by "leading Y" and then move through >> the >>>>> edges >>>>> using the following manner (kind of like an inch worm eating the >>>>> edges, >>>>> maintaining a pointer to the beginning and end of an "active >> list" >>>> of >>>>> edges that are in play at any given time by virtue of having their >> Y >>>>> range intersect the current sampling Y). Note that I use an >> array >>>> of >>>>> edges and then a parallel array of pointers into the edges so that >> I >>>>> can >>>>> sort just the pointers and avoid moving tons of edge data around. >>>>> Also, >>>>> later when I eliminate edges from the active list I just move >> their >>>>> pointers into and out of view rather than having to copy the edge >>>>> data. >>>>> It is harder to do an array of pointers in Java, though - >> perhaps >>>> an >>>>> array of indices? Here is some basic pseudocode: >>>>> >>>>> start with lo and hi pointing at index 0 in edge list. >>>>> until edge list is exhausted { >>>>> process edges between lo and hi (empty on first pass) >>>>> scan from hi to lo and toss any edges that are exhausted >>>>> (compacting remaining pointers towards hi) >>>>> keep incrementing hi to accept any new edges coming into >> play >>>>> process edges between lo and hi to increment to the next Y >>>>> (note that new edges from previous step may not >>>>> need any processing in this stage if their starting >>>>> Y equals the next Y to be sampled) >>>>> } >>>>> >>>>> Gradually lo and hi make their way through the list. The edges >>>> above >>>>> hi >>>>> are always sorted in order of when they may come into play as we >>>> move >>>>> downward in Y. The edges between lo and hi are also usually kept >>>>> sorted >>>>> by their current X so that the stage that processes them into >> spans >>>>> can >>>>> just run through them. The edges below lo are usually random >>>> garbage >>>>> because no care was taken during the "pruning" step to worry >> about >>>>> what >>>>> happens to the pointer table down there as lo is incremented (the >>>>> algorithm only ever looks up the array of pointers). >>>>> >>>>> I hope that helps... >>>>> >>>>> ...jim From dlila at redhat.com Wed Jul 28 23:50:01 2010 From: dlila at redhat.com (Denis Lila) Date: Wed, 28 Jul 2010 19:50:01 -0400 (EDT) Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <408304472.1246031280359818700.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <1999969578.1246371280361001606.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hello. And, here it is: http://icedtea.classpath.org/~dlila/webrevs/fpBetterAA/webrev/ Just as I thought, it's way faster than the original. I made a new test, which is supposed to be more realistic than drawing 30000 length lines. It consists of splitting a 1000x1000 frame in 100 10x10 squares and in each square drawing 20 or so curves with random start/end/control points in that square. In this case it's at least twice faster (~0.85 versus ~1.95 seconds). Unfortunately I've had to do a lot of the same optimizations that I was trying to remove (i.e. making everything a global variable). I tried writing a higher level version of it, but it completely negated the performance gains of the new algorithm. Anyway, it's still not as bad as before because the algorithm is inherently clearer and we only iterate through scan lines instead of iterating through strips and then scanlines in that strip, and then edges, all in the same method. It's also better organized, and logically separate parts of the code don't really touch each other's variables much. And it's definitely better commented. I also made some minor changes outside of Renderer that did not appear in the first version of this patch last week: 1. I fixed the issue Jim pointed out in Dasher, where if (origLen == leftInThisDashSegment) the dash index was not being incremented. 2. In dasher, I no longer copy the dash array. 3. I removed files PiscesMath.java and Transform4.java because they are no longer needed. Thanks, Denis. ----- "Jim Graham" wrote: > Woohoo, Denis! I look forward to seeing the new version! > > ...jim > > On 7/28/2010 5:51 AM, Denis Lila wrote: > > Hello Jim. > > > > This one performs almost identically to what is already there > > in openjdk6 and 7, since it's exactly what I sent for review > > last week, but with all the changes you suggested implemented. > > > > I would actually like to ask you to not look at either one of > > them. First of all, there is an ArrayIndexOutOfBoundsException > > possible in emitRow. > > And secondly, even if there wasn't, last night I implemented > > your algorithm from ShapeSpanIterator.c to iterate through > > the edges. I have yet to debug it, but it makes everything much, > > much simpler, and it should make it far faster, so we get the best > > of both worlds. > > > > Thanks, > > Denis. > > > > ----- "Jim Graham" wrote: > > > >> Hi Denis, > >> > >> I'll try to get through both versions and see if I can find > anything > >> that was hurting performance with your EdgeLists. I'm guessing > that > >> this version was created because of the performance issues you > found > >> with the EdgeList version? Does this perform more closely to the > >> existing code than the EdgeList version? > >> > >> ...jim > >> > >> Denis Lila wrote: > >>> Hello again. > >>> > >>> This attachmet is a "can of worms" implementation without all the > >> fancy (and slow) > >>> iteration. It also includes all of the other suggestions you sent > in > >> your first > >>> review of Dasher and Renderer last week (most importantly, the > >> firstOrientation > >>> issue, horizontal lines filtering, and adding prefixes to > variable > >> names to make > >>> it clear whether they refer to pixels, or subpixels). > >>> > >>> Regards, > >>> Denis. > >>> > >>> ----- "Denis Lila" wrote: > >>> > >>>> Hello Jim. > >>>> > >>>> I implemented your "can of worms" idea. It works, and it got rid > >> of > >>>> the biasing. > >>>> I wasn't able to send a webrev, but there are many changes and a > >> side > >>>> by side > >>>> comparison would probably be useless, so I just attached the > file. > >> I > >>>> hope this is > >>>> ok. > >>>> > >>>> I also implemented a "better" iterating structure for the lines > >> and > >>>> the > >>>> strips and crossings. I think it is better in every way, except > >>>> performance. > >>>> The new file is more than 200 lines smaller than the old one. > The > >> only > >>>> members of Renderer are now the AA variables and the position > >>>> variables > >>>> (sx*, sy*, x*, y*). > >>>> What I've done is I added an EdgeList class, which encapsulates > >> all > >>>> the edge > >>>> related variables in the old Renderer. At first, I had an Edge > >> class > >>>> in addition > >>>> to the EdgeList class, and while this was much nicer, it turned > out > >> to > >>>> be too > >>>> expensive (see last paragraph). > >>>> I've also added a ScanLineIterator, so instead of _endRendering > >>>> iterating > >>>> through strips, and then calling renderStrip() which iterates > >> through > >>>> the > >>>> scanlines in that strip, and then through the crossings in that > >>>> scanline, > >>>> what happens now is that _endRendering uses the > Iterator > >> to > >>>> iterate through each scanline, get get its crossings and iterate > >>>> through them > >>>> to accumulate the alpha. By the way, a ScanLine is a type > defined > >> by > >>>> an > >>>> interface which exports methods for getting the y coord of the > >> line, > >>>> the > >>>> number of crossings in it, the ith crossing, and a method for > >> sorting > >>>> its crossings. > >>>> The class that implements ScanLine is ScanLineIterator itself. I > >> made > >>>> a > >>>> ScanLine class, but I was afraid performance would suffer > because > >> of > >>>> all the > >>>> object creations (this turned out not to be an issue, after I > >> switched > >>>> to the > >>>> current way, and remeasured things). I did not switch back > because > >>>> this is > >>>> only slightly worse. > >>>> > >>>> As for performance: I wrote a simple program that tries to draw > a > >>>> dashed path > >>>> that consists of about 160 dashed lines of width 1 and length > >> 30000, > >>>> going > >>>> from the centre of the frame to some point. On my machine, this > >> takes > >>>> about 4.9 > >>>> seconds in openjdk6, and 26 seconds using the attached file. > Back > >> when > >>>> I was using > >>>> the Edge class it took about 39 seconds. Everything without > hundres > >> of > >>>> thousands of > >>>> edges is not much slower > >>>> I have not changed any of the algorithms. ScanLineIterator still > >> goes > >>>> through > >>>> strips of the same size and computes crossings in every strip > >> using > >>>> the same > >>>> method as before, so I don't know why it's so slow. It can't be > >>>> because of anything > >>>> happening in _endRendering, because there are only about 9000 > >>>> scanlines and for each > >>>> of them I've just added a few calls to one line getters (which > used > >> to > >>>> be direct > >>>> accesses into arrays). > >>>> > >>>> Thanks, > >>>> Denis. > >>>> > >>>> ----- "Jim Graham" wrote: > >>>> > >>>>> Denis Lila wrote: > >>>>>> Hello Jim. > >>>>>> > >>>>>> Thank you very much for taking the time to read through this. > >>>>>> > >>>>>>> 169 - if origLen reaches the end of the dash exactly (the > "==" > >>>>> case) > >>>>>> You're right, I should. I can't just replace<= with == > >>>> though, > >>>>>> because the results will be the same: in the equal case > origLen > >>>>> will > >>>>>> become 0, and on the next iteration, the (origLen< > >>>> dash[idx]-phase) > >>>>> will > >>>>>> be true, and we will do a goTo(x1,y1), which is what we just > did > >>>> in > >>>>> the > >>>>>> previous iteration (unless dash[idx] is 0, in which case the > >>>> results > >>>>>> will be even worse). The best solution to this is to just do a > >>>>> nested > >>>>>> check for the == case. > >>>>> Ah, right - because there is no "break" when origLen becomes > >> zero. > >>>>> Sounds like you're on it. > >>>>> > >>>>>>> 171 - Aren't x0,y0 stored as subpix values? You would then > be > >>>>> comparing > >>>>>>> a subpix value to a non-subpix value. Perhaps if the subpix > >>>> calls > >>>>> are > >>>>>>> moved to the top of the function I think this should work OK? > >>>>>> That's true, they are. This is very puzzling. If a > >> horizontal > >>>>> line is > >>>>>> added, when the crossings for it are being computed, dxBydy > >> should > >>>>> be NaN, and > >>>>>> wouldn't an error be thrown when we try to cast to an int in > the > >>>>> call to addCrossing? > >>>>> > >>>>> I'm not sure - I didn't trace it through very far - I just > noted > >>>> that > >>>>> the values were likely in different "resolutions". > >>>>> > >>>>>>> 194,197 - Shouldn't these be constants, or based on the > >>>>> SUB_POS_XY? > >>>>>> I suppose I should make a biasing constant. I don't think > >> they > >>>>> should be based > >>>>>> on SUB_POS_XY though, because the biasing is done to subpixel > >>>>> coordinates so > >>>>>> there is no danger that if our supersampling is fine enough > the > >>>>> biasing will > >>>>>> make the coordinates jump over some scan line. > >>>>> I'm guessing you punted on my "can of worms" suggestion then. > >> ;-) > >>>>> > >>>>>>> 216 - if you save the sx0,sy0 before subpix'ing them then you > >>>> don't > >>>>> have > >>>>>>> to "unsubpix" them here. (Though you still need the subpix > sy0 > >>>> for > >>>>> line > >>>>>>> 209 - or you could just call subpix on it for that line and > at > >>>>> least > >>>>>>> you'd save 1 call to sub/unsub). > >>>>>> Ok. I'll just save subpixed and unsubpixed versions of > sx0, > >>>> sy0. > >>>>> That should > >>>>>> eliminate all sx0,sy0 related calls to tosubpix and topix > except > >>>> in > >>>>> moveTo. > >>>>> > >>>>> and lineTo. You may only need 3 of those values, though, if I > >>>>> remember > >>>>> my code reading well enough. > >>>>> > >>>>>>> 256,264 - casting to int is problematic. It truncates > towards > >> 0 > >>>>> which > >>>>>>> means negatives are ceil'd and positives are floor'd. It > would > >>>> be > >>>>> best > >>>>>>> to use floor here instead. On the other hand, if negative > >>>> numbers > >>>>> are > >>>>>>> always "off the left side of the drawable" then this is moot. > >>>>>> That's why I left it at int casting. Do you still think I > >>>> should > >>>>> change it > >>>>>> to floor? > >>>>> If you mean floor, I think it best to use floor. Unless you > can > >>>> prove > >>>>> that negatives aren't really an issue and that the strange > >>>> truncation > >>>>> on > >>>>> them won't be numerically a problem - but I don't think it is > >> worth > >>>> it > >>>>> for this code. > >>>>> > >>>>>> Speaking of which, is there a good way to edit and build > openJDK > >>>>> from eclipse? > >>>>>> Then this sort of embarrassing error could be avoided > (including > >>>> the > >>>>> printStats() call). > >>>>> > >>>>> I don't use Eclipse, sorry. :-( > >>>>> > >>>>>> As for Arrays.newSize()... I can't find it here: > >>>>>> > >>>> > >> > http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/Arrays.html > >>>>>> Is this a new function added in 7? > >>>>> Sorry, make that Arrays.copyOf(..., newSize). I tried to type > >> the > >>>>> name > >>>>> from memory and got it wrong. > >>>>> > >>>>>>> 721 - Arrays.sort() > >>>>>> I thought about using this, but I did some measurements, > and > >>>> it > >>>>> turns out that > >>>>>> Arrays.sort() is a bit slower if the portion of the array > being > >>>>> sorted has fewer > >>>>>> than about 70 elements. > >>>>> I wonder what the typical number of elements is. Is this > sorting > >>>>> crossings per line? Then simple primitives like circles should > >> only > >>>>> have 2 per line, right? Is it worth testing for really small > >>>> numbers > >>>>> of > >>>>> elements (much lower than 70) and doing a manual sort? Or am I > >>>>> misunderstanding what is being sorted there? > >>>>> > >>>>>>> How comfortable do you feel with that conversion? > >>>>>> I'll try to do it and include it in a new patch along with, > >>>>> hopefully, a better way > >>>>>> to iterate through strips, and especially crossings. Right now > >> all > >>>>> the iteration > >>>>>> state is saved in global variables. This is... not good. I > spent > >>>> far > >>>>> too much time last > >>>>>> week on bugs caused by this sort of thing. Ideally, any > members > >>>> that > >>>>> can't be put at > >>>>>> the top of a class (like our edge and crossing data) should be > >> put > >>>>> in classes of their own. > >>>>> > >>>>> That sounds good, but also consider doing it in separate stages > >> to > >>>>> reduce churn in the code reviewing (and you then have revs to > go > >>>> back > >>>>> and test which stage caused a probem if we find a bug later): > >>>>> > >>>>> - first get all on floats > >>>>> - then change strip management > >>>>> - then change to open coordinate intervals > >>>>> - (or vice versa) > >>>>> > >>>>>> Do you have any ideas about how to iterate through edges in a > >>>> strip > >>>>> without going through > >>>>>> every edge? I was thinking of maybe using some sort of tree to > >>>> split > >>>>> the drawing surface, > >>>>>> but I haven't given it much thought. > >>>>> If you look for something like the native code for > >>>>> sun/java2d/pipe/ShapeSpanIterator.c you will see the way I > >> typically > >>>>> like to do edge setup and enumeration. > >>>>> > >>>>> That code uses the "half open interval" approach for both X and > Y > >>>>> intervals. > >>>>> > >>>>> I then sort the edge list by "leading Y" and then move through > >> the > >>>>> edges > >>>>> using the following manner (kind of like an inch worm eating > the > >>>>> edges, > >>>>> maintaining a pointer to the beginning and end of an "active > >> list" > >>>> of > >>>>> edges that are in play at any given time by virtue of having > their > >> Y > >>>>> range intersect the current sampling Y). Note that I use an > >> array > >>>> of > >>>>> edges and then a parallel array of pointers into the edges so > that > >> I > >>>>> can > >>>>> sort just the pointers and avoid moving tons of edge data > around. > >>>>> Also, > >>>>> later when I eliminate edges from the active list I just move > >> their > >>>>> pointers into and out of view rather than having to copy the > edge > >>>>> data. > >>>>> It is harder to do an array of pointers in Java, though - > >> perhaps > >>>> an > >>>>> array of indices? Here is some basic pseudocode: > >>>>> > >>>>> start with lo and hi pointing at index 0 in edge list. > >>>>> until edge list is exhausted { > >>>>> process edges between lo and hi (empty on first pass) > >>>>> scan from hi to lo and toss any edges that are exhausted > >>>>> (compacting remaining pointers towards hi) > >>>>> keep incrementing hi to accept any new edges coming into > >> play > >>>>> process edges between lo and hi to increment to the next > Y > >>>>> (note that new edges from previous step may not > >>>>> need any processing in this stage if their starting > >>>>> Y equals the next Y to be sampled) > >>>>> } > >>>>> > >>>>> Gradually lo and hi make their way through the list. The edges > >>>> above > >>>>> hi > >>>>> are always sorted in order of when they may come into play as > we > >>>> move > >>>>> downward in Y. The edges between lo and hi are also usually > kept > >>>>> sorted > >>>>> by their current X so that the stage that processes them into > >> spans > >>>>> can > >>>>> just run through them. The edges below lo are usually random > >>>> garbage > >>>>> because no care was taken during the "pruning" step to worry > >> about > >>>>> what > >>>>> happens to the pointer table down there as lo is incremented > (the > >>>>> algorithm only ever looks up the array of pointers). > >>>>> > >>>>> I hope that helps... > >>>>> > >>>>> ...jim From james.graham at oracle.com Thu Jul 29 03:55:07 2010 From: james.graham at oracle.com (Jim Graham) Date: Wed, 28 Jul 2010 20:55:07 -0700 Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <1999969578.1246371280361001606.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <1999969578.1246371280361001606.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C50FB9B.4050804@oracle.com> Hi Denis, Only some minor comments so far: Stroker.java: - Should det be precomputed and saved? (You calculate it in the constructor anyway, but don't save it.) - Should test for uniform scale be precomputed? - (Is test for uniform scale too strict? Can a rotated uniform scale use the same code as upright uniform scale?) - Why are m00_2_m01_2 et al no longer precomputed (they only need to be precomputed if scale is not uniform which isn't common)? - lineLength method is "user space length" isn't it? - a more descriptive name might help avoid confusion if someone is modifying code here later. - line 614 - missing space Dasher.java: - Line 187 - use "leftInThisDashSegment" here? I still have to look at Renderer.java in depth, but I thought I'd send these minor comments along while they are fresh in my email buffer... ...jim Denis Lila wrote: > Hello. > > And, here it is: http://icedtea.classpath.org/~dlila/webrevs/fpBetterAA/webrev/ > > Just as I thought, it's way faster than the original. I made a new > test, which is supposed to be more realistic than drawing 30000 length > lines. It consists of splitting a 1000x1000 frame in 100 10x10 squares > and in each square drawing 20 or so curves with random start/end/control > points in that square. In this case it's at least twice faster (~0.85 > versus ~1.95 seconds). > > Unfortunately I've had to do a lot of the same optimizations that I was > trying to remove (i.e. making everything a global variable). I tried > writing a higher level version of it, but it completely negated the > performance gains of the new algorithm. Anyway, it's still not as bad > as before because the algorithm is inherently clearer and we only iterate > through scan lines instead of iterating through strips and then scanlines > in that strip, and then edges, all in the same method. > > It's also better organized, and logically separate parts of the code don't > really touch each other's variables much. And it's definitely better > commented. > > I also made some minor changes outside of Renderer that did not appear in > the first version of this patch last week: > 1. I fixed the issue Jim pointed out in Dasher, where if > (origLen == leftInThisDashSegment) the dash index was not being incremented. > 2. In dasher, I no longer copy the dash array. > 3. I removed files PiscesMath.java and Transform4.java because they are no > longer needed. > > Thanks, > Denis. > > ----- "Jim Graham" wrote: > >> Woohoo, Denis! I look forward to seeing the new version! >> >> ...jim >> >> On 7/28/2010 5:51 AM, Denis Lila wrote: >>> Hello Jim. >>> >>> This one performs almost identically to what is already there >>> in openjdk6 and 7, since it's exactly what I sent for review >>> last week, but with all the changes you suggested implemented. >>> >>> I would actually like to ask you to not look at either one of >>> them. First of all, there is an ArrayIndexOutOfBoundsException >>> possible in emitRow. >>> And secondly, even if there wasn't, last night I implemented >>> your algorithm from ShapeSpanIterator.c to iterate through >>> the edges. I have yet to debug it, but it makes everything much, >>> much simpler, and it should make it far faster, so we get the best >>> of both worlds. >>> >>> Thanks, >>> Denis. >>> >>> ----- "Jim Graham" wrote: >>> >>>> Hi Denis, >>>> >>>> I'll try to get through both versions and see if I can find >> anything >>>> that was hurting performance with your EdgeLists. I'm guessing >> that >>>> this version was created because of the performance issues you >> found >>>> with the EdgeList version? Does this perform more closely to the >>>> existing code than the EdgeList version? >>>> >>>> ...jim >>>> >>>> Denis Lila wrote: >>>>> Hello again. >>>>> >>>>> This attachmet is a "can of worms" implementation without all the >>>> fancy (and slow) >>>>> iteration. It also includes all of the other suggestions you sent >> in >>>> your first >>>>> review of Dasher and Renderer last week (most importantly, the >>>> firstOrientation >>>>> issue, horizontal lines filtering, and adding prefixes to >> variable >>>> names to make >>>>> it clear whether they refer to pixels, or subpixels). >>>>> >>>>> Regards, >>>>> Denis. >>>>> >>>>> ----- "Denis Lila" wrote: >>>>> >>>>>> Hello Jim. >>>>>> >>>>>> I implemented your "can of worms" idea. It works, and it got rid >>>> of >>>>>> the biasing. >>>>>> I wasn't able to send a webrev, but there are many changes and a >>>> side >>>>>> by side >>>>>> comparison would probably be useless, so I just attached the >> file. >>>> I >>>>>> hope this is >>>>>> ok. >>>>>> >>>>>> I also implemented a "better" iterating structure for the lines >>>> and >>>>>> the >>>>>> strips and crossings. I think it is better in every way, except >>>>>> performance. >>>>>> The new file is more than 200 lines smaller than the old one. >> The >>>> only >>>>>> members of Renderer are now the AA variables and the position >>>>>> variables >>>>>> (sx*, sy*, x*, y*). >>>>>> What I've done is I added an EdgeList class, which encapsulates >>>> all >>>>>> the edge >>>>>> related variables in the old Renderer. At first, I had an Edge >>>> class >>>>>> in addition >>>>>> to the EdgeList class, and while this was much nicer, it turned >> out >>>> to >>>>>> be too >>>>>> expensive (see last paragraph). >>>>>> I've also added a ScanLineIterator, so instead of _endRendering >>>>>> iterating >>>>>> through strips, and then calling renderStrip() which iterates >>>> through >>>>>> the >>>>>> scanlines in that strip, and then through the crossings in that >>>>>> scanline, >>>>>> what happens now is that _endRendering uses the >> Iterator >>>> to >>>>>> iterate through each scanline, get get its crossings and iterate >>>>>> through them >>>>>> to accumulate the alpha. By the way, a ScanLine is a type >> defined >>>> by >>>>>> an >>>>>> interface which exports methods for getting the y coord of the >>>> line, >>>>>> the >>>>>> number of crossings in it, the ith crossing, and a method for >>>> sorting >>>>>> its crossings. >>>>>> The class that implements ScanLine is ScanLineIterator itself. I >>>> made >>>>>> a >>>>>> ScanLine class, but I was afraid performance would suffer >> because >>>> of >>>>>> all the >>>>>> object creations (this turned out not to be an issue, after I >>>> switched >>>>>> to the >>>>>> current way, and remeasured things). I did not switch back >> because >>>>>> this is >>>>>> only slightly worse. >>>>>> >>>>>> As for performance: I wrote a simple program that tries to draw >> a >>>>>> dashed path >>>>>> that consists of about 160 dashed lines of width 1 and length >>>> 30000, >>>>>> going >>>>>> from the centre of the frame to some point. On my machine, this >>>> takes >>>>>> about 4.9 >>>>>> seconds in openjdk6, and 26 seconds using the attached file. >> Back >>>> when >>>>>> I was using >>>>>> the Edge class it took about 39 seconds. Everything without >> hundres >>>> of >>>>>> thousands of >>>>>> edges is not much slower >>>>>> I have not changed any of the algorithms. ScanLineIterator still >>>> goes >>>>>> through >>>>>> strips of the same size and computes crossings in every strip >>>> using >>>>>> the same >>>>>> method as before, so I don't know why it's so slow. It can't be >>>>>> because of anything >>>>>> happening in _endRendering, because there are only about 9000 >>>>>> scanlines and for each >>>>>> of them I've just added a few calls to one line getters (which >> used >>>> to >>>>>> be direct >>>>>> accesses into arrays). >>>>>> >>>>>> Thanks, >>>>>> Denis. >>>>>> >>>>>> ----- "Jim Graham" wrote: >>>>>> >>>>>>> Denis Lila wrote: >>>>>>>> Hello Jim. >>>>>>>> >>>>>>>> Thank you very much for taking the time to read through this. >>>>>>>> >>>>>>>>> 169 - if origLen reaches the end of the dash exactly (the >> "==" >>>>>>> case) >>>>>>>> You're right, I should. I can't just replace<= with == >>>>>> though, >>>>>>>> because the results will be the same: in the equal case >> origLen >>>>>>> will >>>>>>>> become 0, and on the next iteration, the (origLen< >>>>>> dash[idx]-phase) >>>>>>> will >>>>>>>> be true, and we will do a goTo(x1,y1), which is what we just >> did >>>>>> in >>>>>>> the >>>>>>>> previous iteration (unless dash[idx] is 0, in which case the >>>>>> results >>>>>>>> will be even worse). The best solution to this is to just do a >>>>>>> nested >>>>>>>> check for the == case. >>>>>>> Ah, right - because there is no "break" when origLen becomes >>>> zero. >>>>>>> Sounds like you're on it. >>>>>>> >>>>>>>>> 171 - Aren't x0,y0 stored as subpix values? You would then >> be >>>>>>> comparing >>>>>>>>> a subpix value to a non-subpix value. Perhaps if the subpix >>>>>> calls >>>>>>> are >>>>>>>>> moved to the top of the function I think this should work OK? >>>>>>>> That's true, they are. This is very puzzling. If a >>>> horizontal >>>>>>> line is >>>>>>>> added, when the crossings for it are being computed, dxBydy >>>> should >>>>>>> be NaN, and >>>>>>>> wouldn't an error be thrown when we try to cast to an int in >> the >>>>>>> call to addCrossing? >>>>>>> >>>>>>> I'm not sure - I didn't trace it through very far - I just >> noted >>>>>> that >>>>>>> the values were likely in different "resolutions". >>>>>>> >>>>>>>>> 194,197 - Shouldn't these be constants, or based on the >>>>>>> SUB_POS_XY? >>>>>>>> I suppose I should make a biasing constant. I don't think >>>> they >>>>>>> should be based >>>>>>>> on SUB_POS_XY though, because the biasing is done to subpixel >>>>>>> coordinates so >>>>>>>> there is no danger that if our supersampling is fine enough >> the >>>>>>> biasing will >>>>>>>> make the coordinates jump over some scan line. >>>>>>> I'm guessing you punted on my "can of worms" suggestion then. >>>> ;-) >>>>>>>>> 216 - if you save the sx0,sy0 before subpix'ing them then you >>>>>> don't >>>>>>> have >>>>>>>>> to "unsubpix" them here. (Though you still need the subpix >> sy0 >>>>>> for >>>>>>> line >>>>>>>>> 209 - or you could just call subpix on it for that line and >> at >>>>>>> least >>>>>>>>> you'd save 1 call to sub/unsub). >>>>>>>> Ok. I'll just save subpixed and unsubpixed versions of >> sx0, >>>>>> sy0. >>>>>>> That should >>>>>>>> eliminate all sx0,sy0 related calls to tosubpix and topix >> except >>>>>> in >>>>>>> moveTo. >>>>>>> >>>>>>> and lineTo. You may only need 3 of those values, though, if I >>>>>>> remember >>>>>>> my code reading well enough. >>>>>>> >>>>>>>>> 256,264 - casting to int is problematic. It truncates >> towards >>>> 0 >>>>>>> which >>>>>>>>> means negatives are ceil'd and positives are floor'd. It >> would >>>>>> be >>>>>>> best >>>>>>>>> to use floor here instead. On the other hand, if negative >>>>>> numbers >>>>>>> are >>>>>>>>> always "off the left side of the drawable" then this is moot. >>>>>>>> That's why I left it at int casting. Do you still think I >>>>>> should >>>>>>> change it >>>>>>>> to floor? >>>>>>> If you mean floor, I think it best to use floor. Unless you >> can >>>>>> prove >>>>>>> that negatives aren't really an issue and that the strange >>>>>> truncation >>>>>>> on >>>>>>> them won't be numerically a problem - but I don't think it is >>>> worth >>>>>> it >>>>>>> for this code. >>>>>>> >>>>>>>> Speaking of which, is there a good way to edit and build >> openJDK >>>>>>> from eclipse? >>>>>>>> Then this sort of embarrassing error could be avoided >> (including >>>>>> the >>>>>>> printStats() call). >>>>>>> >>>>>>> I don't use Eclipse, sorry. :-( >>>>>>> >>>>>>>> As for Arrays.newSize()... I can't find it here: >>>>>>>> >> http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/Arrays.html >>>>>>>> Is this a new function added in 7? >>>>>>> Sorry, make that Arrays.copyOf(..., newSize). I tried to type >>>> the >>>>>>> name >>>>>>> from memory and got it wrong. >>>>>>> >>>>>>>>> 721 - Arrays.sort() >>>>>>>> I thought about using this, but I did some measurements, >> and >>>>>> it >>>>>>> turns out that >>>>>>>> Arrays.sort() is a bit slower if the portion of the array >> being >>>>>>> sorted has fewer >>>>>>>> than about 70 elements. >>>>>>> I wonder what the typical number of elements is. Is this >> sorting >>>>>>> crossings per line? Then simple primitives like circles should >>>> only >>>>>>> have 2 per line, right? Is it worth testing for really small >>>>>> numbers >>>>>>> of >>>>>>> elements (much lower than 70) and doing a manual sort? Or am I >>>>>>> misunderstanding what is being sorted there? >>>>>>> >>>>>>>>> How comfortable do you feel with that conversion? >>>>>>>> I'll try to do it and include it in a new patch along with, >>>>>>> hopefully, a better way >>>>>>>> to iterate through strips, and especially crossings. Right now >>>> all >>>>>>> the iteration >>>>>>>> state is saved in global variables. This is... not good. I >> spent >>>>>> far >>>>>>> too much time last >>>>>>>> week on bugs caused by this sort of thing. Ideally, any >> members >>>>>> that >>>>>>> can't be put at >>>>>>>> the top of a class (like our edge and crossing data) should be >>>> put >>>>>>> in classes of their own. >>>>>>> >>>>>>> That sounds good, but also consider doing it in separate stages >>>> to >>>>>>> reduce churn in the code reviewing (and you then have revs to >> go >>>>>> back >>>>>>> and test which stage caused a probem if we find a bug later): >>>>>>> >>>>>>> - first get all on floats >>>>>>> - then change strip management >>>>>>> - then change to open coordinate intervals >>>>>>> - (or vice versa) >>>>>>> >>>>>>>> Do you have any ideas about how to iterate through edges in a >>>>>> strip >>>>>>> without going through >>>>>>>> every edge? I was thinking of maybe using some sort of tree to >>>>>> split >>>>>>> the drawing surface, >>>>>>>> but I haven't given it much thought. >>>>>>> If you look for something like the native code for >>>>>>> sun/java2d/pipe/ShapeSpanIterator.c you will see the way I >>>> typically >>>>>>> like to do edge setup and enumeration. >>>>>>> >>>>>>> That code uses the "half open interval" approach for both X and >> Y >>>>>>> intervals. >>>>>>> >>>>>>> I then sort the edge list by "leading Y" and then move through >>>> the >>>>>>> edges >>>>>>> using the following manner (kind of like an inch worm eating >> the >>>>>>> edges, >>>>>>> maintaining a pointer to the beginning and end of an "active >>>> list" >>>>>> of >>>>>>> edges that are in play at any given time by virtue of having >> their >>>> Y >>>>>>> range intersect the current sampling Y). Note that I use an >>>> array >>>>>> of >>>>>>> edges and then a parallel array of pointers into the edges so >> that >>>> I >>>>>>> can >>>>>>> sort just the pointers and avoid moving tons of edge data >> around. >>>>>>> Also, >>>>>>> later when I eliminate edges from the active list I just move >>>> their >>>>>>> pointers into and out of view rather than having to copy the >> edge >>>>>>> data. >>>>>>> It is harder to do an array of pointers in Java, though - >>>> perhaps >>>>>> an >>>>>>> array of indices? Here is some basic pseudocode: >>>>>>> >>>>>>> start with lo and hi pointing at index 0 in edge list. >>>>>>> until edge list is exhausted { >>>>>>> process edges between lo and hi (empty on first pass) >>>>>>> scan from hi to lo and toss any edges that are exhausted >>>>>>> (compacting remaining pointers towards hi) >>>>>>> keep incrementing hi to accept any new edges coming into >>>> play >>>>>>> process edges between lo and hi to increment to the next >> Y >>>>>>> (note that new edges from previous step may not >>>>>>> need any processing in this stage if their starting >>>>>>> Y equals the next Y to be sampled) >>>>>>> } >>>>>>> >>>>>>> Gradually lo and hi make their way through the list. The edges >>>>>> above >>>>>>> hi >>>>>>> are always sorted in order of when they may come into play as >> we >>>>>> move >>>>>>> downward in Y. The edges between lo and hi are also usually >> kept >>>>>>> sorted >>>>>>> by their current X so that the stage that processes them into >>>> spans >>>>>>> can >>>>>>> just run through them. The edges below lo are usually random >>>>>> garbage >>>>>>> because no care was taken during the "pruning" step to worry >>>> about >>>>>>> what >>>>>>> happens to the pointer table down there as lo is incremented >> (the >>>>>>> algorithm only ever looks up the array of pointers). >>>>>>> >>>>>>> I hope that helps... >>>>>>> >>>>>>> ...jim From dlila at redhat.com Thu Jul 29 21:16:40 2010 From: dlila at redhat.com (Denis Lila) Date: Thu, 29 Jul 2010 17:16:40 -0400 (EDT) Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <1534956184.1319421280438147100.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <1794487132.1319501280438200639.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hello Jim. I made the changes you point out, except for your second point (I don't have time to think about it right now). I stopped precomputing m00_2_m01_2 because it was only being used in one place. But I guess it worth it to precompute it if it's going to be used often (and computeOffset is called for every line). The new webrev is at http://icedtea.classpath.org/~dlila/webrevs/fpBetterAAv2/webrev/ Thanks, Denis. ----- "Jim Graham" wrote: > Hi Denis, > > Only some minor comments so far: > > Stroker.java: > > - Should det be precomputed and saved? (You calculate it in the > constructor anyway, but don't save it.) > - Should test for uniform scale be precomputed? > - (Is test for uniform scale too strict? Can a rotated uniform scale > > use the same code as upright uniform scale?) > - Why are m00_2_m01_2 et al no longer precomputed (they only need to > be > precomputed if scale is not uniform which isn't common)? > - lineLength method is "user space length" isn't it? - a more > descriptive name might help avoid confusion if someone is modifying > code > here later. > - line 614 - missing space > > Dasher.java: > > - Line 187 - use "leftInThisDashSegment" here? > > I still have to look at Renderer.java in depth, but I thought I'd send > > these minor comments along while they are fresh in my email buffer... > > ...jim > > Denis Lila wrote: > > Hello. > > > > And, here it is: > http://icedtea.classpath.org/~dlila/webrevs/fpBetterAA/webrev/ > > > > Just as I thought, it's way faster than the original. I made a new > > test, which is supposed to be more realistic than drawing 30000 > length > > lines. It consists of splitting a 1000x1000 frame in 100 10x10 > squares > > and in each square drawing 20 or so curves with random > start/end/control > > points in that square. In this case it's at least twice faster > (~0.85 > > versus ~1.95 seconds). > > > > Unfortunately I've had to do a lot of the same optimizations that I > was > > trying to remove (i.e. making everything a global variable). I > tried > > writing a higher level version of it, but it completely negated the > > performance gains of the new algorithm. Anyway, it's still not as > bad > > as before because the algorithm is inherently clearer and we only > iterate > > through scan lines instead of iterating through strips and then > scanlines > > in that strip, and then edges, all in the same method. > > > > It's also better organized, and logically separate parts of the code > don't > > really touch each other's variables much. And it's definitely > better > > commented. > > > > I also made some minor changes outside of Renderer that did not > appear in > > the first version of this patch last week: > > 1. I fixed the issue Jim pointed out in Dasher, where if > > (origLen == leftInThisDashSegment) the dash index was not being > incremented. > > 2. In dasher, I no longer copy the dash array. > > 3. I removed files PiscesMath.java and Transform4.java because they > are no > > longer needed. > > > > Thanks, > > Denis. > > > > ----- "Jim Graham" wrote: > > > >> Woohoo, Denis! I look forward to seeing the new version! > >> > >> ...jim > >> > >> On 7/28/2010 5:51 AM, Denis Lila wrote: > >>> Hello Jim. > >>> > >>> This one performs almost identically to what is already there > >>> in openjdk6 and 7, since it's exactly what I sent for review > >>> last week, but with all the changes you suggested implemented. > >>> > >>> I would actually like to ask you to not look at either one of > >>> them. First of all, there is an ArrayIndexOutOfBoundsException > >>> possible in emitRow. > >>> And secondly, even if there wasn't, last night I implemented > >>> your algorithm from ShapeSpanIterator.c to iterate through > >>> the edges. I have yet to debug it, but it makes everything much, > >>> much simpler, and it should make it far faster, so we get the > best > >>> of both worlds. > >>> > >>> Thanks, > >>> Denis. > >>> > >>> ----- "Jim Graham" wrote: > >>> > >>>> Hi Denis, > >>>> > >>>> I'll try to get through both versions and see if I can find > >> anything > >>>> that was hurting performance with your EdgeLists. I'm guessing > >> that > >>>> this version was created because of the performance issues you > >> found > >>>> with the EdgeList version? Does this perform more closely to > the > >>>> existing code than the EdgeList version? > >>>> > >>>> ...jim > >>>> > >>>> Denis Lila wrote: > >>>>> Hello again. > >>>>> > >>>>> This attachmet is a "can of worms" implementation without all > the > >>>> fancy (and slow) > >>>>> iteration. It also includes all of the other suggestions you > sent > >> in > >>>> your first > >>>>> review of Dasher and Renderer last week (most importantly, the > >>>> firstOrientation > >>>>> issue, horizontal lines filtering, and adding prefixes to > >> variable > >>>> names to make > >>>>> it clear whether they refer to pixels, or subpixels). > >>>>> > >>>>> Regards, > >>>>> Denis. > >>>>> > >>>>> ----- "Denis Lila" wrote: > >>>>> > >>>>>> Hello Jim. > >>>>>> > >>>>>> I implemented your "can of worms" idea. It works, and it got > rid > >>>> of > >>>>>> the biasing. > >>>>>> I wasn't able to send a webrev, but there are many changes and > a > >>>> side > >>>>>> by side > >>>>>> comparison would probably be useless, so I just attached the > >> file. > >>>> I > >>>>>> hope this is > >>>>>> ok. > >>>>>> > >>>>>> I also implemented a "better" iterating structure for the > lines > >>>> and > >>>>>> the > >>>>>> strips and crossings. I think it is better in every way, > except > >>>>>> performance. > >>>>>> The new file is more than 200 lines smaller than the old one. > >> The > >>>> only > >>>>>> members of Renderer are now the AA variables and the position > >>>>>> variables > >>>>>> (sx*, sy*, x*, y*). > >>>>>> What I've done is I added an EdgeList class, which > encapsulates > >>>> all > >>>>>> the edge > >>>>>> related variables in the old Renderer. At first, I had an Edge > >>>> class > >>>>>> in addition > >>>>>> to the EdgeList class, and while this was much nicer, it > turned > >> out > >>>> to > >>>>>> be too > >>>>>> expensive (see last paragraph). > >>>>>> I've also added a ScanLineIterator, so instead of > _endRendering > >>>>>> iterating > >>>>>> through strips, and then calling renderStrip() which iterates > >>>> through > >>>>>> the > >>>>>> scanlines in that strip, and then through the crossings in > that > >>>>>> scanline, > >>>>>> what happens now is that _endRendering uses the > >> Iterator > >>>> to > >>>>>> iterate through each scanline, get get its crossings and > iterate > >>>>>> through them > >>>>>> to accumulate the alpha. By the way, a ScanLine is a type > >> defined > >>>> by > >>>>>> an > >>>>>> interface which exports methods for getting the y coord of the > >>>> line, > >>>>>> the > >>>>>> number of crossings in it, the ith crossing, and a method for > >>>> sorting > >>>>>> its crossings. > >>>>>> The class that implements ScanLine is ScanLineIterator itself. > I > >>>> made > >>>>>> a > >>>>>> ScanLine class, but I was afraid performance would suffer > >> because > >>>> of > >>>>>> all the > >>>>>> object creations (this turned out not to be an issue, after I > >>>> switched > >>>>>> to the > >>>>>> current way, and remeasured things). I did not switch back > >> because > >>>>>> this is > >>>>>> only slightly worse. > >>>>>> > >>>>>> As for performance: I wrote a simple program that tries to > draw > >> a > >>>>>> dashed path > >>>>>> that consists of about 160 dashed lines of width 1 and length > >>>> 30000, > >>>>>> going > >>>>>> from the centre of the frame to some point. On my machine, > this > >>>> takes > >>>>>> about 4.9 > >>>>>> seconds in openjdk6, and 26 seconds using the attached file. > >> Back > >>>> when > >>>>>> I was using > >>>>>> the Edge class it took about 39 seconds. Everything without > >> hundres > >>>> of > >>>>>> thousands of > >>>>>> edges is not much slower > >>>>>> I have not changed any of the algorithms. ScanLineIterator > still > >>>> goes > >>>>>> through > >>>>>> strips of the same size and computes crossings in every strip > >>>> using > >>>>>> the same > >>>>>> method as before, so I don't know why it's so slow. It can't > be > >>>>>> because of anything > >>>>>> happening in _endRendering, because there are only about 9000 > >>>>>> scanlines and for each > >>>>>> of them I've just added a few calls to one line getters (which > >> used > >>>> to > >>>>>> be direct > >>>>>> accesses into arrays). > >>>>>> > >>>>>> Thanks, > >>>>>> Denis. > >>>>>> > >>>>>> ----- "Jim Graham" wrote: > >>>>>> > >>>>>>> Denis Lila wrote: > >>>>>>>> Hello Jim. > >>>>>>>> > >>>>>>>> Thank you very much for taking the time to read through > this. > >>>>>>>> > >>>>>>>>> 169 - if origLen reaches the end of the dash exactly (the > >> "==" > >>>>>>> case) > >>>>>>>> You're right, I should. I can't just replace<= with == > >>>>>> though, > >>>>>>>> because the results will be the same: in the equal case > >> origLen > >>>>>>> will > >>>>>>>> become 0, and on the next iteration, the (origLen< > >>>>>> dash[idx]-phase) > >>>>>>> will > >>>>>>>> be true, and we will do a goTo(x1,y1), which is what we just > >> did > >>>>>> in > >>>>>>> the > >>>>>>>> previous iteration (unless dash[idx] is 0, in which case the > >>>>>> results > >>>>>>>> will be even worse). The best solution to this is to just do > a > >>>>>>> nested > >>>>>>>> check for the == case. > >>>>>>> Ah, right - because there is no "break" when origLen becomes > >>>> zero. > >>>>>>> Sounds like you're on it. > >>>>>>> > >>>>>>>>> 171 - Aren't x0,y0 stored as subpix values? You would then > >> be > >>>>>>> comparing > >>>>>>>>> a subpix value to a non-subpix value. Perhaps if the > subpix > >>>>>> calls > >>>>>>> are > >>>>>>>>> moved to the top of the function I think this should work > OK? > >>>>>>>> That's true, they are. This is very puzzling. If a > >>>> horizontal > >>>>>>> line is > >>>>>>>> added, when the crossings for it are being computed, dxBydy > >>>> should > >>>>>>> be NaN, and > >>>>>>>> wouldn't an error be thrown when we try to cast to an int in > >> the > >>>>>>> call to addCrossing? > >>>>>>> > >>>>>>> I'm not sure - I didn't trace it through very far - I just > >> noted > >>>>>> that > >>>>>>> the values were likely in different "resolutions". > >>>>>>> > >>>>>>>>> 194,197 - Shouldn't these be constants, or based on the > >>>>>>> SUB_POS_XY? > >>>>>>>> I suppose I should make a biasing constant. I don't > think > >>>> they > >>>>>>> should be based > >>>>>>>> on SUB_POS_XY though, because the biasing is done to > subpixel > >>>>>>> coordinates so > >>>>>>>> there is no danger that if our supersampling is fine enough > >> the > >>>>>>> biasing will > >>>>>>>> make the coordinates jump over some scan line. > >>>>>>> I'm guessing you punted on my "can of worms" suggestion then. > >>>> ;-) > >>>>>>>>> 216 - if you save the sx0,sy0 before subpix'ing them then > you > >>>>>> don't > >>>>>>> have > >>>>>>>>> to "unsubpix" them here. (Though you still need the subpix > >> sy0 > >>>>>> for > >>>>>>> line > >>>>>>>>> 209 - or you could just call subpix on it for that line and > >> at > >>>>>>> least > >>>>>>>>> you'd save 1 call to sub/unsub). > >>>>>>>> Ok. I'll just save subpixed and unsubpixed versions of > >> sx0, > >>>>>> sy0. > >>>>>>> That should > >>>>>>>> eliminate all sx0,sy0 related calls to tosubpix and topix > >> except > >>>>>> in > >>>>>>> moveTo. > >>>>>>> > >>>>>>> and lineTo. You may only need 3 of those values, though, if > I > >>>>>>> remember > >>>>>>> my code reading well enough. > >>>>>>> > >>>>>>>>> 256,264 - casting to int is problematic. It truncates > >> towards > >>>> 0 > >>>>>>> which > >>>>>>>>> means negatives are ceil'd and positives are floor'd. It > >> would > >>>>>> be > >>>>>>> best > >>>>>>>>> to use floor here instead. On the other hand, if negative > >>>>>> numbers > >>>>>>> are > >>>>>>>>> always "off the left side of the drawable" then this is > moot. > >>>>>>>> That's why I left it at int casting. Do you still think > I > >>>>>> should > >>>>>>> change it > >>>>>>>> to floor? > >>>>>>> If you mean floor, I think it best to use floor. Unless you > >> can > >>>>>> prove > >>>>>>> that negatives aren't really an issue and that the strange > >>>>>> truncation > >>>>>>> on > >>>>>>> them won't be numerically a problem - but I don't think it is > >>>> worth > >>>>>> it > >>>>>>> for this code. > >>>>>>> > >>>>>>>> Speaking of which, is there a good way to edit and build > >> openJDK > >>>>>>> from eclipse? > >>>>>>>> Then this sort of embarrassing error could be avoided > >> (including > >>>>>> the > >>>>>>> printStats() call). > >>>>>>> > >>>>>>> I don't use Eclipse, sorry. :-( > >>>>>>> > >>>>>>>> As for Arrays.newSize()... I can't find it here: > >>>>>>>> > >> > http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/Arrays.html > >>>>>>>> Is this a new function added in 7? > >>>>>>> Sorry, make that Arrays.copyOf(..., newSize). I tried to > type > >>>> the > >>>>>>> name > >>>>>>> from memory and got it wrong. > >>>>>>> > >>>>>>>>> 721 - Arrays.sort() > >>>>>>>> I thought about using this, but I did some > measurements, > >> and > >>>>>> it > >>>>>>> turns out that > >>>>>>>> Arrays.sort() is a bit slower if the portion of the array > >> being > >>>>>>> sorted has fewer > >>>>>>>> than about 70 elements. > >>>>>>> I wonder what the typical number of elements is. Is this > >> sorting > >>>>>>> crossings per line? Then simple primitives like circles > should > >>>> only > >>>>>>> have 2 per line, right? Is it worth testing for really small > >>>>>> numbers > >>>>>>> of > >>>>>>> elements (much lower than 70) and doing a manual sort? Or am > I > >>>>>>> misunderstanding what is being sorted there? > >>>>>>> > >>>>>>>>> How comfortable do you feel with that conversion? > >>>>>>>> I'll try to do it and include it in a new patch along with, > >>>>>>> hopefully, a better way > >>>>>>>> to iterate through strips, and especially crossings. Right > now > >>>> all > >>>>>>> the iteration > >>>>>>>> state is saved in global variables. This is... not good. I > >> spent > >>>>>> far > >>>>>>> too much time last > >>>>>>>> week on bugs caused by this sort of thing. Ideally, any > >> members > >>>>>> that > >>>>>>> can't be put at > >>>>>>>> the top of a class (like our edge and crossing data) should > be > >>>> put > >>>>>>> in classes of their own. > >>>>>>> > >>>>>>> That sounds good, but also consider doing it in separate > stages > >>>> to > >>>>>>> reduce churn in the code reviewing (and you then have revs to > >> go > >>>>>> back > >>>>>>> and test which stage caused a probem if we find a bug later): > >>>>>>> > >>>>>>> - first get all on floats > >>>>>>> - then change strip management > >>>>>>> - then change to open coordinate intervals > >>>>>>> - (or vice versa) > >>>>>>> > >>>>>>>> Do you have any ideas about how to iterate through edges in > a > >>>>>> strip > >>>>>>> without going through > >>>>>>>> every edge? I was thinking of maybe using some sort of tree > to > >>>>>> split > >>>>>>> the drawing surface, > >>>>>>>> but I haven't given it much thought. > >>>>>>> If you look for something like the native code for > >>>>>>> sun/java2d/pipe/ShapeSpanIterator.c you will see the way I > >>>> typically > >>>>>>> like to do edge setup and enumeration. > >>>>>>> > >>>>>>> That code uses the "half open interval" approach for both X > and > >> Y > >>>>>>> intervals. > >>>>>>> > >>>>>>> I then sort the edge list by "leading Y" and then move > through > >>>> the > >>>>>>> edges > >>>>>>> using the following manner (kind of like an inch worm eating > >> the > >>>>>>> edges, > >>>>>>> maintaining a pointer to the beginning and end of an "active > >>>> list" > >>>>>> of > >>>>>>> edges that are in play at any given time by virtue of having > >> their > >>>> Y > >>>>>>> range intersect the current sampling Y). Note that I use an > >>>> array > >>>>>> of > >>>>>>> edges and then a parallel array of pointers into the edges so > >> that > >>>> I > >>>>>>> can > >>>>>>> sort just the pointers and avoid moving tons of edge data > >> around. > >>>>>>> Also, > >>>>>>> later when I eliminate edges from the active list I just move > >>>> their > >>>>>>> pointers into and out of view rather than having to copy the > >> edge > >>>>>>> data. > >>>>>>> It is harder to do an array of pointers in Java, though - > >>>> perhaps > >>>>>> an > >>>>>>> array of indices? Here is some basic pseudocode: > >>>>>>> > >>>>>>> start with lo and hi pointing at index 0 in edge list. > >>>>>>> until edge list is exhausted { > >>>>>>> process edges between lo and hi (empty on first pass) > >>>>>>> scan from hi to lo and toss any edges that are > exhausted > >>>>>>> (compacting remaining pointers towards hi) > >>>>>>> keep incrementing hi to accept any new edges coming > into > >>>> play > >>>>>>> process edges between lo and hi to increment to the > next > >> Y > >>>>>>> (note that new edges from previous step may not > >>>>>>> need any processing in this stage if their > starting > >>>>>>> Y equals the next Y to be sampled) > >>>>>>> } > >>>>>>> > >>>>>>> Gradually lo and hi make their way through the list. The > edges > >>>>>> above > >>>>>>> hi > >>>>>>> are always sorted in order of when they may come into play as > >> we > >>>>>> move > >>>>>>> downward in Y. The edges between lo and hi are also usually > >> kept > >>>>>>> sorted > >>>>>>> by their current X so that the stage that processes them into > >>>> spans > >>>>>>> can > >>>>>>> just run through them. The edges below lo are usually random > >>>>>> garbage > >>>>>>> because no care was taken during the "pruning" step to worry > >>>> about > >>>>>>> what > >>>>>>> happens to the pointer table down there as lo is incremented > >> (the > >>>>>>> algorithm only ever looks up the array of pointers). > >>>>>>> > >>>>>>> I hope that helps... > >>>>>>> > >>>>>>> ...jim From james.graham at oracle.com Fri Jul 30 00:27:17 2010 From: james.graham at oracle.com (Jim Graham) Date: Thu, 29 Jul 2010 17:27:17 -0700 Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <1794487132.1319501280438200639.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <1794487132.1319501280438200639.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C521C65.3060609@oracle.com> Hi Denis, The changes look fine and I'm moving on to Renderer.java... I'd make as many methods private as you can. It looks like all your new methods are private, but some old methods are still public even though I don't think they are accessed elsewhere (like addEdge()?). I think "private" is enough for Hotspot to inline so that should help performance a bit. I usually use "final", but I think "private" does the same thing. You should create constants for the indices into the struct to make the code more readable (and to simplify updating the EDGE layout): X0_OFF = 0 Y0_OFF = 1 // etc. I don't think you touch X0 and Y0 after initializing them and then using them for the first setCurY so you could just use them as the "curX" and "curY" and save 2 slots in the table. You initialize edges twice - once when it is declared, and once in the constructor. Note that the initialization where it is declared uses INIT_SIZE which is not a multiple of EDGE size anyway. It looks like there is a missing statement in moveTo to initialize this.x0...? I need some more time on it, but I thought I would send along these comments in the meantime... ...jim Denis Lila wrote: > Hello Jim. > > I made the changes you point out, except for your second point > (I don't have time to think about it right now). > > I stopped precomputing m00_2_m01_2 because it was only being > used in one place. But I guess it worth it to precompute it > if it's going to be used often (and computeOffset is called > for every line). > > The new webrev is at http://icedtea.classpath.org/~dlila/webrevs/fpBetterAAv2/webrev/ > > Thanks, > Denis. From lana.steuck at oracle.com Fri Jul 30 04:58:27 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Fri, 30 Jul 2010 04:58:27 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d: 7 new changesets Message-ID: <20100730045828.5458B47D8D@hg.openjdk.java.net> Changeset: 055626b50d2d Author: mikejwre Date: 2010-07-15 20:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/rev/055626b50d2d Added tag jdk7-b101 for changeset 4193eaf5f1b8 ! .hgtags Changeset: a191e79df156 Author: lana Date: 2010-06-29 10:48 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/rev/a191e79df156 Merge Changeset: 9cda7c220c08 Author: lana Date: 2010-07-12 19:35 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/rev/9cda7c220c08 Merge Changeset: a136a51f5113 Author: lana Date: 2010-07-20 22:17 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/rev/a136a51f5113 Merge Changeset: 86a3df41c0c7 Author: mikejwre Date: 2010-07-23 16:42 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/rev/86a3df41c0c7 Added tag jdk7-b102 for changeset a136a51f5113 ! .hgtags Changeset: f1ba69da5003 Author: ohair Date: 2010-07-26 14:14 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/rev/f1ba69da5003 6972274: Fix the use of egrep -ci in the top level makefile sanity checks Reviewed-by: prr ! make/sanity-rules.gmk Changeset: be2aedc4e3b1 Author: mikejwre Date: 2010-07-28 21:03 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/rev/be2aedc4e3b1 Merge From lana.steuck at oracle.com Fri Jul 30 04:58:33 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Fri, 30 Jul 2010 04:58:33 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/corba: 5 new changesets Message-ID: <20100730045837.8DB4647D8E@hg.openjdk.java.net> Changeset: d130544adab3 Author: mikejwre Date: 2010-07-15 20:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/corba/rev/d130544adab3 Added tag jdk7-b101 for changeset 86a239832646 ! .hgtags Changeset: 03fd3d78e344 Author: lana Date: 2010-06-29 10:48 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/corba/rev/03fd3d78e344 Merge Changeset: 98da66f47273 Author: lana Date: 2010-07-12 19:35 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/corba/rev/98da66f47273 Merge Changeset: 78561a957790 Author: lana Date: 2010-07-20 22:17 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/corba/rev/78561a957790 Merge Changeset: 11e7678c3eb1 Author: mikejwre Date: 2010-07-23 16:42 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/corba/rev/11e7678c3eb1 Added tag jdk7-b102 for changeset 78561a957790 ! .hgtags From lana.steuck at oracle.com Fri Jul 30 05:03:54 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Fri, 30 Jul 2010 05:03:54 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/hotspot: 53 new changesets Message-ID: <20100730050524.F17CC47D8F@hg.openjdk.java.net> Changeset: 75b254ea860e Author: mikejwre Date: 2010-07-15 20:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/75b254ea860e Added tag jdk7-b101 for changeset 6c3a919105b6 ! .hgtags Changeset: 136b78722a08 Author: jrose Date: 2010-06-09 18:50 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/136b78722a08 6939203: JSR 292 needs method handle constants Summary: Add new CP types CONSTANT_MethodHandle, CONSTANT_MethodType; extend 'ldc' bytecode. Reviewed-by: twisti, never ! agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeDisassembler.java ! agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeInvoke.java ! agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java ! agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeWithCPIndex.java ! agent/src/share/classes/sun/jvm/hotspot/interpreter/Bytecodes.java ! agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java ! agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCache.java ! agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCacheEntry.java ! agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java ! agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java ! agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java ! agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java ! agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java ! agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java ! agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js ! src/cpu/sparc/vm/templateTable_sparc.cpp ! src/cpu/x86/vm/templateTable_x86_32.cpp ! src/cpu/x86/vm/templateTable_x86_64.cpp ! src/share/vm/c1/c1_GraphBuilder.cpp ! src/share/vm/c1/c1_Runtime1.cpp ! src/share/vm/ci/ciCPCache.cpp ! src/share/vm/ci/ciCPCache.hpp ! src/share/vm/ci/ciClassList.hpp ! src/share/vm/ci/ciEnv.cpp ! src/share/vm/ci/ciEnv.hpp ! src/share/vm/ci/ciInstanceKlass.cpp ! src/share/vm/ci/ciObjectFactory.cpp ! src/share/vm/ci/ciObjectFactory.hpp ! src/share/vm/ci/ciStreams.cpp ! src/share/vm/ci/ciStreams.hpp ! src/share/vm/classfile/classFileParser.cpp ! src/share/vm/classfile/systemDictionary.cpp ! src/share/vm/classfile/systemDictionary.hpp ! src/share/vm/classfile/verifier.cpp ! src/share/vm/classfile/verifier.hpp ! src/share/vm/classfile/vmSymbols.hpp ! src/share/vm/code/nmethod.cpp ! src/share/vm/includeDB_core ! src/share/vm/interpreter/bytecode.cpp ! src/share/vm/interpreter/bytecode.hpp ! src/share/vm/interpreter/bytecodeTracer.cpp ! src/share/vm/interpreter/bytecodes.cpp ! src/share/vm/interpreter/bytecodes.hpp ! src/share/vm/interpreter/interpreter.cpp ! src/share/vm/interpreter/interpreterRuntime.cpp ! src/share/vm/interpreter/interpreterRuntime.hpp ! src/share/vm/interpreter/rewriter.cpp ! src/share/vm/interpreter/rewriter.hpp ! src/share/vm/interpreter/templateTable.cpp ! src/share/vm/interpreter/templateTable.hpp ! src/share/vm/oops/constantPoolKlass.cpp ! src/share/vm/oops/constantPoolOop.cpp ! src/share/vm/oops/constantPoolOop.hpp ! src/share/vm/oops/cpCacheOop.hpp ! src/share/vm/opto/parse2.cpp ! src/share/vm/prims/jvm.h ! src/share/vm/prims/methodComparator.cpp ! src/share/vm/runtime/sharedRuntime.cpp ! src/share/vm/utilities/constantTag.cpp ! src/share/vm/utilities/constantTag.hpp Changeset: d93949c5bdcc Author: kvn Date: 2010-06-10 13:04 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/d93949c5bdcc 6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86 Summary: Modify assembler code to check for 0 count for all copy routines. Reviewed-by: never, ysr, jcoomes ! src/os_cpu/linux_x86/vm/copy_linux_x86.inline.hpp ! src/os_cpu/linux_x86/vm/linux_x86_32.s ! src/os_cpu/solaris_x86/vm/solaris_x86_32.s ! src/share/vm/asm/codeBuffer.cpp ! src/share/vm/c1/c1_Runtime1.cpp ! src/share/vm/interpreter/interpreterRuntime.cpp ! src/share/vm/runtime/stubRoutines.cpp ! src/share/vm/runtime/thread.cpp ! src/share/vm/runtime/vframeArray.cpp ! src/share/vm/utilities/copy.cpp ! src/share/vm/utilities/copy.hpp Changeset: b918d354830a Author: jrose Date: 2010-06-12 22:53 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/b918d354830a 6960865: ldc of unloaded class throws an assert in ciTypeFlow Summary: Support java_mirror for unloaded klasses, arrays as well as instances. Simplify ciTypeFlow by removing unused path. Reviewed-by: kvn ! src/share/vm/ci/ciInstanceKlass.cpp ! src/share/vm/ci/ciKlass.cpp ! src/share/vm/ci/ciTypeFlow.cpp Changeset: d179e225c164 Author: twisti Date: 2010-06-14 00:52 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/d179e225c164 6960550: Missing semicolon in Zero Summary: There is a missing semicolon in cppInterpreter_zero.cpp. Reviewed-by: twisti Contributed-by: Gary Benson ! src/cpu/zero/vm/cppInterpreter_zero.cpp Changeset: 0b4ee1df1b44 Author: never Date: 2010-06-15 12:03 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/0b4ee1df1b44 6952176: Remove debug flag from adlc makefile for 6Update trains Reviewed-by: kvn, twisti ! make/linux/makefiles/adlc.make Changeset: 78fc92dfd4ca Author: never Date: 2010-06-15 12:06 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/78fc92dfd4ca Merge Changeset: 2389669474a6 Author: jrose Date: 2010-06-15 15:57 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/2389669474a6 Merge ! src/share/vm/classfile/classFileParser.cpp ! src/share/vm/runtime/thread.cpp Changeset: 4311f23817fd Author: kvn Date: 2010-06-15 18:07 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/4311f23817fd 6959430: Make sure raw loads have control edge Summary: check that raw loads have control edge Reviewed-by: never, twisti ! src/share/vm/opto/compile.cpp ! src/share/vm/opto/graphKit.cpp ! src/share/vm/opto/library_call.cpp ! src/share/vm/opto/macro.cpp ! src/share/vm/opto/memnode.cpp ! src/share/vm/opto/memnode.hpp ! src/share/vm/opto/parse1.cpp Changeset: 79107c3a6bd5 Author: tonyp Date: 2010-05-07 13:14 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/79107c3a6bd5 6949307: G1: raise a vm error, do not core dump, if target pause time and target interval are inconsistent Summary: First, change the guarantee to raising a vm error. Second, set the interval dynamically, and based on the pause time target, if it is not set explicitly. Reviewed-by: ysr, johnc ! src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp ! src/share/vm/runtime/arguments.cpp ! src/share/vm/runtime/globals.hpp Changeset: 215576b54709 Author: tonyp Date: 2010-04-22 15:20 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/215576b54709 6946048: G1: improvements to +PrintGCDetails output Summary: Small improvements to G1's PrintGCDetails output. It also includes minor formatting details. Reviewed-by: ysr, johnc ! src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp ! src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp ! src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp ! src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp ! src/share/vm/gc_implementation/g1/g1RemSet.cpp Changeset: fdde661c8e06 Author: jmasa Date: 2010-06-23 08:35 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008 Summary: Shrinking of a generation and the corresponding card table was causing part of the card table to be uncommitted. Reviewed-by: jcoomes ! src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp ! src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp ! src/share/vm/memory/cardTableModRefBS.cpp Changeset: 0d781caf0cbb Author: jmasa Date: 2010-06-23 15:17 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/0d781caf0cbb Merge Changeset: b8537b881421 Author: jmasa Date: 2010-06-24 15:56 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/b8537b881421 Merge Changeset: ff38d05ea86f Author: never Date: 2010-06-18 16:51 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/ff38d05ea86f 6956958: assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted() || is_optimized() || is_megam Reviewed-by: kvn ! src/share/vm/runtime/sweeper.cpp ! src/share/vm/runtime/sweeper.hpp Changeset: 38e8278318ca Author: never Date: 2010-06-21 14:26 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/38e8278318ca 6656830: assert((*p)->is_oop(),"expected an oop while scanning weak refs") Reviewed-by: dcubed, kvn, twisti ! src/share/vm/code/nmethod.cpp ! src/share/vm/code/nmethod.hpp ! src/share/vm/prims/jvmtiCodeBlobEvents.cpp ! src/share/vm/runtime/jniHandles.cpp Changeset: 9887b5e57f9e Author: iveresov Date: 2010-06-22 12:10 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/9887b5e57f9e 6962980: C1: stub area should take into account method handle deopt stub Reviewed-by: twisti, never ! src/share/vm/c1/c1_Compilation.cpp Changeset: 5f249b390094 Author: kvn Date: 2010-06-23 09:40 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/5f249b390094 6947341: JVM Crash running Oracle ATG CRMDemo Summary: Missing protected page below heap with compressed oops on Linux with large pages use. Reviewed-by: never, phh, jcoomes ! src/share/vm/runtime/virtualspace.cpp Changeset: 5a297ea605c7 Author: jrose Date: 2010-06-26 00:19 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/5a297ea605c7 Merge Changeset: d678e3277048 Author: kvn Date: 2010-06-28 10:52 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/d678e3277048 6964479: widen normalization of small int and long values should be symmetric Summary: normalize widen value in xmeet() and xdual() methods for types Int and Long so the type meet will be symmetric. Reviewed-by: jrose ! src/share/vm/opto/type.cpp Changeset: 6027dddc26c6 Author: kvn Date: 2010-06-28 14:54 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/6027dddc26c6 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist() Summary: Use replace_node() method instead of subsume_node(). Reviewed-by: jrose, never ! src/share/vm/opto/cfgnode.cpp ! src/share/vm/opto/ifnode.cpp ! src/share/vm/opto/loopTransform.cpp ! src/share/vm/opto/loopnode.cpp ! src/share/vm/opto/loopnode.hpp ! src/share/vm/opto/loopopts.cpp ! src/share/vm/opto/macro.cpp ! src/share/vm/opto/phaseX.cpp ! src/share/vm/opto/phaseX.hpp ! src/share/vm/opto/split_if.cpp ! src/share/vm/opto/superword.cpp Changeset: 76efbe666d6c Author: kvn Date: 2010-06-29 10:34 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/76efbe666d6c 6964774: Adjust optimization flags setting Summary: Adjust performance flags settings. Reviewed-by: never, phh ! src/cpu/x86/vm/vm_version_x86.cpp ! src/cpu/x86/vm/vm_version_x86.hpp ! src/share/vm/runtime/arguments.cpp Changeset: fcbb92a1ab3b Author: jrose Date: 2010-06-29 16:09 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/fcbb92a1ab3b Merge ! src/share/vm/runtime/arguments.cpp Changeset: 726b40449bd2 Author: zgu Date: 2010-06-22 09:46 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/726b40449bd2 6939019: Source code adjustments for parfait compilation of hotspot Summary: Minor source code adjustments for parfait compilation, since it uses different compiler vs. JDK Reviewed-by: never, kamg ! src/os/solaris/vm/osThread_solaris.hpp ! src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Changeset: 3e351982aac7 Author: zgu Date: 2010-06-22 10:03 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/3e351982aac7 Merge Changeset: 1a11430e0326 Author: jcoomes Date: 2010-06-24 15:38 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/1a11430e0326 6888573: class data sharing does not always disable large pages Reviewed-by: phh ! src/share/vm/memory/genCollectedHeap.cpp ! src/share/vm/runtime/arguments.cpp Changeset: c5f1ea9e15e8 Author: coleenp Date: 2010-06-28 12:03 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/c5f1ea9e15e8 Merge ! src/share/vm/runtime/arguments.cpp Changeset: a00567c82f02 Author: coleenp Date: 2010-06-30 11:52 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/a00567c82f02 Merge ! src/share/vm/runtime/arguments.cpp Changeset: 871d2aa321f7 Author: trims Date: 2010-07-02 01:36 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/871d2aa321f7 Merge Changeset: 7cc68a696c62 Author: trims Date: 2010-07-02 01:37 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/7cc68a696c62 6966252: Bump the HS19 build number to 04 Summary: Update the HS19 build number to 04 Reviewed-by: jcoomes ! make/hotspot_version Changeset: 56cc7e01da2f Author: trims Date: 2010-07-09 00:31 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/56cc7e01da2f Added tag hs19-b03 for changeset ad1977f08c4d ! .hgtags Changeset: 1dbaff4aa23a Author: trims Date: 2010-07-09 00:32 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/1dbaff4aa23a Merge Changeset: 65b0c03b165d Author: never Date: 2010-07-02 15:01 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/65b0c03b165d 6965671: fatal error: acquiring lock JNIGlobalHandle_lock/16 out of order with lock CodeCache_lock/1 Reviewed-by: kvn, dcubed ! src/share/vm/prims/jvmtiCodeBlobEvents.cpp Changeset: 60a14ad85270 Author: kvn Date: 2010-07-02 17:30 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/60a14ad85270 6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP Summary: Execute IGVN optimization before and after Escape Analysis Reviewed-by: never ! src/share/vm/opto/callnode.cpp ! src/share/vm/opto/compile.cpp ! src/share/vm/opto/compile.hpp ! src/share/vm/opto/escape.cpp ! src/share/vm/opto/escape.hpp Changeset: a693e51ac197 Author: never Date: 2010-07-07 12:40 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/a693e51ac197 Merge Changeset: cf647374e044 Author: trims Date: 2010-07-09 00:35 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/cf647374e044 Merge Changeset: a2b581345549 Author: trims Date: 2010-07-15 19:51 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/a2b581345549 Merge ! .hgtags Changeset: b2a00dd3117c Author: jcoomes Date: 2010-07-01 21:40 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/b2a00dd3117c 6957084: simplify TaskQueue overflow handling Reviewed-by: ysr, jmasa ! src/share/vm/gc_implementation/includeDB_gc_parallelScavenge ! src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp ! src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp ! src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.inline.hpp ! src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp ! src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp ! src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp ! src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp ! src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp ! src/share/vm/utilities/taskqueue.cpp ! src/share/vm/utilities/taskqueue.hpp Changeset: 9ee05c8ab82f Author: ysr Date: 2010-07-12 12:53 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/9ee05c8ab82f Merge Changeset: bfc89697cccb Author: acorn Date: 2010-07-02 17:23 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/bfc89697cccb 6964164: MonitorInUseLists leak of contended objects Summary: fix MonitorInUseLists memory leak and MonitorBound now works Reviewed-by: chrisphi, dice ! src/share/vm/runtime/synchronizer.cpp ! src/share/vm/runtime/synchronizer.hpp ! src/share/vm/runtime/thread.hpp Changeset: 5087ecc10458 Author: acorn Date: 2010-07-07 14:12 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/5087ecc10458 Merge Changeset: 0e7d2a08b605 Author: mchung Date: 2010-07-07 15:35 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/0e7d2a08b605 6967423: Hotspot support for modules image Summary: Add hotspot support for modules image Reviewed-by: acorn ! make/linux/makefiles/sa.make ! make/solaris/makefiles/sa.make ! src/os/linux/vm/os_linux.cpp ! src/os/solaris/vm/os_solaris.cpp ! src/share/vm/runtime/os.cpp Changeset: 1e7ec26380bd Author: apangin Date: 2010-07-14 17:52 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/1e7ec26380bd Merge Changeset: 2a47bd84841f Author: never Date: 2010-07-08 14:29 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/2a47bd84841f 6965184: possible races in make_not_entrant_or_zombie Reviewed-by: kvn ! agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java - src/os/linux/vm/vtune_linux.cpp - src/os/solaris/vm/vtune_solaris.cpp - src/os/windows/vm/vtune_windows.cpp ! src/share/vm/classfile/classLoader.cpp ! src/share/vm/code/codeBlob.cpp ! src/share/vm/code/codeCache.cpp ! src/share/vm/code/codeCache.hpp ! src/share/vm/code/nmethod.cpp ! src/share/vm/code/nmethod.hpp ! src/share/vm/code/vtableStubs.cpp ! src/share/vm/includeDB_core ! src/share/vm/interpreter/interpreter.cpp ! src/share/vm/runtime/globals.hpp ! src/share/vm/runtime/init.cpp ! src/share/vm/runtime/java.cpp ! src/share/vm/runtime/sharedRuntime.cpp ! src/share/vm/runtime/stubCodeGenerator.cpp ! src/share/vm/runtime/sweeper.cpp ! src/share/vm/runtime/sweeper.hpp ! src/share/vm/runtime/vmStructs.cpp - src/share/vm/runtime/vtune.hpp Changeset: 3941674cc7fa Author: never Date: 2010-07-12 10:58 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/3941674cc7fa 6958668: repeated uncommon trapping for new of klass which is being initialized Reviewed-by: kvn, jrose ! src/share/vm/ci/ciInstanceKlass.cpp ! src/share/vm/ci/ciInstanceKlass.hpp ! src/share/vm/opto/doCall.cpp ! src/share/vm/opto/parse.hpp ! src/share/vm/opto/parseHelper.cpp Changeset: 8d5934a77f10 Author: never Date: 2010-07-12 22:27 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/8d5934a77f10 6968385: malformed xml in sweeper logging Reviewed-by: kvn ! src/share/vm/runtime/sweeper.cpp Changeset: 079980c86f33 Author: kvn Date: 2010-07-14 14:29 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/079980c86f33 6968646: JVM crashes with SIGFPE during startup Summary: Check that cpuid returns valid values for processor topology (not zeros). Reviewed-by: never, twisti ! src/cpu/x86/vm/vm_version_x86.hpp Changeset: 8099e71601df Author: kvn Date: 2010-07-14 14:47 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/8099e71601df 6968368: SIGSEGV in the BCEscapeAnalyzer::copy_dependencies Summary: Use GrowableArray and VectorSet allocated in ciEnv arena. Reviewed-by: never, twisti ! src/share/vm/ci/bcEscapeAnalyzer.cpp ! src/share/vm/ci/bcEscapeAnalyzer.hpp ! src/share/vm/ci/ciMethod.cpp ! src/share/vm/ci/ciMethod.hpp ! src/share/vm/includeDB_compiler2 ! src/share/vm/includeDB_core Changeset: a528509c992b Author: never Date: 2010-07-15 08:54 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/a528509c992b 6968336: VM crash guarantee(!nm->is_zombie()) failed: cannot lock a zombie method Reviewed-by: twisti ! src/share/vm/prims/jvmtiCodeBlobEvents.cpp Changeset: 61fdaf88f57f Author: never Date: 2010-07-15 13:48 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/61fdaf88f57f Merge - src/os/linux/vm/vtune_linux.cpp - src/os/solaris/vm/vtune_solaris.cpp - src/os/windows/vm/vtune_windows.cpp - src/share/vm/runtime/vtune.hpp Changeset: e55900b5c1b8 Author: trims Date: 2010-07-15 19:52 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/e55900b5c1b8 Merge - src/os/linux/vm/vtune_linux.cpp - src/os/solaris/vm/vtune_solaris.cpp - src/os/windows/vm/vtune_windows.cpp - src/share/vm/runtime/vtune.hpp Changeset: c5cadf1a0771 Author: trims Date: 2010-07-20 18:13 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/c5cadf1a0771 Merge ! .hgtags Changeset: cb4250ef73b2 Author: mikejwre Date: 2010-07-23 16:42 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/hotspot/rev/cb4250ef73b2 Added tag jdk7-b102 for changeset c5cadf1a0771 ! .hgtags From lana.steuck at oracle.com Fri Jul 30 05:12:45 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Fri, 30 Jul 2010 05:12:45 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/jaxp: 6 new changesets Message-ID: <20100730051245.CC36747D90@hg.openjdk.java.net> Changeset: c9bd73f6d584 Author: mikejwre Date: 2010-07-15 20:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxp/rev/c9bd73f6d584 Added tag jdk7-b101 for changeset 17f62a566a20 ! .hgtags Changeset: 34ed99f84832 Author: ohair Date: 2010-06-24 08:34 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxp/rev/34ed99f84832 6963941: Correct download link for source drop bundle Reviewed-by: darcy ! jaxp.properties Changeset: e46c304486c0 Author: lana Date: 2010-06-29 10:49 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxp/rev/e46c304486c0 Merge Changeset: 70c8a34e2eb6 Author: lana Date: 2010-07-12 19:37 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxp/rev/70c8a34e2eb6 Merge Changeset: 15573625af97 Author: lana Date: 2010-07-20 22:17 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxp/rev/15573625af97 Merge Changeset: b7722e878864 Author: mikejwre Date: 2010-07-23 16:42 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxp/rev/b7722e878864 Added tag jdk7-b102 for changeset 15573625af97 ! .hgtags From lana.steuck at oracle.com Fri Jul 30 05:12:51 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Fri, 30 Jul 2010 05:12:51 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/jaxws: 5 new changesets Message-ID: <20100730051251.2D47547D91@hg.openjdk.java.net> Changeset: d1525c38428a Author: mikejwre Date: 2010-07-15 20:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxws/rev/d1525c38428a Added tag jdk7-b101 for changeset b55ce2744900 ! .hgtags Changeset: 2dd6394ddec2 Author: lana Date: 2010-06-29 10:49 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxws/rev/2dd6394ddec2 Merge Changeset: 2b7a1ec9562e Author: lana Date: 2010-07-12 19:37 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxws/rev/2b7a1ec9562e Merge Changeset: d8580443d181 Author: lana Date: 2010-07-20 22:17 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxws/rev/d8580443d181 Merge Changeset: 267386d6b923 Author: mikejwre Date: 2010-07-23 16:42 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jaxws/rev/267386d6b923 Added tag jdk7-b102 for changeset d8580443d181 ! .hgtags From lana.steuck at oracle.com Fri Jul 30 05:14:43 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Fri, 30 Jul 2010 05:14:43 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/jdk: 74 new changesets Message-ID: <20100730052631.EA0DF47D93@hg.openjdk.java.net> Changeset: d58354a69011 Author: bpatel Date: 2010-07-14 15:42 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/d58354a69011 6955341: Oracle rebranding changes for man pages Reviewed-by: darcy ! src/linux/doc/man/appletviewer.1 ! src/linux/doc/man/apt.1 ! src/linux/doc/man/extcheck.1 ! src/linux/doc/man/idlj.1 ! src/linux/doc/man/ja/appletviewer.1 ! src/linux/doc/man/ja/apt.1 ! src/linux/doc/man/ja/extcheck.1 ! src/linux/doc/man/ja/idlj.1 ! src/linux/doc/man/ja/jar.1 ! src/linux/doc/man/ja/jarsigner.1 ! src/linux/doc/man/ja/java.1 ! src/linux/doc/man/ja/javac.1 ! src/linux/doc/man/ja/javadoc.1 ! src/linux/doc/man/ja/javah.1 ! src/linux/doc/man/ja/javap.1 ! src/linux/doc/man/ja/javaws.1 ! src/linux/doc/man/ja/jconsole.1 ! src/linux/doc/man/ja/jdb.1 ! src/linux/doc/man/ja/jhat.1 ! src/linux/doc/man/ja/jinfo.1 ! src/linux/doc/man/ja/jmap.1 ! src/linux/doc/man/ja/jps.1 ! src/linux/doc/man/ja/jrunscript.1 ! src/linux/doc/man/ja/jsadebugd.1 ! src/linux/doc/man/ja/jstack.1 ! src/linux/doc/man/ja/jstat.1 ! src/linux/doc/man/ja/jstatd.1 ! src/linux/doc/man/ja/keytool.1 - src/linux/doc/man/ja/kinit.1 - src/linux/doc/man/ja/klist.1 - src/linux/doc/man/ja/ktab.1 ! src/linux/doc/man/ja/native2ascii.1 ! src/linux/doc/man/ja/orbd.1 ! src/linux/doc/man/ja/pack200.1 ! src/linux/doc/man/ja/policytool.1 ! src/linux/doc/man/ja/rmic.1 ! src/linux/doc/man/ja/rmid.1 ! src/linux/doc/man/ja/rmiregistry.1 ! src/linux/doc/man/ja/schemagen.1 ! src/linux/doc/man/ja/serialver.1 ! src/linux/doc/man/ja/servertool.1 ! src/linux/doc/man/ja/tnameserv.1 ! src/linux/doc/man/ja/unpack200.1 ! src/linux/doc/man/ja/wsgen.1 ! src/linux/doc/man/ja/wsimport.1 ! src/linux/doc/man/ja/xjc.1 ! src/linux/doc/man/jar.1 ! src/linux/doc/man/jarsigner.1 ! src/linux/doc/man/java.1 ! src/linux/doc/man/javac.1 ! src/linux/doc/man/javadoc.1 ! src/linux/doc/man/javah.1 ! src/linux/doc/man/javap.1 ! src/linux/doc/man/javaws.1 ! src/linux/doc/man/jconsole.1 ! src/linux/doc/man/jdb.1 ! src/linux/doc/man/jhat.1 ! src/linux/doc/man/jinfo.1 ! src/linux/doc/man/jmap.1 ! src/linux/doc/man/jps.1 ! src/linux/doc/man/jrunscript.1 ! src/linux/doc/man/jsadebugd.1 ! src/linux/doc/man/jstack.1 ! src/linux/doc/man/jstat.1 ! src/linux/doc/man/jstatd.1 ! src/linux/doc/man/keytool.1 ! src/linux/doc/man/native2ascii.1 ! src/linux/doc/man/orbd.1 ! src/linux/doc/man/pack200.1 ! src/linux/doc/man/policytool.1 ! src/linux/doc/man/rmic.1 ! src/linux/doc/man/rmid.1 ! src/linux/doc/man/rmiregistry.1 ! src/linux/doc/man/schemagen.1 ! src/linux/doc/man/serialver.1 ! src/linux/doc/man/servertool.1 ! src/linux/doc/man/tnameserv.1 ! src/linux/doc/man/unpack200.1 ! src/linux/doc/man/wsgen.1 ! src/linux/doc/man/wsimport.1 ! src/linux/doc/man/xjc.1 ! src/solaris/doc/sun/man/man1/appletviewer.1 ! src/solaris/doc/sun/man/man1/apt.1 ! src/solaris/doc/sun/man/man1/extcheck.1 ! src/solaris/doc/sun/man/man1/idlj.1 ! src/solaris/doc/sun/man/man1/ja/appletviewer.1 ! src/solaris/doc/sun/man/man1/ja/apt.1 ! src/solaris/doc/sun/man/man1/ja/extcheck.1 ! src/solaris/doc/sun/man/man1/ja/idlj.1 ! src/solaris/doc/sun/man/man1/ja/jar.1 ! src/solaris/doc/sun/man/man1/ja/jarsigner.1 ! src/solaris/doc/sun/man/man1/ja/java.1 ! src/solaris/doc/sun/man/man1/ja/javac.1 ! src/solaris/doc/sun/man/man1/ja/javadoc.1 ! src/solaris/doc/sun/man/man1/ja/javah.1 ! src/solaris/doc/sun/man/man1/ja/javap.1 ! src/solaris/doc/sun/man/man1/ja/javaws.1 ! src/solaris/doc/sun/man/man1/ja/jconsole.1 ! src/solaris/doc/sun/man/man1/ja/jdb.1 ! src/solaris/doc/sun/man/man1/ja/jhat.1 ! src/solaris/doc/sun/man/man1/ja/jinfo.1 ! src/solaris/doc/sun/man/man1/ja/jmap.1 ! src/solaris/doc/sun/man/man1/ja/jps.1 ! src/solaris/doc/sun/man/man1/ja/jrunscript.1 ! src/solaris/doc/sun/man/man1/ja/jsadebugd.1 ! src/solaris/doc/sun/man/man1/ja/jstack.1 ! src/solaris/doc/sun/man/man1/ja/jstat.1 ! src/solaris/doc/sun/man/man1/ja/jstatd.1 ! src/solaris/doc/sun/man/man1/ja/keytool.1 ! src/solaris/doc/sun/man/man1/ja/native2ascii.1 ! src/solaris/doc/sun/man/man1/ja/orbd.1 ! src/solaris/doc/sun/man/man1/ja/pack200.1 ! src/solaris/doc/sun/man/man1/ja/policytool.1 ! src/solaris/doc/sun/man/man1/ja/rmic.1 ! src/solaris/doc/sun/man/man1/ja/rmid.1 ! src/solaris/doc/sun/man/man1/ja/rmiregistry.1 ! src/solaris/doc/sun/man/man1/ja/schemagen.1 ! src/solaris/doc/sun/man/man1/ja/serialver.1 ! src/solaris/doc/sun/man/man1/ja/servertool.1 ! src/solaris/doc/sun/man/man1/ja/tnameserv.1 ! src/solaris/doc/sun/man/man1/ja/unpack200.1 ! src/solaris/doc/sun/man/man1/ja/wsgen.1 ! src/solaris/doc/sun/man/man1/ja/wsimport.1 ! src/solaris/doc/sun/man/man1/ja/xjc.1 ! src/solaris/doc/sun/man/man1/jar.1 ! src/solaris/doc/sun/man/man1/jarsigner.1 ! src/solaris/doc/sun/man/man1/java.1 ! src/solaris/doc/sun/man/man1/javac.1 ! src/solaris/doc/sun/man/man1/javadoc.1 ! src/solaris/doc/sun/man/man1/javah.1 ! src/solaris/doc/sun/man/man1/javap.1 ! src/solaris/doc/sun/man/man1/javaws.1 ! src/solaris/doc/sun/man/man1/jconsole.1 ! src/solaris/doc/sun/man/man1/jdb.1 ! src/solaris/doc/sun/man/man1/jhat.1 ! src/solaris/doc/sun/man/man1/jinfo.1 ! src/solaris/doc/sun/man/man1/jmap.1 ! src/solaris/doc/sun/man/man1/jps.1 ! src/solaris/doc/sun/man/man1/jrunscript.1 ! src/solaris/doc/sun/man/man1/jsadebugd.1 ! src/solaris/doc/sun/man/man1/jstack.1 ! src/solaris/doc/sun/man/man1/jstat.1 ! src/solaris/doc/sun/man/man1/jstatd.1 ! src/solaris/doc/sun/man/man1/keytool.1 ! src/solaris/doc/sun/man/man1/native2ascii.1 ! src/solaris/doc/sun/man/man1/orbd.1 ! src/solaris/doc/sun/man/man1/pack200.1 ! src/solaris/doc/sun/man/man1/policytool.1 ! src/solaris/doc/sun/man/man1/rmic.1 ! src/solaris/doc/sun/man/man1/rmid.1 ! src/solaris/doc/sun/man/man1/rmiregistry.1 ! src/solaris/doc/sun/man/man1/schemagen.1 ! src/solaris/doc/sun/man/man1/serialver.1 ! src/solaris/doc/sun/man/man1/servertool.1 ! src/solaris/doc/sun/man/man1/tnameserv.1 ! src/solaris/doc/sun/man/man1/unpack200.1 ! src/solaris/doc/sun/man/man1/wsgen.1 ! src/solaris/doc/sun/man/man1/wsimport.1 ! src/solaris/doc/sun/man/man1/xjc.1 Changeset: 6c4450bbad6d Author: mikejwre Date: 2010-07-15 20:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/6c4450bbad6d Added tag jdk7-b101 for changeset d58354a69011 ! .hgtags Changeset: 4a639bcd3361 Author: lana Date: 2010-07-12 19:32 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/4a639bcd3361 Merge Changeset: f5145c7119c2 Author: yan Date: 2010-06-24 11:50 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/f5145c7119c2 6957166: With XAWT, set arguments properly creating a MouseWheelEvent. Summary: swap some parameters to allow bigger values for click count. Reviewed-by: dav ! src/solaris/classes/sun/awt/X11/XWindow.java Changeset: bccf2a4ee318 Author: art Date: 2010-07-06 17:59 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/bccf2a4ee318 6424157: java.awt.EventQueue push/pop might cause threading issues Reviewed-by: ant, dcherepanov ! src/share/classes/java/awt/EventDispatchThread.java ! src/share/classes/java/awt/EventQueue.java ! src/share/classes/sun/awt/SunToolkit.java ! test/java/awt/EventDispatchThread/HandleExceptionOnEDT/HandleExceptionOnEDT.java ! test/java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.java + test/java/awt/EventDispatchThread/PreserveDispathThread/PreserveDispatchThread.java ! test/java/awt/EventQueue/PushPopDeadlock2/PushPopTest.java Changeset: 21b17c64df74 Author: dcherepanov Date: 2010-07-06 18:23 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/21b17c64df74 6966643: GTK FileDialog hangs when user manually closes it Reviewed-by: art ! src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c Changeset: 9950dc616615 Author: dcherepanov Date: 2010-07-07 14:20 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/9950dc616615 6959174: Need to introduce sun.awt.disableGtkFileDialogs system property Reviewed-by: art, anthony ! src/share/classes/sun/awt/SunToolkit.java ! src/solaris/classes/sun/awt/X11/XToolkit.java Changeset: 48aa2a1edd2b Author: lana Date: 2010-07-08 11:28 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/48aa2a1edd2b Merge Changeset: 2d8f060dd1c5 Author: lana Date: 2010-07-12 19:33 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/2d8f060dd1c5 Merge Changeset: 69ddf06e616a Author: malenkov Date: 2010-06-22 12:06 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/69ddf06e616a 6707234: Method returned by Introspector.internalFindMethod not necessarily most specific Reviewed-by: peterz ! src/share/classes/com/sun/beans/finder/MethodFinder.java ! src/share/classes/java/beans/EventSetDescriptor.java ! src/share/classes/java/beans/IndexedPropertyDescriptor.java ! src/share/classes/java/beans/Introspector.java ! src/share/classes/java/beans/MethodDescriptor.java ! src/share/classes/java/beans/PropertyDescriptor.java + test/java/beans/Introspector/Test6707234.java Changeset: 5af3b0430bbe Author: peterz Date: 2010-06-22 14:36 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/5af3b0430bbe 6959260: javax/swing/JLabel/6501991/bug6501991.java failed on build 1.7.0-ea-b96 Reviewed-by: rupashka ! src/share/classes/sun/swing/SwingUtilities2.java ! test/ProblemList.txt ! test/com/sun/java/swing/plaf/gtk/Test6635110.java Changeset: dea63f6dda7a Author: alexp Date: 2010-06-22 19:38 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/dea63f6dda7a 6777378: NullPointerException in XPDefaultRenderer.paint() Reviewed-by: rupashka ! src/share/classes/javax/swing/plaf/basic/BasicTableHeaderUI.java + test/javax/swing/JTable/6777378/bug6777378.java Changeset: a05e047c5b98 Author: alexp Date: 2010-06-22 20:36 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/a05e047c5b98 6684401: JTree isExpanded should not call itself recursively Reviewed-by: rupashka ! src/share/classes/javax/swing/JTree.java Changeset: f1bafc4f249d Author: peterz Date: 2010-06-29 14:42 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/f1bafc4f249d 6963870: NPE in CompoundBorder.getInsets() Reviewed-by: alexp Contributed-by: jon.vanalten at redhat.com ! src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java + test/com/sun/java/swing/plaf/gtk/Test6963870.java Changeset: c0e785f055a7 Author: lana Date: 2010-06-30 19:05 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/c0e785f055a7 Merge ! test/ProblemList.txt Changeset: d062afbe2107 Author: malenkov Date: 2010-07-01 18:09 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/d062afbe2107 4129681: Cannot get a title border to display its label as disabled Reviewed-by: alexp, rupashka ! src/share/classes/javax/swing/border/TitledBorder.java + test/javax/swing/border/Test4129681.html + test/javax/swing/border/Test4129681.java + test/javax/swing/border/Test4760089.html + test/javax/swing/border/Test4760089.java Changeset: 46306a419ba3 Author: malenkov Date: 2010-07-01 18:47 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/46306a419ba3 6959266: test javax/swing/JInternalFrame/6725409/bug6725409.java should be modified Reviewed-by: alexp ! test/javax/swing/JInternalFrame/6725409/bug6725409.java Changeset: e94a94d176f9 Author: alexp Date: 2010-07-02 19:28 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/e94a94d176f9 6711682: JCheckBox in JTable: checkbox doesn't alaways respond to the first mouse click Reviewed-by: rupashka ! src/share/classes/javax/swing/plaf/basic/BasicButtonListener.java + test/javax/swing/AbstractButton/6711682/bug6711682.java Changeset: 46d5aef470a3 Author: alexp Date: 2010-07-02 19:34 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/46d5aef470a3 6937415: Some components return undocumented default values under Nimbus LaF Reviewed-by: peterz ! src/share/classes/javax/swing/JSplitPane.java ! src/share/classes/javax/swing/JTable.java ! src/share/classes/javax/swing/plaf/nimbus/skin.laf Changeset: e12c92d2dc11 Author: rupashka Date: 2010-07-08 19:09 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/e12c92d2dc11 6520101: FileChooser will cause OutOfMemory when application will run long time Reviewed-by: peterz ! src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java + test/javax/swing/JFileChooser/6520101/bug6520101.java Changeset: d0bcc9aa5a7a Author: malenkov Date: 2010-07-09 19:42 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/d0bcc9aa5a7a 6894597: test/closed/javax/swing/JPopupMenu/6495920/bug6495920.java fails Reviewed-by: alexp, peterz + test/javax/swing/JPopupMenu/6495920/bug6495920.java Changeset: 3dc686ecb4cd Author: malenkov Date: 2010-07-09 22:07 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/3dc686ecb4cd 6963811: Deadlock-prone locking changes in Introspector Reviewed-by: peterz, rupashka ! src/share/classes/com/sun/beans/finder/InstanceFinder.java ! src/share/classes/com/sun/beans/finder/PersistenceDelegateFinder.java ! src/share/classes/com/sun/beans/finder/PropertyEditorFinder.java ! src/share/classes/java/beans/Encoder.java ! src/share/classes/java/beans/Introspector.java ! src/share/classes/java/beans/PropertyEditorManager.java + test/java/beans/Introspector/Test6963811.java + test/java/beans/PropertyEditor/Test6963811.java + test/java/beans/XMLEncoder/Test6963811.java Changeset: a93a7ed5018c Author: lana Date: 2010-07-12 19:35 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/a93a7ed5018c Merge Changeset: dd98b0b747ec Author: ohair Date: 2010-06-22 10:54 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/dd98b0b747ec 6931871: Rebranding of javadoc generation in makefiles 6951293: control docs target does not work on windows Reviewed-by: jjg + make/common/shared/Defs-javadoc.gmk ! make/docs/Makefile Changeset: d7fdaee81c14 Author: sherman Date: 2010-06-22 14:04 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/d7fdaee81c14 6963156: TEST_BUG: Several tests under sun/nio/cs failed Summary: Updated the test cases and removed them from ProblemList.txt Reviewed-by: alanb ! test/ProblemList.txt ! test/sun/nio/cs/FindDecoderBugs.java ! test/sun/nio/cs/TestX11CNS.java Changeset: 6fe3b86f4720 Author: sherman Date: 2010-06-22 14:22 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/6fe3b86f4720 Merge Changeset: 4e76be6e9fe1 Author: dcubed Date: 2010-06-22 10:54 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/4e76be6e9fe1 6942989: 2/2 Memory leak of java.lang.ref.WeakReference objects Summary: Use ReferenceQueues to manage WeakReferences in LogManager and Logger. Reviewed-by: dholmes, alanb, emcmanus, tonyp Contributed-by: jeremymanson at google.com ! src/share/classes/java/util/logging/LogManager.java ! src/share/classes/java/util/logging/Logger.java + test/java/util/logging/AnonLoggerWeakRefLeak.java + test/java/util/logging/AnonLoggerWeakRefLeak.sh + test/java/util/logging/LoggerWeakRefLeak.java + test/java/util/logging/LoggerWeakRefLeak.sh Changeset: 600ef8b4a211 Author: dcubed Date: 2010-06-22 16:18 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/600ef8b4a211 Merge Changeset: 25fe5c3bf7b7 Author: ohair Date: 2010-06-22 17:07 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/25fe5c3bf7b7 6939022: Source code adjustments for parfait compilation Reviewed-by: jjg ! src/solaris/demo/jni/Poller/Poller.c Changeset: 848e69fcf2f3 Author: ohair Date: 2010-06-22 17:26 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/848e69fcf2f3 6933622: Duplicate class files in rt.jar and charsets.jar 6895003: JarReorder is not excluding a requested file. Reviewed-by: jjg ! make/common/Release.gmk ! make/tools/src/build/tools/jarreorder/JarReorder.java ! test/ProblemList.txt Changeset: 3c745249065f Author: ohair Date: 2010-06-22 19:18 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/3c745249065f Merge Changeset: 887e525597f8 Author: dsamersoff Date: 2010-06-23 17:25 +0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/887e525597f8 6931566: NetworkInterface is not working when interface name is more than 15 characters long Summary: Separate Linux and Solaris code, use lifreq under Solaris Reviewed-by: chegar ! src/solaris/native/java/net/NetworkInterface.c Changeset: eb84b89ef3ff Author: alanb Date: 2010-06-23 20:19 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/eb84b89ef3ff 6963027: TEST_BUG: channels and buffer tests need to run in samevm mode Reviewed-by: ohair, sherman, chegar ! test/Makefile ! test/ProblemList.txt ! test/java/nio/BufferPoolMXBean/Basic.java ! test/java/nio/MappedByteBuffer/Basic.java ! test/java/nio/MappedByteBuffer/Force.java ! test/java/nio/MappedByteBuffer/ZeroMap.java ! test/java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java ! test/java/nio/channels/AsynchronousChannelGroup/Identity.java ! test/java/nio/channels/AsynchronousDatagramChannel/Basic.java ! test/java/nio/channels/AsynchronousFileChannel/Basic.java ! test/java/nio/channels/AsynchronousFileChannel/Lock.java ! test/java/nio/channels/AsynchronousFileChannel/LotsOfWrites.java ! test/java/nio/channels/AsynchronousSocketChannel/Basic.java ! test/java/nio/channels/Channels/Basic2.java ! test/java/nio/channels/Channels/Write.java ! test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java ! test/java/nio/channels/DatagramChannel/EmptyBuffer.java ! test/java/nio/channels/DatagramChannel/ReceiveISA.java ! test/java/nio/channels/DatagramChannel/SelectWhenRefused.java ! test/java/nio/channels/FileChannel/Args.java ! test/java/nio/channels/FileChannel/ClosedChannelTransfer.java ! test/java/nio/channels/FileChannel/ExpandingMap.java ! test/java/nio/channels/FileChannel/Lock.java ! test/java/nio/channels/FileChannel/MapOverEnd.java ! test/java/nio/channels/FileChannel/MapReadOnly.java ! test/java/nio/channels/FileChannel/MapTest.java ! test/java/nio/channels/FileChannel/Mode.java ! test/java/nio/channels/FileChannel/Position.java ! test/java/nio/channels/FileChannel/Pread.java ! test/java/nio/channels/FileChannel/Pwrite.java ! test/java/nio/channels/FileChannel/Read.java ! test/java/nio/channels/FileChannel/ReadFull.java ! test/java/nio/channels/FileChannel/ReadToLimit.java ! test/java/nio/channels/FileChannel/ReleaseOnCloseDeadlock.java ! test/java/nio/channels/FileChannel/ScatteringRead.java ! test/java/nio/channels/FileChannel/Size.java ! test/java/nio/channels/FileChannel/Transfer.java ! test/java/nio/channels/FileChannel/TransferToChannel.java ! test/java/nio/channels/FileChannel/TransferToNonWritable.java ! test/java/nio/channels/FileChannel/Transfers.java ! test/java/nio/channels/FileChannel/TryLock.java ! test/java/nio/channels/FileChannel/Write.java ! test/java/nio/channels/Pipe/NonBlocking.java ! test/java/nio/channels/Pipe/SelectPipe.java ! test/java/nio/channels/SelectionKey/AtomicAttachTest.java ! test/java/nio/channels/Selector/BasicAccept.java ! test/java/nio/channels/Selector/BasicConnect.java ! test/java/nio/channels/Selector/CheckLocking.java ! test/java/nio/channels/Selector/CloseInvalidatesKeys.java ! test/java/nio/channels/Selector/CloseWhenKeyIdle.java ! test/java/nio/channels/Selector/Connect.java ! test/java/nio/channels/Selector/ConnectWrite.java ! test/java/nio/channels/Selector/HelperSlowToDie.java ! test/java/nio/channels/Selector/KeysReady.java ! test/java/nio/channels/Selector/LotsOfChannels.java ! test/java/nio/channels/Selector/RegAfterPreClose.java ! test/java/nio/channels/Selector/SelectAndCancel.java ! test/java/nio/channels/Selector/SelectorLimit.java ! test/java/nio/channels/Selector/SelectorTest.java ! test/java/nio/channels/Selector/WakeupNow.java ! test/java/nio/channels/Selector/WakeupOverflow.java ! test/java/nio/channels/Selector/WakeupSpeed.java - test/java/nio/channels/ServerSocketChannel/AcceptAddress.java ! test/java/nio/channels/SocketChannel/AdaptSocket.java ! test/java/nio/channels/SocketChannel/Bind.java ! test/java/nio/channels/SocketChannel/Close.java ! test/java/nio/channels/SocketChannel/CloseRegisteredChannel.java ! test/java/nio/channels/SocketChannel/CloseTimeoutChannel.java ! test/java/nio/channels/SocketChannel/IsConnectable.java ! test/java/nio/channels/SocketChannel/LocalAddress.java ! test/java/nio/channels/SocketChannel/SocketInheritance.java ! test/java/nio/channels/SocketChannel/Trivial.java ! test/java/nio/channels/SocketChannel/UnboundSocketTests.java ! test/java/nio/channels/etc/Shadow.java ! test/java/nio/channels/spi/SelectorProvider/inheritedChannel/ClosedStreams.java ! test/sun/nio/ch/Basic.java ! test/sun/nio/ch/TempBuffer.java ! test/sun/nio/cs/ReadZero.java ! test/sun/nio/cs/Test4206507.java ! test/sun/nio/cs/TestStringCoding.java Changeset: 55aa27b8bb98 Author: alanb Date: 2010-06-23 21:22 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/55aa27b8bb98 Merge Changeset: c4d60bcce958 Author: darcy Date: 2010-06-23 17:03 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/c4d60bcce958 6911258: Project Coin: Add essential API support for Automatic Resource Management (ARM) blocks 6911261: Project Coin: Retrofit Automatic Resource Management (ARM) support onto platform APIs 6962571: Infinite loop in printing out Throwable stack traces with circular references Reviewed-by: darcy, alanb Contributed-by: jjb at google.com ! make/java/java/FILES_java.gmk ! src/share/classes/java/io/Closeable.java + src/share/classes/java/lang/AutoCloseable.java ! src/share/classes/java/lang/Throwable.java ! src/share/classes/java/nio/channels/FileLock.java ! src/share/classes/javax/imageio/stream/ImageInputStream.java + test/java/lang/Throwable/SuppressedExceptions.java Changeset: 706e2d1fc378 Author: weijun Date: 2010-06-24 14:26 +0800 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/706e2d1fc378 6958026: Problem with PKCS12 keystore Reviewed-by: mullan ! src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java + test/sun/security/pkcs12/PKCS12SameKeyId.java Changeset: 1da7dfca3e20 Author: weijun Date: 2010-06-24 14:26 +0800 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/1da7dfca3e20 6844907: krb5 etype order should be from strong to weak Reviewed-by: valeriep ! src/share/classes/sun/security/krb5/Credentials.java ! src/share/classes/sun/security/krb5/internal/crypto/EType.java ! src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java + test/sun/security/krb5/etype/ETypeOrder.java ! test/sun/security/krb5/ktab/HighestKvno.java Changeset: 9c0f542c8b37 Author: weijun Date: 2010-06-24 14:26 +0800 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/9c0f542c8b37 6946669: SSL/Krb5 should not call EncryptedData.reset(data, false) Reviewed-by: xuelei ! src/share/classes/sun/security/krb5/EncryptedData.java ! src/share/classes/sun/security/krb5/KrbApRep.java ! src/share/classes/sun/security/krb5/KrbApReq.java ! src/share/classes/sun/security/krb5/KrbAsRep.java ! src/share/classes/sun/security/krb5/KrbCred.java ! src/share/classes/sun/security/krb5/KrbPriv.java ! src/share/classes/sun/security/krb5/KrbTgsRep.java ! src/share/classes/sun/security/ssl/krb5/KerberosClientKeyExchangeImpl.java ! src/share/classes/sun/security/ssl/krb5/KerberosPreMasterSecret.java ! test/sun/security/krb5/auto/SSL.java Changeset: 2e9ef9a80d82 Author: ohair Date: 2010-06-25 08:44 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/2e9ef9a80d82 6964311: Build regression due to rt.jar contents change Summary: The fix for 6933622 regressed control builds, this is a workaround fix, filed 6964313 to find the right answer to why it happened and how to fix it correctly. Reviewed-by: alanb, darcy ! make/common/Release.gmk Changeset: 6bf403a14da4 Author: alanb Date: 2010-06-25 18:31 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/6bf403a14da4 6963828: TEST_BUG: java/nio/channels/FileTransfer.java takes too long (win) Reviewed-by: chegar ! test/java/nio/channels/FileChannel/Transfer.java Changeset: 0995c5a2dc6d Author: alanb Date: 2010-06-25 18:34 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/0995c5a2dc6d Merge Changeset: 6d274503d1b7 Author: chegar Date: 2010-06-28 14:55 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/6d274503d1b7 6954525: Testcase failure java/net/Authenticator/B4769350.java Reviewed-by: michaelm, weijun ! src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java ! test/java/net/Authenticator/B4769350.java Changeset: a89f8c292a5b Author: chegar Date: 2010-06-28 15:06 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/a89f8c292a5b Merge Changeset: 7c3da1f0e17c Author: chegar Date: 2010-06-28 20:52 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/7c3da1f0e17c 6961029: java/net/BindException/Test.java should not use wildcard address Reviewed-by: michaelm, alanb ! test/ProblemList.txt ! test/java/net/BindException/Test.java ! test/java/net/ipv6tests/Tests.java Changeset: a9e0a6fb6057 Author: ksrini Date: 2010-06-28 18:25 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/a9e0a6fb6057 6856415: Enabling java security manager will make programe thrown wrong exception ( main method not found ) Reviewed-by: darcy ! src/share/classes/sun/launcher/LauncherHelper.java + test/tools/launcher/VerifyExceptions.java Changeset: 5c5fe62d990d Author: alanb Date: 2010-06-29 17:11 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/5c5fe62d990d 6213702: (so) non-blocking sockets with TCP urgent disabled get still selected for read ops (win) Reviewed-by: michaelm, chegar ! src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java ! src/windows/native/sun/nio/ch/WindowsSelectorImpl.c + test/java/nio/channels/Selector/OutOfBand.java Changeset: b318df97820f Author: lana Date: 2010-06-29 10:50 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/b318df97820f Merge Changeset: 4436a3e97a9b Author: martin Date: 2010-06-30 16:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/4436a3e97a9b 6934268: Better implementation of Character.isValidCodePoint Summary: Use the cleverest possible bit-twiddling micro-optimizations Reviewed-by: sherman Contributed-by: Ulf Zibis ! src/share/classes/java/lang/Character.java Changeset: 1776791f4fb9 Author: martin Date: 2010-06-30 16:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/1776791f4fb9 6934265: Add public method Character.isBmpCodePoint Summary: Move isBmpCodePoint from sun.nio.cs.Surrogate to Character Reviewed-by: sherman Contributed-by: Ulf Zibis ! src/share/classes/java/lang/AbstractStringBuilder.java ! src/share/classes/java/lang/Character.java ! src/share/classes/java/lang/String.java ! src/share/classes/sun/io/CharToByteDBCS_ASCII.java ! src/share/classes/sun/io/CharToByteDBCS_EBCDIC.java ! src/share/classes/sun/nio/cs/Surrogate.java ! src/share/classes/sun/nio/cs/UTF_32Coder.java ! src/share/classes/sun/nio/cs/UTF_8.java ! src/share/classes/sun/nio/cs/ext/EUC_TW.java ! src/share/classes/sun/nio/cs/ext/GB18030.java ! src/share/classes/sun/nio/cs/ext/IBM33722.java ! src/share/classes/sun/nio/cs/ext/IBM964.java ! test/java/nio/charset/coders/BashStreams.java - test/java/nio/charset/coders/Surrogate.java ! test/java/nio/charset/coders/Surrogates.java Changeset: 5503dbb2e6cc Author: martin Date: 2010-06-30 16:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/5503dbb2e6cc 6937112: String.lastIndexOf confused by unpaired trailing surrogate Summary: Rewrite lastIndexOf for performance and correctness Reviewed-by: sherman Contributed-by: Reviewed by Ulf Zibis ! src/share/classes/java/lang/String.java ! test/java/lang/String/Supplementary.java ! test/java/lang/StringBuffer/Supplementary.java ! test/java/lang/StringBuilder/Supplementary.java Changeset: 5e9daa8fd04a Author: martin Date: 2010-06-30 16:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/5e9daa8fd04a 6940381: Wording improvements for String.indexOf, String.lastIndexOf Summary: Make wording of javadoc clearer and more consistent Reviewed-by: sherman ! src/share/classes/java/lang/String.java Changeset: 0d2bff3b2ca6 Author: martin Date: 2010-06-30 16:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/0d2bff3b2ca6 6963749: Minor improvements to Character.UnicodeBlock Summary: Fix surrogate area docs; make source more readable Reviewed-by: okutsu, sherman Contributed-by: Ulf Zibis ! src/share/classes/java/lang/Character.java Changeset: 4f1b4e3c6d1b Author: martin Date: 2010-06-30 16:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/4f1b4e3c6d1b 6934270: Remove javac warnings from Character.java Summary: Use generics and conform to coding style Reviewed-by: sherman Contributed-by: Ulf Zibis ! src/share/classes/java/lang/Character.java Changeset: 98186c162c1e Author: martin Date: 2010-06-30 16:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/98186c162c1e 6933322: Add methods highSurrogate(), lowSurrogate() to class Character Summary: Add public variants of methods Surrogate.high, Surrogate.low Reviewed-by: okutsu, sherman Contributed-by: Ulf Zibis ! src/share/classes/java/lang/Character.java ! src/share/classes/java/lang/String.java ! src/share/classes/sun/nio/cs/Surrogate.java ! src/share/classes/sun/nio/cs/UTF_32Coder.java ! src/share/classes/sun/nio/cs/UTF_8.java ! src/share/classes/sun/nio/cs/UnicodeEncoder.java ! src/share/classes/sun/nio/cs/ext/EUC_TW.java ! test/java/nio/charset/coders/BashStreams.java Changeset: 838a21b99591 Author: martin Date: 2010-06-30 16:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/838a21b99591 6934271: Better handling of longer utf-8 sequences Summary: Various cleanups, including clever bit-twiddling Reviewed-by: sherman ! src/share/classes/sun/nio/cs/UTF_8.java Changeset: 9c80da212eaf Author: martin Date: 2010-06-30 16:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/9c80da212eaf 6935172: Optimize bit-twiddling in Bits.java Summary: Transformations to reduce size of bytecode Reviewed-by: sherman Contributed-by: Based on an idea by Ulf Zibis ! src/share/classes/java/io/Bits.java Changeset: ce0ba8da0bd1 Author: martin Date: 2010-06-30 16:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/ce0ba8da0bd1 6940258: (bf) Use intrinsified reverseBytes operation; elide no-op constructs Reviewed-by: alanb, sherman Contributed-by: Ulf Zibis ! src/share/classes/java/nio/Bits.java Changeset: a5a34c696d62 Author: alanb Date: 2010-07-01 16:28 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/a5a34c696d62 6947216: Even more Dual-pivot quicksort improvements Reviewed-by: jjb Contributed-by: vladimir.yaroslavskiy at sun.com ! src/share/classes/java/util/DualPivotQuicksort.java ! test/java/util/Arrays/Sorting.java Changeset: 9bffc32b645d Author: mullan Date: 2010-07-01 15:20 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/9bffc32b645d 6782979: Add JNLPAppletLauncher (6618105) to blacklist Reviewed-by: ohair ! make/java/security/Makefile Changeset: c0d2a097eb99 Author: mullan Date: 2010-07-01 15:30 -0400 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/c0d2a097eb99 Merge Changeset: 425960cef714 Author: darcy Date: 2010-07-06 18:58 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/425960cef714 6963723: Project Coin: Retrofit more JDK classes for ARM Reviewed-by: alanb, malenkov, prr, amenkov ! src/share/classes/java/beans/XMLDecoder.java ! src/share/classes/java/beans/XMLEncoder.java ! src/share/classes/java/io/ObjectInput.java ! src/share/classes/java/io/ObjectOutput.java ! src/share/classes/java/util/Scanner.java ! src/share/classes/javax/sound/midi/MidiDevice.java ! src/share/classes/javax/sound/midi/Receiver.java ! src/share/classes/javax/sound/midi/Transmitter.java ! src/share/classes/javax/sound/sampled/Line.java Changeset: d6f8ffc3c54a Author: ohair Date: 2010-07-07 10:17 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/d6f8ffc3c54a 6954517: Testcase failure tools/launcher/UnicodeTest.sh Reviewed-by: ksrini ! test/tools/launcher/UnicodeTest.sh Changeset: f13e94562d84 Author: ksrini Date: 2010-07-09 09:54 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/f13e94562d84 6930056: (launcher) Need to remove or build as part of test these liblibrary.so files Reviewed-by: ohair, darcy - test/tools/launcher/Makefile.SolarisRunpath - test/tools/launcher/lib/i386/lib32/lib32/liblibrary.so - test/tools/launcher/lib/i386/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib32/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib64/lib64/liblibrary.so - test/tools/launcher/lib/sparc/lib64/liblibrary.so Changeset: da8526047e5f Author: martin Date: 2010-07-09 18:55 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/da8526047e5f 6967533: Epoch bug: ExceptionInInitializerError on systems with uninitialized clock Summary: Remove (hopefully!) unnecessary check of currentTimeMillis Reviewed-by: dholmes Contributed-by: Jon VanAlten ! src/share/classes/java/lang/System.java Changeset: a7f8f269f741 Author: chegar Date: 2010-07-12 18:13 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/a7f8f269f741 6967937: Scope id no longer being set after 6931566 Reviewed-by: alanb, dsamersoff ! src/solaris/native/java/net/NetworkInterface.c ! test/java/net/Inet6Address/B6214234.java Changeset: 1371a2d5f3a8 Author: chegar Date: 2010-07-12 18:16 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/1371a2d5f3a8 6967684: httpserver using a non thread-safe SimpleDateFormat Reviewed-by: michaelm ! src/share/classes/sun/net/httpserver/ExchangeImpl.java Changeset: bb0b32ffefe9 Author: chegar Date: 2010-07-12 18:18 +0100 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/bb0b32ffefe9 6966846: Incorrect assertion in java.net.Inet6Address.readObject Reviewed-by: michaelm ! src/share/classes/java/net/Inet6Address.java Changeset: d3fa95d0710c Author: ksrini Date: 2010-07-09 11:04 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/d3fa95d0710c 6921472: RFE: java launcher code needs clean up Summary: This changeset also contains fixes for 6405284, 6753938 and 6922500 Reviewed-by: darcy ! src/share/bin/emessages.h ! src/share/bin/java.c ! src/share/bin/java.h ! src/share/bin/jli_util.c ! src/share/bin/jli_util.h ! src/solaris/bin/java_md.c ! src/windows/bin/java_md.c ! test/tools/launcher/Arrrghs.java Changeset: ddf825161d2d Author: dcubed Date: 2010-07-12 14:19 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/ddf825161d2d 6968401: 3/3 disable tests added by 6942989 until 6964018 is fixed Summary: Disable AnonLoggerWeakRefLeak.sh and LoggerWeakRefLeak.sh Reviewed-by: ohair ! test/java/util/logging/AnonLoggerWeakRefLeak.sh ! test/java/util/logging/LoggerWeakRefLeak.sh Changeset: 4e365ef6576d Author: dcubed Date: 2010-07-12 15:52 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/4e365ef6576d Merge Changeset: c5a436f053aa Author: lana Date: 2010-07-12 19:42 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/c5a436f053aa Merge ! test/ProblemList.txt - test/java/nio/channels/ServerSocketChannel/AcceptAddress.java - test/java/nio/charset/coders/Surrogate.java - test/tools/launcher/Makefile.SolarisRunpath - test/tools/launcher/lib/i386/lib32/lib32/liblibrary.so - test/tools/launcher/lib/i386/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib32/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib64/lib64/liblibrary.so - test/tools/launcher/lib/sparc/lib64/liblibrary.so Changeset: 13029a61b16b Author: lana Date: 2010-07-20 22:21 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/13029a61b16b Merge - test/java/nio/channels/ServerSocketChannel/AcceptAddress.java - test/java/nio/charset/coders/Surrogate.java - test/tools/launcher/Makefile.SolarisRunpath - test/tools/launcher/lib/i386/lib32/lib32/liblibrary.so - test/tools/launcher/lib/i386/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib32/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib64/lib64/liblibrary.so - test/tools/launcher/lib/sparc/lib64/liblibrary.so Changeset: 6488b70a23cc Author: mikejwre Date: 2010-07-23 16:42 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/6488b70a23cc Added tag jdk7-b102 for changeset 13029a61b16b ! .hgtags Changeset: cf0c23a99823 Author: lana Date: 2010-07-29 17:12 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/jdk/rev/cf0c23a99823 Merge - src/linux/doc/man/ja/kinit.1 - src/linux/doc/man/ja/klist.1 - src/linux/doc/man/ja/ktab.1 - test/java/nio/channels/ServerSocketChannel/AcceptAddress.java - test/java/nio/charset/coders/Surrogate.java - test/tools/launcher/Makefile.SolarisRunpath - test/tools/launcher/lib/i386/lib32/lib32/liblibrary.so - test/tools/launcher/lib/i386/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib32/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib32/liblibrary.so - test/tools/launcher/lib/sparc/lib64/lib64/liblibrary.so - test/tools/launcher/lib/sparc/lib64/liblibrary.so From lana.steuck at oracle.com Fri Jul 30 05:41:45 2010 From: lana.steuck at oracle.com (lana.steuck at oracle.com) Date: Fri, 30 Jul 2010 05:41:45 +0000 Subject: [OpenJDK 2D-Dev] hg: jdk7/2d/langtools: 9 new changesets Message-ID: <20100730054159.5283F47D94@hg.openjdk.java.net> Changeset: f87f1f3e23e1 Author: mikejwre Date: 2010-07-15 20:11 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/f87f1f3e23e1 Added tag jdk7-b101 for changeset 20a8fe72ee7b ! .hgtags Changeset: be5cafeb318d Author: darcy Date: 2010-06-23 16:51 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/be5cafeb318d 6911258: Project Coin: Add essential API support for Automatic Resource Management (ARM) blocks Reviewed-by: darcy, alanb Contributed-by: jjb at google.com ! src/share/classes/javax/lang/model/element/ElementKind.java Changeset: d8a15fda7e3a Author: jjg Date: 2010-06-24 10:34 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/d8a15fda7e3a 6917288: Unnamed nested class is not generated Reviewed-by: mcimadamore ! src/share/classes/com/sun/tools/javac/comp/Lower.java + test/tools/javac/6917288/GraphicalInstaller.java + test/tools/javac/6917288/GraphicalInstallerTest.java + test/tools/javac/6917288/T6917288.java Changeset: 6386f0fd6205 Author: lana Date: 2010-06-29 12:06 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/6386f0fd6205 Merge ! src/share/classes/com/sun/tools/javac/code/Flags.java ! src/share/classes/com/sun/tools/javac/code/Source.java ! src/share/classes/com/sun/tools/javac/code/Symtab.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/MemberEnter.java ! src/share/classes/com/sun/tools/javac/comp/Resolve.java ! src/share/classes/com/sun/tools/javac/jvm/ClassReader.java ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java ! src/share/classes/com/sun/tools/javac/jvm/Gen.java ! src/share/classes/com/sun/tools/javac/main/Main.java ! src/share/classes/com/sun/tools/javac/util/Names.java Changeset: d2b7ecf33b35 Author: jjg Date: 2010-06-30 18:06 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/d2b7ecf33b35 6964768: need test program to validate javac resource bundles Reviewed-by: darcy ! src/share/classes/com/sun/tools/javac/code/Kinds.java ! src/share/classes/com/sun/tools/javac/main/JavaCompiler.java ! src/share/classes/com/sun/tools/javac/parser/Scanner.java ! src/share/classes/com/sun/tools/javac/resources/compiler.properties + test/tools/javac/diags/CheckResourceKeys.java ! test/tools/javac/literals/BadUnderscoreLiterals.6.out Changeset: 064468702a8d Author: jjg Date: 2010-07-12 16:37 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/064468702a8d 6968497: localized text appears in raw diagnostic Reviewed-by: darcy ! src/share/classes/com/sun/tools/javac/comp/Check.java ! test/tools/javac/generics/6946618/T6946618c.java ! test/tools/javac/generics/6946618/T6946618c.out Changeset: eaab979c8b36 Author: lana Date: 2010-07-12 19:43 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/eaab979c8b36 Merge Changeset: ff9c0a0bf7ed Author: lana Date: 2010-07-20 22:22 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/ff9c0a0bf7ed Merge Changeset: bd85271c580c Author: mikejwre Date: 2010-07-23 16:42 -0700 URL: http://hg.openjdk.java.net/jdk7/2d/langtools/rev/bd85271c580c Added tag jdk7-b102 for changeset ff9c0a0bf7ed ! .hgtags From james.graham at Oracle.COM Fri Jul 30 10:06:20 2010 From: james.graham at Oracle.COM (Jim Graham) Date: Fri, 30 Jul 2010 03:06:20 -0700 Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <1794487132.1319501280438200639.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <1794487132.1319501280438200639.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C52A41C.2060707@oracle.com> Hi Denis, More thoughts on Renderer.java. -- Skipping gaps (minor optimization) -- If there is a gap in the edges in Y, say if a path consists of two subpaths, one that covers y=[0..10] and another that covers y=[1000..1010], then I think you will iterate over each y value from 10 to 1000, but have no work to do on each scan line. That could possibly waste a bit of time. On the other hand, fixing that would have to take into account whether or not you are done with a given alpha row, so the "NextY" function can't simply skip - the skipping has to be done at the higher level in endRendering - or at least with the cooperation of endRendering. Since it asks what the "current Y" is near the top of the loop, it could detect if the current Y jumped out of the given alpha row, emit it, and prepare for a new alpha row starting at the new Y...? For now, it might be simpler to ignore this and revisit that later since it isn't going to be common to have large such jumps in the middle of most paths. -- Done with skipping gaps -- -- Alpha accumulation opt -- Filling the alpha row. I had an interesting optimization here that I never got around to. Instead of filling the array entries with the alpha values, fill them with the deltas of the alpha values. The inner loop in endRendering then becomes something like: alpha[pix_x0 ] += NUM_POS - (x0 & MASK); alpha[pix_x0+1] += (x0 & MASK); alpha[pix_x1 ] -= NUM_POS - (x1 & MASK); alpha[pix_x1+1] -= (x1 & MASK); The [pix+1] lines were the gotcha that always confused me when I tried to do this in the past. Basically if you enter an inside region at 1 subpixel before the end of a pixel then you need to add one to the coverage for that pixel. But, starting with the next pixel you want the total contribution of the interior region to be NUM_POS per pixel, but you've only added 1 so far - so you have to add the additional amount so that the total amount added for each "enter" crossing ends up being NUM_POS. Similarly, when you decrement for the "exit" crossing you need to ensure that the total negative delta sums to NUM_POS across the pixel where the exit happens and the following pixel. Does that make sense? Note that you could still have the "single pixel" optimization which would look like: alpha[pix_x0 ] += (x1 - x0); alpha[pix_x0+1] -= (x1 - x0); and is equivalent to the above 4 lines. then when you do the RLE, you simply have to use an accumulation as you scan the alpha row: byte nextVal = startVal + alphaRow[i]; So, for the cost of an add per pixel as you do the RLE you can avoid having to do the loop in the "multiple pixel section" when filling the alpha array. I don't think I've ever quantified this optimization so it might be better to investigate it after the current code goes in and adopt it only if it shows a big savings. -- Done with alpha accumulation opt -- Something about the "emit last row" code bothers me. First, I would guess that the "y == boundsMaxY - 1" test would have already flushed the row, right? Also, why do the for loop? Why not just flush the row if it isn't flushed? I kind of feel like the "y == boundsMaxY-1" test could be removed from inside the loop and simply test if there is unflushed data in the alpha array then just make a call to emitRow() with the appropriate values after the loop. while (hasNext()) { ... if ((y & MASK) == MASK) { emitRow(...); pix_min,max = MAX,MIN; } } if (pix_min < pix_max) { emitRow(...); } Am I missing something? So, the upshot is that I didn't find anything wrong. You can take or leave my suggestions for improvements as you see fit and maybe save some of them for a second round after this goes back... ...jim On 7/29/2010 2:16 PM, Denis Lila wrote: > Hello Jim. > > I made the changes you point out, except for your second point > (I don't have time to think about it right now). > > I stopped precomputing m00_2_m01_2 because it was only being > used in one place. But I guess it worth it to precompute it > if it's going to be used often (and computeOffset is called > for every line). > > The new webrev is at http://icedtea.classpath.org/~dlila/webrevs/fpBetterAAv2/webrev/ > > Thanks, > Denis. From james.graham at oracle.com Fri Jul 30 10:08:23 2010 From: james.graham at oracle.com (Jim Graham) Date: Fri, 30 Jul 2010 03:08:23 -0700 Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <4C521C65.3060609@oracle.com> References: <1794487132.1319501280438200639.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> <4C521C65.3060609@oracle.com> Message-ID: <4C52A497.3070306@oracle.com> Just to clarify. My second message that I just sent mostly contained some additional optimizations to consider for now or later, but this message below contained at least one (maybe 2) thing(s) that looked like a bug and a few maintenance issues that I think should be done before finalizing this set of changes... ...jim On 7/29/2010 5:27 PM, Jim Graham wrote: > Hi Denis, > > The changes look fine and I'm moving on to Renderer.java... > > I'd make as many methods private as you can. It looks like all your new > methods are private, but some old methods are still public even though I > don't think they are accessed elsewhere (like addEdge()?). I think > "private" is enough for Hotspot to inline so that should help > performance a bit. I usually use "final", but I think "private" does the > same thing. > > You should create constants for the indices into the struct to make the > code more readable (and to simplify updating the EDGE layout): > > X0_OFF = 0 > Y0_OFF = 1 > // etc. > > I don't think you touch X0 and Y0 after initializing them and then using > them for the first setCurY so you could just use them as the "curX" and > "curY" and save 2 slots in the table. > > You initialize edges twice - once when it is declared, and once in the > constructor. Note that the initialization where it is declared uses > INIT_SIZE which is not a multiple of EDGE size anyway. > > It looks like there is a missing statement in moveTo to initialize > this.x0...? > > I need some more time on it, but I thought I would send along these > comments in the meantime... > > ...jim > > Denis Lila wrote: >> Hello Jim. >> >> I made the changes you point out, except for your second point >> (I don't have time to think about it right now). >> >> I stopped precomputing m00_2_m01_2 because it was only being >> used in one place. But I guess it worth it to precompute it >> if it's going to be used often (and computeOffset is called >> for every line). >> >> The new webrev is at >> http://icedtea.classpath.org/~dlila/webrevs/fpBetterAAv2/webrev/ >> >> Thanks, >> Denis. From dlila at redhat.com Fri Jul 30 22:27:23 2010 From: dlila at redhat.com (Denis Lila) Date: Fri, 30 Jul 2010 18:27:23 -0400 (EDT) Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <1299887891.1399051280528707455.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <459805495.1399131280528843009.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Hi Jim. Thanks for all your suggestions. I fixed the edge array indexing issue, the moveTo bug (not assigning x0), and the double initialization issue. I also improved the emission of the last row to what you said. The link is the same as the last one I sent. I considered one more optimization for the scan line iteration: instead of keeping a crossings array and Arrays.sort'ing it for every scanline, utilize the fact that the crossings information is already in the active list, and doesn't need to be copied, so we could just keep the active list sorted by increasing x crossing (this is the way things are done in ShapeSpanIterator, which is where I got the idea from). An added benefit of this (so I thought) would be that the order of the edges sorted by x crossing would not change very often, and not very much, in which case keeping it sorted by insertion sort would have (on average) linear time complexity per scan line, instead of nlogn which is what Arrays.sort has. After implementing this, I tested it, and unfortunately it turns out not to be as good as I expected. It is faster in some tests, but it is a lot slower in some others. It's a shame because it simplified things quite a bit (the file became just 440 lines). With it I was able to remove about 4 or 5 variables from Renderer, flips among them so we no longer needed to keep track of orientations, since we only do that to determine the size of the crossings array. > For now, it might be simpler to ignore this and revisit that later > since it isn't going to be common to have large such jumps in the > middle of most paths. I agree. Not only that, but even if there are gaps I don't think it will be much of a problem since very little work has to be done to traverse scan lines with no crossings. > Filling the alpha row. I had an interesting optimization here that I > > never got around to. Instead of filling the array entries with the > alpha values, fill them with the deltas of the alpha values. The > inner > loop in endRendering then becomes something like: > > alpha[pix_x0 ] += NUM_POS - (x0 & MASK); > alpha[pix_x0+1] += (x0 & MASK); > alpha[pix_x1 ] -= NUM_POS - (x1 & MASK); > alpha[pix_x1+1] -= (x1 & MASK); That's a good idea. I implemented it but I think we should use it whether it offers big savings or not. It's just a nicer algorithm. Although, the way it is now, it is a bit misleading (the name of the array is alpha). I should have commented this a bit more. I don't have time now, I'll do it on Monday. Thanks, Denis. ----- "Jim Graham" wrote: > Hi Denis, > > More thoughts on Renderer.java. > > -- Skipping gaps (minor optimization) -- > > If there is a gap in the edges in Y, say if a path consists of two > subpaths, one that covers y=[0..10] and another that covers > y=[1000..1010], then I think you will iterate over each y value from > 10 > to 1000, but have no work to do on each scan line. That could > possibly > waste a bit of time. > > On the other hand, fixing that would have to take into account whether > > or not you are done with a given alpha row, so the "NextY" function > can't simply skip - the skipping has to be done at the higher level in > > endRendering - or at least with the cooperation of endRendering. > Since > it asks what the "current Y" is near the top of the loop, it could > detect if the current Y jumped out of the given alpha row, emit it, > and > prepare for a new alpha row starting at the new Y...? > > > -- Done with skipping gaps -- > > -- Alpha accumulation opt -- > > > The [pix+1] lines were the gotcha that always confused me when I tried > > to do this in the past. Basically if you enter an inside region at 1 > > subpixel before the end of a pixel then you need to add one to the > coverage for that pixel. But, starting with the next pixel you want > the > total contribution of the interior region to be NUM_POS per pixel, but > > you've only added 1 so far - so you have to add the additional amount > so > that the total amount added for each "enter" crossing ends up being > NUM_POS. Similarly, when you decrement for the "exit" crossing you > need > to ensure that the total negative delta sums to NUM_POS across the > pixel > where the exit happens and the following pixel. Does that make > sense? > > Note that you could still have the "single pixel" optimization which > would look like: > > alpha[pix_x0 ] += (x1 - x0); > alpha[pix_x0+1] -= (x1 - x0); > > and is equivalent to the above 4 lines. > > then when you do the RLE, you simply have to use an accumulation as > you > scan the alpha row: > > byte nextVal = startVal + alphaRow[i]; > > So, for the cost of an add per pixel as you do the RLE you can avoid > having to do the loop in the "multiple pixel section" when filling the > > alpha array. > > I don't think I've ever quantified this optimization so it might be > better to investigate it after the current code goes in and adopt it > only if it shows a big savings. > > -- Done with alpha accumulation opt -- > > Something about the "emit last row" code bothers me. First, I would > guess that the "y == boundsMaxY - 1" test would have already flushed > the > row, right? Also, why do the for loop? Why not just flush the row if > > it isn't flushed? I kind of feel like the "y == boundsMaxY-1" test > could be removed from inside the loop and simply test if there is > unflushed data in the alpha array then just make a call to emitRow() > with the appropriate values after the loop. > > while (hasNext()) { > ... > if ((y & MASK) == MASK) { > emitRow(...); > pix_min,max = MAX,MIN; > } > } > if (pix_min < pix_max) { > emitRow(...); > } > > Am I missing something? > > So, the upshot is that I didn't find anything wrong. You can take or > > leave my suggestions for improvements as you see fit and maybe save > some > of them for a second round after this goes back... > > ...jim > > On 7/29/2010 2:16 PM, Denis Lila wrote: > > Hello Jim. > > > > I made the changes you point out, except for your second point > > (I don't have time to think about it right now). > > > > I stopped precomputing m00_2_m01_2 because it was only being > > used in one place. But I guess it worth it to precompute it > > if it's going to be used often (and computeOffset is called > > for every line). > > > > The new webrev is at > http://icedtea.classpath.org/~dlila/webrevs/fpBetterAAv2/webrev/ > > > > Thanks, > > Denis. From james.graham at oracle.com Fri Jul 30 23:43:40 2010 From: james.graham at oracle.com (Jim Graham) Date: Fri, 30 Jul 2010 16:43:40 -0700 Subject: [OpenJDK 2D-Dev] Various fixes to pisces stroke widening code In-Reply-To: <459805495.1399131280528843009.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> References: <459805495.1399131280528843009.JavaMail.root@zmail04.collab.prod.int.phx2.redhat.com> Message-ID: <4C5363AC.3060308@oracle.com> Hi Denis, It looks fine. Hopefully we can eventually figure out why the sorting on the fly didn't pan out. Denis Lila wrote: > Hi Jim. > > Thanks for all your suggestions. I fixed the edge array indexing > issue, the moveTo bug (not assigning x0), and the double > initialization issue. I also improved the emission of the last row > to what you said. The link is the same as the last one I sent. I'm guessing the test for "y == boundsMaxY-1" at line 470 could probably also be deleted now (since it will be handled by the end test when y reaches maxY)? But everything looks in order! ...jim