diff options
731 files changed, 32670 insertions, 15203 deletions
@@ -1,3 +1,89 @@ +2012-07-18 Thiago Marcos P. Santos <thiago.santos@intel.com> + + [CMake] Make gtest a shared library + https://bugs.webkit.org/show_bug.cgi?id=90973 + + Reviewed by Daniel Bates. + + It's nicer to make it a shared library because it might improve + linking time and we don't need to force gtest users to link with gtest + dependencies like pthreads (which causes linking errors when it is not + available). + + * Source/cmake/gtest/CMakeLists.txt: + +2012-07-17 Gabor Ballabas <gaborb@inf.u-szeged.hu> + + [Qt][V8] Remove the V8 related codepaths and configuration + https://bugs.webkit.org/show_bug.cgi?id=90863 + + Reviewed by Simon Hausmann. + + * Source/api.pri: + * WebKit.pro: + +2012-07-17 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r122834. + http://trac.webkit.org/changeset/122834 + https://bugs.webkit.org/show_bug.cgi?id=91492 + + it broke the chromium (Requested by kkristof on #webkit). + + * Source/api.pri: + * WebKit.pro: + +2012-07-17 Gabor Ballabas <gaborb@inf.u-szeged.hu> + + [Qt][V8] Remove the V8 related codepaths and configuration + https://bugs.webkit.org/show_bug.cgi?id=90863 + + Reviewed by Simon Hausmann. + + * Source/api.pri: + * WebKit.pro: + +2012-07-17 David Barr <davidbarr@chromium.org> + + Introduce ENABLE_CSS_IMAGE_ORIENTATION compile flag + https://bugs.webkit.org/show_bug.cgi?id=89055 + + Reviewed by Kent Tamura. + + The css3-images module is at candidate recommendation. + http://www.w3.org/TR/2012/CR-css3-images-20120417/#the-image-orientation + + Add a configuration option for CSS image-orientation support, disabling it by default. + + * Source/cmake/WebKitFeatures.cmake: + * Source/cmakeconfig.h.cmake: + +2012-07-16 Pete Williamson <petewil@google.com> + + Expose an export for the iconUrl list so Internals can use it + https://bugs.webkit.org/show_bug.cgi?id=88665 + + Reviewed by Kent Tamura. + + * Source/autotools/symbols.filter: export iconURLs + +2012-07-16 Hajime Morrita <morrita@chromium.org> + + WebCore needs WEBCORE_TESTING macro to mark methods being exported for testing. + https://bugs.webkit.org/show_bug.cgi?id=90764 + + Reviewed by Adam Barth. + + Removed symbols which are now covered by WEBCORE_TESTING. + + * Source/autotools/symbols.filter: + +2012-07-16 Carlos Garcia Campos <cgarcia@igalia.com> + + Unreviewed. Update NEWS and configure.ac for 1.9.5 release + + * configure.ac: Bump version number. + 2012-07-12 Josh Hawn <jhawn@apple.com> Fix for WebContext::getWebCoreStatistics() causes crash if no m_process diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog index 79b7789b2..0d7945765 100644 --- a/Source/JavaScriptCore/ChangeLog +++ b/Source/JavaScriptCore/ChangeLog @@ -1,20 +1,457 @@ -2012-06-13 Patrick Gansterer <paroga@webkit.org> +2012-07-17 Filip Pizlo <fpizlo@apple.com> - [WIN] Remove dependency on pthread from MachineStackMarker - https://bugs.webkit.org/show_bug.cgi?id=68429 + DFG 32-bit PutById transition stub passes the payload/tag arguments to a DFG operation in the wrong order + https://bugs.webkit.org/show_bug.cgi?id=91576 - Reviewed by NOBODY (OOPS!). + Reviewed by Gavin Barraclough. + + * dfg/DFGRepatch.cpp: + (JSC::DFG::emitPutTransitionStub): - Implement pthread TLS functionality with native windows functions. +2012-07-17 Filip Pizlo <fpizlo@apple.com> - * heap/MachineStackMarker.cpp: Use the new functions instead of pthread directly. - * heap/MachineStackMarker.h: - * wtf/ThreadSpecific.h: - (WTF::ThreadSpecificKeyCreate): Added wrapper around pthread_key_create. - (WTF::ThreadSpecificKeyDelete): Added wrapper around pthread_key_delete. - (WTF::ThreadSpecificSet): Added wrapper around pthread_setspecific. - (WTF::ThreadSpecificGet): Added wrapper around pthread_getspecific. - * wtf/ThreadSpecificWin.cpp: + [Qt] REGRESSION(r122768, r122771): They broke jquery/data.html and inspector/elements/edit-dom-actions.html + https://bugs.webkit.org/show_bug.cgi?id=91476 + + Reviewed by Mark Hahnenberg. + + The 32-bit repatching code was not correctly adapted to the new world where there may not always + be an available scratch register. Fixed it by ensuring that the scratch register we select does + not overlap with the value tag. + + * dfg/DFGRepatch.cpp: + (JSC::DFG::generateProtoChainAccessStub): + (JSC::DFG::tryCacheGetByID): + (JSC::DFG::tryBuildGetByIDList): + (JSC::DFG::emitPutReplaceStub): + +2012-07-17 Gabor Rapcsanyi <rgabor@webkit.org> + + Unreviewed buildfix from Zoltan Herczeg after 122768. + + * dfg/DFGCCallHelpers.h: + (JSC::DFG::CCallHelpers::setupArgumentsWithExecState): + (CCallHelpers): + +2012-07-17 David Barr <davidbarr@chromium.org> + + Introduce ENABLE_CSS_IMAGE_ORIENTATION compile flag + https://bugs.webkit.org/show_bug.cgi?id=89055 + + Reviewed by Kent Tamura. + + The css3-images module is at candidate recommendation. + http://www.w3.org/TR/2012/CR-css3-images-20120417/#the-image-orientation + + Add a configuration option for CSS image-orientation support, disabling it by default. + + * Configurations/FeatureDefines.xcconfig: + +2012-07-16 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, roll out 122790 because it broke the Windows build. I'm not + sure what to do with exported symbols that are predicated on NDEBUG. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * bytecode/CodeBlock.cpp: + (JSC): + * bytecode/CodeBlock.h: + (CodeBlock): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::generate): + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::link): + * interpreter/Interpreter.cpp: + (JSC): + (JSC::Interpreter::dumpRegisters): + (JSC::getCallerInfo): + (JSC::Interpreter::getStackTrace): + (JSC::Interpreter::retrieveCallerFromVMCode): + * interpreter/Interpreter.h: + (Interpreter): + * jsc.cpp: + (GlobalObject::finishCreation): + +2012-07-16 Oliver Hunt <oliver@apple.com> + + dumpCallFrame is broken in ToT + https://bugs.webkit.org/show_bug.cgi?id=91444 + + Reviewed by Gavin Barraclough. + + Various changes have been made to the SF calling convention, but + dumpCallFrame has not been updated to reflect these changes. + That resulted in both bogus information, as well as numerous + assertions of sadness. + + This patch makes dumpCallFrame actually work again and adds the + wonderful feature of telling you the name of the variable that a + register reflects, or what value it contains. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::nameForRegister): + A really innefficient mechanism for finding the name of a local register. + This should only ever be used by debug code so this should be okay. + * bytecode/CodeBlock.h: + (CodeBlock): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::generate): + Debug builds no longer throw away a functions symbol table, this allows + us to actually perform a register# to name mapping + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::link): + We weren't propogating the bytecode offset here leading to assertions + in debug builds when dumping bytecode of DFG compiled code. + * interpreter/Interpreter.cpp: + (JSC): + (JSC::Interpreter::dumpRegisters): + Rework to actually be correct. + (JSC::getCallerInfo): + Return the byteocde offset as well now, given we have to determine it + anyway. + (JSC::Interpreter::getStackTrace): + (JSC::Interpreter::retrieveCallerFromVMCode): + * interpreter/Interpreter.h: + (Interpreter): + * jsc.cpp: + (GlobalObject::finishCreation): + (functionDumpCallFrame): + Give debug builds of JSC a method for calling dumpCallFrame so we can + inspect a callframe without requiring us to break in a debugger. + +2012-07-16 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, adding forgotten files. + + * dfg/DFGRegisterSet.h: Added. + (DFG): + (RegisterSet): + (JSC::DFG::RegisterSet::RegisterSet): + (JSC::DFG::RegisterSet::asPOD): + (JSC::DFG::RegisterSet::copyInfo): + (JSC::DFG::RegisterSet::set): + (JSC::DFG::RegisterSet::setGPRByIndex): + (JSC::DFG::RegisterSet::clear): + (JSC::DFG::RegisterSet::get): + (JSC::DFG::RegisterSet::getGPRByIndex): + (JSC::DFG::RegisterSet::getFreeGPR): + (JSC::DFG::RegisterSet::setFPRByIndex): + (JSC::DFG::RegisterSet::getFPRByIndex): + (JSC::DFG::RegisterSet::setByIndex): + (JSC::DFG::RegisterSet::getByIndex): + (JSC::DFG::RegisterSet::numberOfSetGPRs): + (JSC::DFG::RegisterSet::numberOfSetFPRs): + (JSC::DFG::RegisterSet::numberOfSetRegisters): + (JSC::DFG::RegisterSet::setBit): + (JSC::DFG::RegisterSet::clearBit): + (JSC::DFG::RegisterSet::getBit): + * dfg/DFGScratchRegisterAllocator.h: Added. + (DFG): + (ScratchRegisterAllocator): + (JSC::DFG::ScratchRegisterAllocator::ScratchRegisterAllocator): + (JSC::DFG::ScratchRegisterAllocator::lock): + (JSC::DFG::ScratchRegisterAllocator::allocateScratch): + (JSC::DFG::ScratchRegisterAllocator::allocateScratchGPR): + (JSC::DFG::ScratchRegisterAllocator::allocateScratchFPR): + (JSC::DFG::ScratchRegisterAllocator::didReuseRegisters): + (JSC::DFG::ScratchRegisterAllocator::preserveReusedRegistersByPushing): + (JSC::DFG::ScratchRegisterAllocator::restoreReusedRegistersByPopping): + (JSC::DFG::ScratchRegisterAllocator::desiredScratchBufferSize): + (JSC::DFG::ScratchRegisterAllocator::preserveUsedRegistersToScratchBuffer): + (JSC::DFG::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBuffer): + +2012-07-15 Filip Pizlo <fpizlo@apple.com> + + DFG PutById transition should handle storage allocation, and inline it + https://bugs.webkit.org/show_bug.cgi?id=91337 + + Reviewed by Oliver Hunt. + + This enables the patching of DFG PutById to handle the out-of-line storage + allocation case. Furthermore, it inlines out-of-line storage allocation (and + reallocation) into the generated stubs. + + To do this, this patch adds the ability to store the relevant register + allocation state (i.e. the set of in-use registers) in the structure stub + info so that the stub generation code can more flexibly select scratch + registers: sometimes it needs none, sometimes one - or sometimes up to + three. Moreover, to make the stub generation register allocation simple and + maintainable, this patch introduces a reusable scratch register allocator + class. This register allocator understands that some registers are in use by + the main path code and so must be spilled as necessary, other registers are + locked for use in the stub itself and so cannot even be spilled, while still + others may be allocated for scratch purposes. A scratch register that is + used must be spilled. If a register is locked, it cannot be used as a + scratch register. If a register is used, it can be used as a scratch + register so long as it is spilled. + + This is a sub-1% speed-up on V8 and neutral elsewhere. + + * GNUmakefile.list.am: + * JavaScriptCore.xcodeproj/project.pbxproj: + * assembler/MacroAssemblerCodeRef.h: + (FunctionPtr): + (JSC::FunctionPtr::FunctionPtr): + * bytecode/StructureStubInfo.h: + * dfg/DFGCCallHelpers.h: + (JSC::DFG::CCallHelpers::setupArgumentsWithExecState): + (CCallHelpers): + * dfg/DFGGPRInfo.h: + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::link): + * dfg/DFGJITCompiler.h: + (JSC::DFG::PropertyAccessRecord::PropertyAccessRecord): + (PropertyAccessRecord): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGRegisterBank.h: + (JSC::DFG::RegisterBank::isInUse): + (RegisterBank): + * dfg/DFGRegisterSet.h: Added. + (DFG): + (RegisterSet): + (JSC::DFG::RegisterSet::RegisterSet): + (JSC::DFG::RegisterSet::asPOD): + (JSC::DFG::RegisterSet::copyInfo): + (JSC::DFG::RegisterSet::set): + (JSC::DFG::RegisterSet::setGPRByIndex): + (JSC::DFG::RegisterSet::clear): + (JSC::DFG::RegisterSet::get): + (JSC::DFG::RegisterSet::getGPRByIndex): + (JSC::DFG::RegisterSet::getFreeGPR): + (JSC::DFG::RegisterSet::setFPRByIndex): + (JSC::DFG::RegisterSet::getFPRByIndex): + (JSC::DFG::RegisterSet::setByIndex): + (JSC::DFG::RegisterSet::getByIndex): + (JSC::DFG::RegisterSet::numberOfSetGPRs): + (JSC::DFG::RegisterSet::numberOfSetFPRs): + (JSC::DFG::RegisterSet::numberOfSetRegisters): + (JSC::DFG::RegisterSet::setBit): + (JSC::DFG::RegisterSet::clearBit): + (JSC::DFG::RegisterSet::getBit): + * dfg/DFGRepatch.cpp: + (JSC::DFG::generateProtoChainAccessStub): + (JSC::DFG::tryCacheGetByID): + (JSC::DFG::tryBuildGetByIDList): + (JSC::DFG::emitPutReplaceStub): + (JSC::DFG::emitPutTransitionStub): + (JSC::DFG::tryCachePutByID): + (JSC::DFG::tryBuildPutByIdList): + * dfg/DFGScratchRegisterAllocator.h: Added. + (DFG): + (ScratchRegisterAllocator): + (JSC::DFG::ScratchRegisterAllocator::ScratchRegisterAllocator): + (JSC::DFG::ScratchRegisterAllocator::lock): + (JSC::DFG::ScratchRegisterAllocator::allocateScratch): + (JSC::DFG::ScratchRegisterAllocator::allocateScratchGPR): + (JSC::DFG::ScratchRegisterAllocator::allocateScratchFPR): + (JSC::DFG::ScratchRegisterAllocator::didReuseRegisters): + (JSC::DFG::ScratchRegisterAllocator::preserveReusedRegistersByPushing): + (JSC::DFG::ScratchRegisterAllocator::restoreReusedRegistersByPopping): + (JSC::DFG::ScratchRegisterAllocator::desiredScratchBufferSize): + (JSC::DFG::ScratchRegisterAllocator::preserveUsedRegistersToScratchBuffer): + (JSC::DFG::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBuffer): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + (JSC::DFG::SpeculativeJIT::usedRegisters): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::cachedGetById): + (JSC::DFG::SpeculativeJIT::cachedPutById): + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::cachedGetById): + (JSC::DFG::SpeculativeJIT::cachedPutById): + (JSC::DFG::SpeculativeJIT::compile): + * heap/CopiedAllocator.h: + (CopiedAllocator): + (JSC::CopiedAllocator::fastPathShouldSucceed): + (JSC): + +2012-07-16 Patrick Gansterer <paroga@webkit.org> + + Add dfg switch to create_jit_stubs script + https://bugs.webkit.org/show_bug.cgi?id=91256 + + Reviewed by Geoffrey Garen. + + * create_jit_stubs: Add a switch to enable or disable the generation of + stub functions in #if ENABLE(DFG_JIT) conditions. + +2012-07-16 Gabor Rapcsanyi <rgabor@webkit.org> + + Unreviewed buildfix after r122729. Typo fix. + + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::add32): + +2012-07-16 Gabor Rapcsanyi <rgabor@webkit.org> + + Unreviewed buildfix from Zoltan Herczeg after r122677. + Implement missing add32 function to MacroAssemblerARM. + + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::add32): + (MacroAssemblerARM): + +2012-07-14 Filip Pizlo <fpizlo@apple.com> + + DFG PutByVal opcodes should accept more than 3 operands + https://bugs.webkit.org/show_bug.cgi?id=91332 + + Reviewed by Oliver Hunt. + + Turned PutByVal/PutByValAlias into var-arg nodes, so that we can give them + 4 or more operands in the future. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::getByValLoadElimination): + (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGFixupPhase.cpp: + (JSC::DFG::FixupPhase::fixupNode): + (JSC::DFG::FixupPhase::fixDoubleEdge): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::byValIsPure): + (JSC::DFG::Graph::varArgNumChildren): + (Graph): + (JSC::DFG::Graph::numChildren): + (JSC::DFG::Graph::varArgChild): + (JSC::DFG::Graph::child): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray): + (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-07-14 Filip Pizlo <fpizlo@apple.com> + + Rationalize and optimize storage allocation + https://bugs.webkit.org/show_bug.cgi?id=91303 + + Reviewed by Oliver Hunt. + + This implements a backwards bump allocator for copied space storage + allocation, shown in pseudo-code below: + + pointer bump(size) { + pointer tmp = allocator->remaining; + tmp -= size; + if (tmp < 0) + fail; + allocator->remaining = tmp; + return allocator->payloadEnd - tmp - size; + } + + The advantage of this allocator is that it: + + - Only requires one comparison in the common case where size is known to + not be huge, and this comparison can be done by checking the sign bit + of the subtraction. + + - Can be implemented even when only one register is available. This + register is reused for both temporary storage during allocation and + for the result. + + - Preserves the behavior that memory in a block is filled in from lowest + address to highest address, which allows for a cheap reallocation fast + path. + + - Is resilient against the block used for allocation being the last one + in virtual memory, thereby otherwise leading to the risk of overflow + in the bump pointer, despite only doing one branch. + + In order to implement this allocator using the smallest possible chunk + of code, I refactored the copied space code so that all of the allocation + logic is in CopiedAllocator, and all of the state is in either + CopiedBlock or CopiedAllocator. This should make changing the allocation + fast path easier in the future. + + In order to do this, I needed to add some new assembler support, + particularly for various forms of add(address, register) and negPtr(). + + This is performance neutral. The purpose of this change is to facilitate + further inlining of storage allocation without having to reserve + additional registers or emit too much code. + + * assembler/MacroAssembler.h: + (JSC::MacroAssembler::addPtr): + (MacroAssembler): + (JSC::MacroAssembler::negPtr): + * assembler/MacroAssemblerARMv7.h: + (MacroAssemblerARMv7): + (JSC::MacroAssemblerARMv7::add32): + * assembler/MacroAssemblerX86.h: + (JSC::MacroAssemblerX86::add32): + (MacroAssemblerX86): + * assembler/MacroAssemblerX86_64.h: + (MacroAssemblerX86_64): + (JSC::MacroAssemblerX86_64::addPtr): + (JSC::MacroAssemblerX86_64::negPtr): + * assembler/X86Assembler.h: + (X86Assembler): + (JSC::X86Assembler::addl_mr): + (JSC::X86Assembler::addq_mr): + (JSC::X86Assembler::negq_r): + * heap/CopiedAllocator.h: + (CopiedAllocator): + (JSC::CopiedAllocator::isValid): + (JSC::CopiedAllocator::CopiedAllocator): + (JSC::CopiedAllocator::tryAllocate): + (JSC): + (JSC::CopiedAllocator::tryReallocate): + (JSC::CopiedAllocator::forceAllocate): + (JSC::CopiedAllocator::resetCurrentBlock): + (JSC::CopiedAllocator::setCurrentBlock): + (JSC::CopiedAllocator::currentCapacity): + * heap/CopiedBlock.h: + (CopiedBlock): + (JSC::CopiedBlock::create): + (JSC::CopiedBlock::zeroFillWilderness): + (JSC::CopiedBlock::CopiedBlock): + (JSC::CopiedBlock::payloadEnd): + (JSC): + (JSC::CopiedBlock::payloadCapacity): + (JSC::CopiedBlock::data): + (JSC::CopiedBlock::dataEnd): + (JSC::CopiedBlock::dataSize): + (JSC::CopiedBlock::wilderness): + (JSC::CopiedBlock::wildernessEnd): + (JSC::CopiedBlock::wildernessSize): + (JSC::CopiedBlock::size): + * heap/CopiedSpace.cpp: + (JSC::CopiedSpace::tryAllocateSlowCase): + (JSC::CopiedSpace::tryAllocateOversize): + (JSC::CopiedSpace::tryReallocate): + (JSC::CopiedSpace::doneFillingBlock): + (JSC::CopiedSpace::doneCopying): + * heap/CopiedSpace.h: + (CopiedSpace): + * heap/CopiedSpaceInlineMethods.h: + (JSC::CopiedSpace::startedCopying): + (JSC::CopiedSpace::allocateBlockForCopyingPhase): + (JSC::CopiedSpace::allocateBlock): + (JSC::CopiedSpace::tryAllocate): + (JSC): + * heap/MarkStack.cpp: + (JSC::SlotVisitor::startCopying): + (JSC::SlotVisitor::allocateNewSpace): + (JSC::SlotVisitor::doneCopying): + * heap/SlotVisitor.h: + (JSC::SlotVisitor::SlotVisitor): + * jit/JIT.h: + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateBasicStorage): + (JSC::JIT::emitAllocateJSArray): 2012-07-13 Mark Lam <mark.lam@apple.com> diff --git a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig index 5fa30a6e9..dcea98333 100644 --- a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig +++ b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig @@ -41,6 +41,7 @@ ENABLE_CSS3_FLEXBOX = ENABLE_CSS3_FLEXBOX; ENABLE_CSS_EXCLUSIONS = ENABLE_CSS_EXCLUSIONS; ENABLE_CSS_FILTERS = ENABLE_CSS_FILTERS; ENABLE_CSS_SHADERS = ENABLE_CSS_SHADERS; +ENABLE_CSS_IMAGE_ORIENTATION = ; ENABLE_CSS_IMAGE_RESOLUTION = ; ENABLE_CSS_REGIONS = ENABLE_CSS_REGIONS; ENABLE_CSS_VARIABLES = ; @@ -133,4 +134,4 @@ ENABLE_WEB_TIMING = ; ENABLE_WORKERS = ENABLE_WORKERS; ENABLE_XSLT = ENABLE_XSLT; -FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS3_FLEXBOX) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_VARIABLES) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIALOG_ELEMENT) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LINK_PREFETCH) $(ENABLE_LINK_PRERENDER) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_TAG) $(ENABLE_MICRODATA) $(ENABLE_MUTATION_OBSERVERS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_TAG) $(ENABLE_QUOTA) $(ENABLE_REGISTER_PROTOCOL_HANDLER) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SVG) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TEXT_NOTIFICATIONS_ONLY) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_UNDO_MANAGER) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XSLT); +FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS3_FLEXBOX) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_VARIABLES) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIALOG_ELEMENT) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LINK_PREFETCH) $(ENABLE_LINK_PRERENDER) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_TAG) $(ENABLE_MICRODATA) $(ENABLE_MUTATION_OBSERVERS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_TAG) $(ENABLE_QUOTA) $(ENABLE_REGISTER_PROTOCOL_HANDLER) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SVG) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TEXT_NOTIFICATIONS_ONLY) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_UNDO_MANAGER) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XSLT); diff --git a/Source/JavaScriptCore/Configurations/Version.xcconfig b/Source/JavaScriptCore/Configurations/Version.xcconfig index 9760c9ada..39ad1b2be 100644 --- a/Source/JavaScriptCore/Configurations/Version.xcconfig +++ b/Source/JavaScriptCore/Configurations/Version.xcconfig @@ -22,7 +22,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. MAJOR_VERSION = 537; -MINOR_VERSION = 1; +MINOR_VERSION = 2; TINY_VERSION = 0; FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION); diff --git a/Source/JavaScriptCore/GNUmakefile.list.am b/Source/JavaScriptCore/GNUmakefile.list.am index 751d5657a..e21ad80d7 100644 --- a/Source/JavaScriptCore/GNUmakefile.list.am +++ b/Source/JavaScriptCore/GNUmakefile.list.am @@ -216,9 +216,11 @@ javascriptcore_sources += \ Source/JavaScriptCore/dfg/DFGRedundantPhiEliminationPhase.cpp \ Source/JavaScriptCore/dfg/DFGRedundantPhiEliminationPhase.h \ Source/JavaScriptCore/dfg/DFGRegisterBank.h \ + Source/JavaScriptCore/dfg/DFGRegisterSet.h \ Source/JavaScriptCore/dfg/DFGRepatch.cpp \ Source/JavaScriptCore/dfg/DFGRepatch.h \ Source/JavaScriptCore/dfg/DFGScoreBoard.h \ + Source/JavaScriptCore/dfg/DFGScratchRegisterAllocator.h \ Source/JavaScriptCore/dfg/DFGSilentRegisterSavePlan.h \ Source/JavaScriptCore/dfg/DFGSlowPathGenerator.h \ Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp \ diff --git a/Source/JavaScriptCore/JavaScriptCore.pri b/Source/JavaScriptCore/JavaScriptCore.pri index f6580c51f..380bbaf1b 100644 --- a/Source/JavaScriptCore/JavaScriptCore.pri +++ b/Source/JavaScriptCore/JavaScriptCore.pri @@ -34,6 +34,12 @@ INCLUDEPATH += \ win32-* { LIBS += -lwinmm + + win32-g++* { + LIBS += -lpthreadGC2 + } else:win32-msvc* { + LIBS += -lpthreadVC2 + } } wince* { diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj index f9548f184..a81416659 100644 --- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj @@ -150,6 +150,8 @@ 0F766D3515AE253B008F363E /* JumpReplacementWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D3315AE2535008F363E /* JumpReplacementWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F766D3815AE4A1C008F363E /* StructureStubClearingWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F766D3615AE4A1A008F363E /* StructureStubClearingWatchpoint.cpp */; }; 0F766D3915AE4A1F008F363E /* StructureStubClearingWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D3715AE4A1A008F363E /* StructureStubClearingWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0F766D4415B2A3C0008F363E /* DFGRegisterSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D4215B2A3BD008F363E /* DFGRegisterSet.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0F766D4615B3701F008F363E /* DFGScratchRegisterAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D4515B3701D008F363E /* DFGScratchRegisterAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7700911402FF280078EB39 /* SamplingCounter.cpp */; }; 0F7B294A14C3CD29007C3DB1 /* DFGCCallHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7B294814C3CD23007C3DB1 /* DFGCCallHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82E1F14172C2F00179C94 /* DFGCapabilities.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -895,6 +897,8 @@ 0F766D3315AE2535008F363E /* JumpReplacementWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JumpReplacementWatchpoint.h; sourceTree = "<group>"; }; 0F766D3615AE4A1A008F363E /* StructureStubClearingWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureStubClearingWatchpoint.cpp; sourceTree = "<group>"; }; 0F766D3715AE4A1A008F363E /* StructureStubClearingWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureStubClearingWatchpoint.h; sourceTree = "<group>"; }; + 0F766D4215B2A3BD008F363E /* DFGRegisterSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGRegisterSet.h; path = dfg/DFGRegisterSet.h; sourceTree = "<group>"; }; + 0F766D4515B3701D008F363E /* DFGScratchRegisterAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGScratchRegisterAllocator.h; path = dfg/DFGScratchRegisterAllocator.h; sourceTree = "<group>"; }; 0F77008E1402FDD60078EB39 /* SamplingCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplingCounter.h; sourceTree = "<group>"; }; 0F7700911402FF280078EB39 /* SamplingCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SamplingCounter.cpp; sourceTree = "<group>"; }; 0F7B294814C3CD23007C3DB1 /* DFGCCallHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCCallHelpers.h; path = dfg/DFGCCallHelpers.h; sourceTree = "<group>"; }; @@ -2304,9 +2308,11 @@ 0A4337BA1506218800991C95 /* DFGRedundantPhiEliminationPhase.cpp */, 0A4337BD1506219B00991C95 /* DFGRedundantPhiEliminationPhase.h */, 86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */, + 0F766D4215B2A3BD008F363E /* DFGRegisterSet.h */, 86BB09BE138E381B0056702F /* DFGRepatch.cpp */, 86BB09BF138E381B0056702F /* DFGRepatch.h */, 86ECA3F9132DF25A002B2AD7 /* DFGScoreBoard.h */, + 0F766D4515B3701D008F363E /* DFGScratchRegisterAllocator.h */, 0F1E3A65153A21DF000F9456 /* DFGSilentRegisterSavePlan.h */, 0F1E3A501537C2CB000F9456 /* DFGSlowPathGenerator.h */, 86EC9DC21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp */, @@ -2850,6 +2856,8 @@ 0F766D3115AA8112008F363E /* JITStubRoutine.h in Headers */, 0F766D3515AE253B008F363E /* JumpReplacementWatchpoint.h in Headers */, 0F766D3915AE4A1F008F363E /* StructureStubClearingWatchpoint.h in Headers */, + 0F766D4415B2A3C0008F363E /* DFGRegisterSet.h in Headers */, + 0F766D4615B3701F008F363E /* DFGScratchRegisterAllocator.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Source/JavaScriptCore/assembler/MacroAssembler.h b/Source/JavaScriptCore/assembler/MacroAssembler.h index 516ffac16..1a9af2989 100644 --- a/Source/JavaScriptCore/assembler/MacroAssembler.h +++ b/Source/JavaScriptCore/assembler/MacroAssembler.h @@ -280,6 +280,16 @@ public: // On 32-bit platforms (i.e. x86), these methods directly map onto their 32-bit equivalents. // FIXME: should this use a test for 32-bitness instead of this specific exception? #if !CPU(X86_64) + void addPtr(Address src, RegisterID dest) + { + add32(src, dest); + } + + void addPtr(AbsoluteAddress src, RegisterID dest) + { + add32(src, dest); + } + void addPtr(RegisterID src, RegisterID dest) { add32(src, dest); @@ -314,6 +324,11 @@ public: { and32(imm, srcDest); } + + void negPtr(RegisterID dest) + { + neg32(dest); + } void orPtr(RegisterID src, RegisterID dest) { diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h index 8e123d423..2773b022c 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h @@ -107,6 +107,13 @@ public: m_assembler.adds_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0)); } + void add32(AbsoluteAddress src, RegisterID dest) + { + move(TrustedImmPtr(src.m_ptr), ARMRegisters::S1); + m_assembler.dtr_u(ARMAssembler::LoadUint32, ARMRegisters::S1, ARMRegisters::S1, 0); + add32(ARMRegisters::S1, dest); + } + void add32(Address src, RegisterID dest) { load32(src, ARMRegisters::S1); diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h index 3694c9163..cf6f02ca9 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -157,6 +157,12 @@ public: { add32(imm, dest, dest); } + + void add32(AbsoluteAddress src, RegisterID dest) + { + load32(src.m_ptr, dataTempRegister); + add32(dataTempRegister, dest); + } void add32(TrustedImm32 imm, RegisterID src, RegisterID dest) { diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h b/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h index a1b3a8338..c6db26597 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h @@ -126,6 +126,13 @@ public: ASSERT_VALID_CODE_POINTER(m_value); } + template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4, typename argType5> + FunctionPtr(returnType(*value)(argType1, argType2, argType3, argType4, argType5)) + : m_value((void*)value) + { + ASSERT_VALID_CODE_POINTER(m_value); + } + // MSVC doesn't seem to treat functions with different calling conventions as // different types; these methods already defined for fastcall, below. #if CALLING_CONVENTION_IS_STDCALL && !OS(WINDOWS) diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86.h index 45de8139f..da9dd8f2a 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerX86.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86.h @@ -63,6 +63,11 @@ public: m_assembler.addl_im(imm.m_value, address.m_ptr); } + void add32(AbsoluteAddress address, RegisterID dest) + { + m_assembler.addl_mr(address.m_ptr, dest); + } + void add64(TrustedImm32 imm, AbsoluteAddress address) { m_assembler.addl_im(imm.m_value, address.m_ptr); @@ -78,7 +83,7 @@ public: { m_assembler.orl_im(imm.m_value, address.m_ptr); } - + void sub32(TrustedImm32 imm, AbsoluteAddress address) { m_assembler.subl_im(imm.m_value, address.m_ptr); diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h index 1fb574b51..43bcddb64 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h @@ -63,6 +63,12 @@ public: and32(imm, Address(scratchRegister)); } + void add32(AbsoluteAddress address, RegisterID dest) + { + move(TrustedImmPtr(address.m_ptr), scratchRegister); + add32(Address(scratchRegister), dest); + } + void or32(TrustedImm32 imm, AbsoluteAddress address) { move(TrustedImmPtr(address.m_ptr), scratchRegister); @@ -140,6 +146,17 @@ public: { m_assembler.addq_rr(src, dest); } + + void addPtr(Address src, RegisterID dest) + { + m_assembler.addq_mr(src.offset, src.base, dest); + } + + void addPtr(AbsoluteAddress src, RegisterID dest) + { + move(TrustedImmPtr(src.m_ptr), scratchRegister); + addPtr(Address(scratchRegister), dest); + } void addPtr(TrustedImm32 imm, RegisterID srcDest) { @@ -182,6 +199,11 @@ public: { m_assembler.andq_ir(imm.m_value, srcDest); } + + void negPtr(RegisterID dest) + { + m_assembler.negq_r(dest); + } void orPtr(RegisterID src, RegisterID dest) { diff --git a/Source/JavaScriptCore/assembler/X86Assembler.h b/Source/JavaScriptCore/assembler/X86Assembler.h index cf8133266..83d681cf7 100644 --- a/Source/JavaScriptCore/assembler/X86Assembler.h +++ b/Source/JavaScriptCore/assembler/X86Assembler.h @@ -304,6 +304,13 @@ public: { m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset); } + +#if !CPU(X86_64) + void addl_mr(const void* addr, RegisterID dst) + { + m_formatter.oneByteOp(OP_ADD_GvEv, dst, addr); + } +#endif void addl_rm(RegisterID src, int offset, RegisterID base) { @@ -338,6 +345,11 @@ public: m_formatter.oneByteOp64(OP_ADD_EvGv, src, dst); } + void addq_mr(int offset, RegisterID base, RegisterID dst) + { + m_formatter.oneByteOp64(OP_ADD_GvEv, dst, base, offset); + } + void addq_ir(int imm, RegisterID dst) { if (CAN_SIGN_EXTEND_8_32(imm)) { @@ -443,6 +455,13 @@ public: m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, dst); } +#if CPU(X86_64) + void negq_r(RegisterID dst) + { + m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_NEG, dst); + } +#endif + void negl_m(int offset, RegisterID base) { m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, base, offset); diff --git a/Source/JavaScriptCore/bytecode/StructureStubInfo.h b/Source/JavaScriptCore/bytecode/StructureStubInfo.h index 737ea88c2..a1bbc9c37 100644 --- a/Source/JavaScriptCore/bytecode/StructureStubInfo.h +++ b/Source/JavaScriptCore/bytecode/StructureStubInfo.h @@ -31,6 +31,7 @@ #if ENABLE(JIT) #include "CodeOrigin.h" +#include "DFGRegisterSet.h" #include "Instruction.h" #include "JITStubRoutine.h" #include "MacroAssembler.h" @@ -212,7 +213,7 @@ namespace JSC { int8_t valueTagGPR; #endif int8_t valueGPR; - int8_t scratchGPR; + DFG::RegisterSetPOD usedRegisters; int32_t deltaCallToDone; int32_t deltaCallToStorageLoad; int32_t deltaCallToStructCheck; diff --git a/Source/JavaScriptCore/create_jit_stubs b/Source/JavaScriptCore/create_jit_stubs index f0fcb53b0..d90fa8eb4 100644 --- a/Source/JavaScriptCore/create_jit_stubs +++ b/Source/JavaScriptCore/create_jit_stubs @@ -28,10 +28,12 @@ my $rtype_template = quotemeta("#rtype#"); my $op_template = quotemeta("#op#"); my $prefix; +my $enable_dfg = 0; my $file; my $getOptionsResult = GetOptions( - 'prefix=s' => \$prefix + 'prefix=s' => \$prefix, + 'dfg!' => \$enable_dfg ); $file = $ARGV[0]; @@ -44,11 +46,25 @@ my $stub = ""; my $rtype = ""; my $op = ""; +my $if_counter = 0; +my $dfg_begin = 0; print STDERR "Creating JIT stubs for $file \n"; open(IN, $file) or die "No such file $file"; while ( $_ = <IN> ) { + if ( /^#if (.*)/ ) { + $if_counter++; + if ( $1 eq "ENABLE(DFG_JIT)" ) { + $dfg_begin = $if_counter; + } + } + if ( /^#endif/ ) { + if ( $if_counter == $dfg_begin ) { + $dfg_begin = 0; + } + $if_counter--; + } if ( /^$prefix\_BEGIN\((.*)\)/ ) { $stub = $1; print $stub . "\n"; @@ -66,7 +82,9 @@ while ( $_ = <IN> ) { $stub =~ s/$rtype_template/$rtype/g; $stub =~ s/$op_template/$op/g; $stub =~ s/\\\*/\*/g; - print $stub; + if ( $enable_dfg == 1 || $dfg_begin == 0 ) { + print $stub; + } } } diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp index 95f44c092..e4561da06 100644 --- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp +++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp @@ -946,13 +946,18 @@ bool AbstractState::execute(unsigned indexInBlock) case PutByVal: case PutByValAlias: { node.setCanExit(true); - if (!m_graph[node.child1()].prediction() || !m_graph[node.child2()].prediction()) { + + Edge child1 = m_graph.varArgChild(node, 0); + Edge child2 = m_graph.varArgChild(node, 1); + Edge child3 = m_graph.varArgChild(node, 2); + + if (!m_graph[child1].prediction() || !m_graph[child2].prediction()) { m_isValid = false; break; } - if (!m_graph[node.child2()].shouldSpeculateInteger() || !isActionableMutableArraySpeculation(m_graph[node.child1()].prediction()) + if (!m_graph[child2].shouldSpeculateInteger() || !isActionableMutableArraySpeculation(m_graph[child1].prediction()) #if USE(JSVALUE32_64) - || m_graph[node.child1()].shouldSpeculateArguments() + || m_graph[child1].shouldSpeculateArguments() #endif ) { ASSERT(node.op() == PutByVal); @@ -961,89 +966,89 @@ bool AbstractState::execute(unsigned indexInBlock) break; } - if (m_graph[node.child1()].shouldSpeculateArguments()) { - forNode(node.child1()).filter(SpecArguments); - forNode(node.child2()).filter(SpecInt32); + if (m_graph[child1].shouldSpeculateArguments()) { + forNode(child1).filter(SpecArguments); + forNode(child2).filter(SpecInt32); break; } - if (m_graph[node.child1()].shouldSpeculateInt8Array()) { - forNode(node.child1()).filter(SpecInt8Array); - forNode(node.child2()).filter(SpecInt32); - if (m_graph[node.child3()].shouldSpeculateInteger()) - forNode(node.child3()).filter(SpecInt32); + if (m_graph[child1].shouldSpeculateInt8Array()) { + forNode(child1).filter(SpecInt8Array); + forNode(child2).filter(SpecInt32); + if (m_graph[child3].shouldSpeculateInteger()) + forNode(child3).filter(SpecInt32); else - forNode(node.child3()).filter(SpecNumber); + forNode(child3).filter(SpecNumber); break; } - if (m_graph[node.child1()].shouldSpeculateInt16Array()) { - forNode(node.child1()).filter(SpecInt16Array); - forNode(node.child2()).filter(SpecInt32); - if (m_graph[node.child3()].shouldSpeculateInteger()) - forNode(node.child3()).filter(SpecInt32); + if (m_graph[child1].shouldSpeculateInt16Array()) { + forNode(child1).filter(SpecInt16Array); + forNode(child2).filter(SpecInt32); + if (m_graph[child3].shouldSpeculateInteger()) + forNode(child3).filter(SpecInt32); else - forNode(node.child3()).filter(SpecNumber); + forNode(child3).filter(SpecNumber); break; } - if (m_graph[node.child1()].shouldSpeculateInt32Array()) { - forNode(node.child1()).filter(SpecInt32Array); - forNode(node.child2()).filter(SpecInt32); - if (m_graph[node.child3()].shouldSpeculateInteger()) - forNode(node.child3()).filter(SpecInt32); + if (m_graph[child1].shouldSpeculateInt32Array()) { + forNode(child1).filter(SpecInt32Array); + forNode(child2).filter(SpecInt32); + if (m_graph[child3].shouldSpeculateInteger()) + forNode(child3).filter(SpecInt32); else - forNode(node.child3()).filter(SpecNumber); + forNode(child3).filter(SpecNumber); break; } - if (m_graph[node.child1()].shouldSpeculateUint8Array()) { - forNode(node.child1()).filter(SpecUint8Array); - forNode(node.child2()).filter(SpecInt32); - if (m_graph[node.child3()].shouldSpeculateInteger()) - forNode(node.child3()).filter(SpecInt32); + if (m_graph[child1].shouldSpeculateUint8Array()) { + forNode(child1).filter(SpecUint8Array); + forNode(child2).filter(SpecInt32); + if (m_graph[child3].shouldSpeculateInteger()) + forNode(child3).filter(SpecInt32); else - forNode(node.child3()).filter(SpecNumber); + forNode(child3).filter(SpecNumber); break; } - if (m_graph[node.child1()].shouldSpeculateUint8ClampedArray()) { - forNode(node.child1()).filter(SpecUint8ClampedArray); - forNode(node.child2()).filter(SpecInt32); - if (m_graph[node.child3()].shouldSpeculateInteger()) - forNode(node.child3()).filter(SpecInt32); + if (m_graph[child1].shouldSpeculateUint8ClampedArray()) { + forNode(child1).filter(SpecUint8ClampedArray); + forNode(child2).filter(SpecInt32); + if (m_graph[child3].shouldSpeculateInteger()) + forNode(child3).filter(SpecInt32); else - forNode(node.child3()).filter(SpecNumber); + forNode(child3).filter(SpecNumber); break; } - if (m_graph[node.child1()].shouldSpeculateUint16Array()) { - forNode(node.child1()).filter(SpecUint16Array); - forNode(node.child2()).filter(SpecInt32); - if (m_graph[node.child3()].shouldSpeculateInteger()) - forNode(node.child3()).filter(SpecInt32); + if (m_graph[child1].shouldSpeculateUint16Array()) { + forNode(child1).filter(SpecUint16Array); + forNode(child2).filter(SpecInt32); + if (m_graph[child3].shouldSpeculateInteger()) + forNode(child3).filter(SpecInt32); else - forNode(node.child3()).filter(SpecNumber); + forNode(child3).filter(SpecNumber); break; } - if (m_graph[node.child1()].shouldSpeculateUint32Array()) { - forNode(node.child1()).filter(SpecUint32Array); - forNode(node.child2()).filter(SpecInt32); - if (m_graph[node.child3()].shouldSpeculateInteger()) - forNode(node.child3()).filter(SpecInt32); + if (m_graph[child1].shouldSpeculateUint32Array()) { + forNode(child1).filter(SpecUint32Array); + forNode(child2).filter(SpecInt32); + if (m_graph[child3].shouldSpeculateInteger()) + forNode(child3).filter(SpecInt32); else - forNode(node.child3()).filter(SpecNumber); + forNode(child3).filter(SpecNumber); break; } - if (m_graph[node.child1()].shouldSpeculateFloat32Array()) { - forNode(node.child1()).filter(SpecFloat32Array); - forNode(node.child2()).filter(SpecInt32); - forNode(node.child3()).filter(SpecNumber); + if (m_graph[child1].shouldSpeculateFloat32Array()) { + forNode(child1).filter(SpecFloat32Array); + forNode(child2).filter(SpecInt32); + forNode(child3).filter(SpecNumber); break; } - if (m_graph[node.child1()].shouldSpeculateFloat64Array()) { - forNode(node.child1()).filter(SpecFloat64Array); - forNode(node.child2()).filter(SpecInt32); - forNode(node.child3()).filter(SpecNumber); + if (m_graph[child1].shouldSpeculateFloat64Array()) { + forNode(child1).filter(SpecFloat64Array); + forNode(child2).filter(SpecInt32); + forNode(child3).filter(SpecNumber); break; } - ASSERT(m_graph[node.child1()].shouldSpeculateArray()); - forNode(node.child1()).filter(SpecArray); - forNode(node.child2()).filter(SpecInt32); + ASSERT(m_graph[child1].shouldSpeculateArray()); + forNode(child1).filter(SpecArray); + forNode(child2).filter(SpecInt32); if (node.op() == PutByVal) clobberWorld(node.codeOrigin, indexInBlock); break; diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp index 91b882399..1b1395934 100644 --- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp +++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp @@ -2152,7 +2152,10 @@ bool ByteCodeParser::parseBlock(unsigned limit) NodeIndex property = get(currentInstruction[2].u.operand); NodeIndex value = get(currentInstruction[3].u.operand); - addToGraph(PutByVal, base, property, value); + addVarArgChild(base); + addVarArgChild(property); + addVarArgChild(value); + addToGraph(Node::VarArg, PutByVal, OpInfo(0), OpInfo(0)); NEXT_OPCODE(op_put_by_val); } diff --git a/Source/JavaScriptCore/dfg/DFGCCallHelpers.h b/Source/JavaScriptCore/dfg/DFGCCallHelpers.h index 5985b251e..fd4e1cae0 100644 --- a/Source/JavaScriptCore/dfg/DFGCCallHelpers.h +++ b/Source/JavaScriptCore/dfg/DFGCCallHelpers.h @@ -229,6 +229,27 @@ public: addCallArgument(arg3); } + ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4) + { + resetCallArguments(); + addCallArgument(GPRInfo::callFrameRegister); + addCallArgument(arg1); + addCallArgument(arg2); + addCallArgument(arg3); + addCallArgument(arg4); + } + + ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5) + { + resetCallArguments(); + addCallArgument(GPRInfo::callFrameRegister); + addCallArgument(arg1); + addCallArgument(arg2); + addCallArgument(arg3); + addCallArgument(arg4); + addCallArgument(arg5); + } + ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4) { resetCallArguments(); @@ -570,6 +591,14 @@ public: move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); } + ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3) + { + move(arg1, GPRInfo::argumentGPR1); + move(arg2, GPRInfo::argumentGPR2); + move(arg3, GPRInfo::argumentGPR3); + move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); + } + ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImmPtr arg3) { move(arg1, GPRInfo::argumentGPR1); @@ -642,6 +671,19 @@ public: setupArgumentsWithExecState(arg1, arg2, arg3); } + ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4) + { + poke(arg4); + setupArgumentsWithExecState(arg1, arg2, arg3); + } + + ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5) + { + poke(arg5, 1); + poke(arg4); + setupArgumentsWithExecState(arg1, arg2, arg3); + } + ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4) { poke(arg4); @@ -722,6 +764,16 @@ public: #endif // NUMBER_OF_ARGUMENT_REGISTERS == 4 +#if NUMBER_OF_ARGUMENT_REGISTERS >= 5 + ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4) + { + setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR4>(arg1, arg4); + move(arg2, GPRInfo::argumentGPR2); + move(arg3, GPRInfo::argumentGPR3); + move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); + } +#endif + void setupResults(GPRReg destA, GPRReg destB) { GPRReg srcA = GPRInfo::returnValueGPR; diff --git a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp index 108cf1965..04c3ebc66 100644 --- a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp @@ -284,15 +284,16 @@ private: return index; break; case PutByVal: - case PutByValAlias: + case PutByValAlias: { if (!m_graph.byValIsPure(node)) return NoNode; - if (node.child1() == child1 && canonicalize(node.child2()) == canonicalize(child2)) - return node.child3().index(); + if (m_graph.varArgChild(node, 0) == child1 && canonicalize(m_graph.varArgChild(node, 1)) == canonicalize(child2)) + return m_graph.varArgChild(node, 2).index(); // We must assume that the PutByVal will clobber the location we're getting from. // FIXME: We can do better; if we know that the PutByVal is accessing an array of a // different type than the GetByVal, then we know that they won't clobber each other. return NoNode; + } case PutStructure: case PutByOffset: // GetByVal currently always speculates that it's accessing an @@ -634,7 +635,7 @@ private: break; case PutByVal: - if (isFixedIndexedStorageObjectSpeculation(m_graph[node.child1()].prediction()) && m_graph.byValIsPure(node)) + if (isFixedIndexedStorageObjectSpeculation(m_graph[m_graph.varArgChild(node, 0)].prediction()) && m_graph.byValIsPure(node)) break; return NoNode; @@ -1079,17 +1080,19 @@ private: setReplacement(getByValLoadElimination(node.child1().index(), node.child2().index())); break; - case PutByVal: - if (isActionableMutableArraySpeculation(m_graph[node.child1()].prediction()) - && m_graph[node.child2()].shouldSpeculateInteger() - && !m_graph[node.child1()].shouldSpeculateArguments()) { - NodeIndex nodeIndex = getByValLoadElimination( - node.child1().index(), node.child2().index()); + case PutByVal: { + Edge child1 = m_graph.varArgChild(node, 0); + Edge child2 = m_graph.varArgChild(node, 1); + if (isActionableMutableArraySpeculation(m_graph[child1].prediction()) + && m_graph[child2].shouldSpeculateInteger() + && !m_graph[child1].shouldSpeculateArguments()) { + NodeIndex nodeIndex = getByValLoadElimination(child1.index(), child2.index()); if (nodeIndex == NoNode) break; node.setOp(PutByValAlias); } break; + } case CheckStructure: if (checkStructureLoadElimination(node.structureSet(), node.child1().index())) diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp index 2e7389f21..a1954d7e0 100644 --- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp @@ -315,19 +315,22 @@ private: } case PutByVal: { - if (!m_graph[node.child1()].prediction() || !m_graph[node.child2()].prediction()) + Edge child1 = m_graph.varArgChild(node, 0); + Edge child2 = m_graph.varArgChild(node, 1); + Edge child3 = m_graph.varArgChild(node, 2); + if (!m_graph[child1].prediction() || !m_graph[child2].prediction()) break; - if (!m_graph[node.child2()].shouldSpeculateInteger()) + if (!m_graph[child2].shouldSpeculateInteger()) break; - if (isActionableIntMutableArraySpeculation(m_graph[node.child1()].prediction())) { - if (m_graph[node.child3()].isConstant()) + if (isActionableIntMutableArraySpeculation(m_graph[child1].prediction())) { + if (m_graph[child3].isConstant()) break; - if (m_graph[node.child3()].shouldSpeculateInteger()) + if (m_graph[child3].shouldSpeculateInteger()) break; fixDoubleEdge(2); break; } - if (isActionableFloatMutableArraySpeculation(m_graph[node.child1()].prediction())) { + if (isActionableFloatMutableArraySpeculation(m_graph[child1].prediction())) { fixDoubleEdge(2); break; } @@ -368,7 +371,7 @@ private: void fixDoubleEdge(unsigned childIndex) { Node& source = m_graph[m_compileIndex]; - Edge& edge = source.children.child(childIndex); + Edge& edge = m_graph.child(source, childIndex); if (!m_graph[edge].shouldSpeculateInteger()) { edge.setUseKind(DoubleUse); diff --git a/Source/JavaScriptCore/dfg/DFGGPRInfo.h b/Source/JavaScriptCore/dfg/DFGGPRInfo.h index 23f1697a6..498b116ec 100644 --- a/Source/JavaScriptCore/dfg/DFGGPRInfo.h +++ b/Source/JavaScriptCore/dfg/DFGGPRInfo.h @@ -26,10 +26,12 @@ #ifndef DFGGPRInfo_h #define DFGGPRInfo_h +#include <wtf/Platform.h> + #if ENABLE(DFG_JIT) -#include <assembler/MacroAssembler.h> -#include <dfg/DFGRegisterBank.h> +#include "DFGRegisterBank.h" +#include "MacroAssembler.h" namespace JSC { namespace DFG { diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h index a9080d117..4091c48f7 100644 --- a/Source/JavaScriptCore/dfg/DFGGraph.h +++ b/Source/JavaScriptCore/dfg/DFGGraph.h @@ -463,26 +463,35 @@ public: bool byValIsPure(Node& node) { - if (!at(node.child2()).shouldSpeculateInteger()) - return false; - SpeculatedType prediction = at(node.child1()).prediction(); switch (node.op()) { - case PutByVal: + case PutByVal: { + if (!at(varArgChild(node, 1)).shouldSpeculateInteger()) + return false; + SpeculatedType prediction = at(varArgChild(node, 0)).prediction(); if (!isActionableMutableArraySpeculation(prediction)) return false; if (isArraySpeculation(prediction)) return false; return true; + } - case PutByValAlias: + case PutByValAlias: { + if (!at(varArgChild(node, 1)).shouldSpeculateInteger()) + return false; + SpeculatedType prediction = at(varArgChild(node, 0)).prediction(); if (!isActionableMutableArraySpeculation(prediction)) return false; return true; + } - case GetByVal: + case GetByVal: { + if (!at(node.child2()).shouldSpeculateInteger()) + return false; + SpeculatedType prediction = at(node.child1()).prediction(); if (!isActionableArraySpeculation(prediction)) return false; return true; + } default: ASSERT_NOT_REACHED(); @@ -524,17 +533,29 @@ public: void resetExitStates(); + unsigned varArgNumChildren(Node& node) + { + ASSERT(node.flags() & NodeHasVarArgs); + return node.numChildren(); + } + unsigned numChildren(Node& node) { if (node.flags() & NodeHasVarArgs) - return node.numChildren(); + return varArgNumChildren(node); return AdjacencyList::Size; } - Edge child(Node& node, unsigned index) + Edge& varArgChild(Node& node, unsigned index) + { + ASSERT(node.flags() & NodeHasVarArgs); + return m_varArgChildren[node.firstChild() + index]; + } + + Edge& child(Node& node, unsigned index) { if (node.flags() & NodeHasVarArgs) - return m_varArgChildren[node.firstChild() + index]; + return varArgChild(node, index); return node.children.child(index); } diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp index 2ebee13c1..5a9f972b8 100644 --- a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp +++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp @@ -179,7 +179,7 @@ void JITCompiler::link(LinkBuffer& linkBuffer) info.patch.dfg.valueTagGPR = m_propertyAccesses[i].m_valueTagGPR; info.patch.dfg.valueGPR = m_propertyAccesses[i].m_valueGPR; #endif - info.patch.dfg.scratchGPR = m_propertyAccesses[i].m_scratchGPR; + m_propertyAccesses[i].m_usedRegisters.copyInfo(info.patch.dfg.usedRegisters); info.patch.dfg.registersFlushed = m_propertyAccesses[i].m_registerMode == PropertyAccessRecord::RegistersFlushed; } diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.h b/Source/JavaScriptCore/dfg/DFGJITCompiler.h index d6374b790..7ff399f78 100644 --- a/Source/JavaScriptCore/dfg/DFGJITCompiler.h +++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.h @@ -35,6 +35,7 @@ #include "DFGGPRInfo.h" #include "DFGGraph.h" #include "DFGRegisterBank.h" +#include "DFGRegisterSet.h" #include "JITCode.h" #include "LinkBuffer.h" #include "MacroAssembler.h" @@ -169,7 +170,7 @@ struct PropertyAccessRecord { MacroAssembler::Label done, int8_t baseGPR, int8_t valueGPR, - int8_t scratchGPR, + const RegisterSet& usedRegisters, RegisterMode registerMode = RegistersInUse) #elif USE(JSVALUE32_64) PropertyAccessRecord( @@ -184,7 +185,7 @@ struct PropertyAccessRecord { int8_t baseGPR, int8_t valueTagGPR, int8_t valueGPR, - int8_t scratchGPR, + const RegisterSet& usedRegisters, RegisterMode registerMode = RegistersInUse) #endif : m_codeOrigin(codeOrigin) @@ -204,7 +205,7 @@ struct PropertyAccessRecord { , m_valueTagGPR(valueTagGPR) #endif , m_valueGPR(valueGPR) - , m_scratchGPR(scratchGPR) + , m_usedRegisters(usedRegisters) , m_registerMode(registerMode) { } @@ -226,7 +227,7 @@ struct PropertyAccessRecord { int8_t m_valueTagGPR; #endif int8_t m_valueGPR; - int8_t m_scratchGPR; + RegisterSet m_usedRegisters; RegisterMode m_registerMode; }; diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h index 8c2f96222..7fcd2ec14 100644 --- a/Source/JavaScriptCore/dfg/DFGNodeType.h +++ b/Source/JavaScriptCore/dfg/DFGNodeType.h @@ -109,10 +109,11 @@ namespace JSC { namespace DFG { /* Property access. */\ /* PutByValAlias indicates a 'put' aliases a prior write to the same property. */\ /* Since a put to 'length' may invalidate optimizations here, */\ - /* this must be the directly subsequent property put. */\ + /* this must be the directly subsequent property put. Note that PutByVal */\ + /* opcodes use VarArgs beause they may have up to 4 children. */\ macro(GetByVal, NodeResultJS | NodeMustGenerate | NodeMightClobber) \ - macro(PutByVal, NodeMustGenerate | NodeMightClobber) \ - macro(PutByValAlias, NodeMustGenerate | NodeMightClobber) \ + macro(PutByVal, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \ + macro(PutByValAlias, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \ macro(GetById, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \ macro(GetByIdFlush, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \ macro(PutById, NodeMustGenerate | NodeClobbersWorld) \ diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp index bbe55d351..03c0666b7 100644 --- a/Source/JavaScriptCore/dfg/DFGOperations.cpp +++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp @@ -1232,6 +1232,15 @@ size_t DFG_OPERATION operationIsFunction(EncodedJSValue value) return jsIsFunctionType(JSValue::decode(value)); } +void DFG_OPERATION operationReallocateStorageAndFinishPut(ExecState* exec, JSObject* base, Structure* structure, PropertyOffset offset, EncodedJSValue value) +{ + JSGlobalData& globalData = exec->globalData(); + ASSERT(structure->outOfLineCapacity() > base->structure()->outOfLineCapacity()); + ASSERT(!globalData.heap.storageAllocator().fastPathShouldSucceed(structure->outOfLineCapacity() * sizeof(JSValue))); + base->setStructureAndReallocateStorageIfNecessary(globalData, structure); + base->putDirectOffset(globalData, offset, JSValue::decode(value)); +} + double DFG_OPERATION operationFModOnInts(int32_t a, int32_t b) { return fmod(a, b); diff --git a/Source/JavaScriptCore/dfg/DFGOperations.h b/Source/JavaScriptCore/dfg/DFGOperations.h index 3c85ee761..109dcb2eb 100644 --- a/Source/JavaScriptCore/dfg/DFGOperations.h +++ b/Source/JavaScriptCore/dfg/DFGOperations.h @@ -180,6 +180,7 @@ JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState*, JSCell*) WTF_IN double DFG_OPERATION operationFModOnInts(int32_t, int32_t) WTF_INTERNAL; size_t DFG_OPERATION operationIsObject(EncodedJSValue) WTF_INTERNAL; size_t DFG_OPERATION operationIsFunction(EncodedJSValue) WTF_INTERNAL; +void DFG_OPERATION operationReallocateStorageAndFinishPut(ExecState*, JSObject*, Structure*, PropertyOffset, EncodedJSValue) WTF_INTERNAL; // This method is used to lookup an exception hander, keyed by faultLocation, which is // the return location from one of the calls out to one of the helper operations above. diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp index 320eb6cb6..d23cd8265 100644 --- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp @@ -635,9 +635,9 @@ private: } case PutByVal: - changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue); - changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsNumber | NodeUsedAsInt); - changed |= m_graph[node.child3()].mergeFlags(NodeUsedAsValue); + changed |= m_graph[m_graph.varArgChild(node, 0)].mergeFlags(NodeUsedAsValue); + changed |= m_graph[m_graph.varArgChild(node, 1)].mergeFlags(NodeUsedAsNumber | NodeUsedAsInt); + changed |= m_graph[m_graph.varArgChild(node, 2)].mergeFlags(NodeUsedAsValue); break; case PutScopedVar: diff --git a/Source/JavaScriptCore/dfg/DFGRegisterBank.h b/Source/JavaScriptCore/dfg/DFGRegisterBank.h index 85dc246f2..1d1d6fa52 100644 --- a/Source/JavaScriptCore/dfg/DFGRegisterBank.h +++ b/Source/JavaScriptCore/dfg/DFGRegisterBank.h @@ -226,6 +226,11 @@ public: return nameAtIndex(BankInfo::toIndex(reg)); } + bool isInUse(RegID reg) const + { + return isLocked(reg) || name(reg) != InvalidVirtualRegister; + } + #ifndef NDEBUG void dump() { diff --git a/Source/JavaScriptCore/dfg/DFGRegisterSet.h b/Source/JavaScriptCore/dfg/DFGRegisterSet.h new file mode 100644 index 000000000..bb36359f0 --- /dev/null +++ b/Source/JavaScriptCore/dfg/DFGRegisterSet.h @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DFGRegisterSet_h +#define DFGRegisterSet_h + +#include <wtf/Platform.h> + +#if ENABLE(DFG_JIT) + +#include "DFGFPRInfo.h" +#include "DFGGPRInfo.h" +#include <wtf/Bitmap.h> + +namespace JSC { namespace DFG { + +static const unsigned totalNumberOfRegisters = + GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters; + +static const unsigned numberOfBytesInRegisterSet = + (totalNumberOfRegisters + 7) >> 3; + +typedef uint8_t RegisterSetPOD[numberOfBytesInRegisterSet]; + +class RegisterSet { +public: + RegisterSet() + { + for (unsigned i = numberOfBytesInRegisterSet; i--;) + m_set[i] = 0; + } + + RegisterSet(const RegisterSetPOD& other) + { + for (unsigned i = numberOfBytesInRegisterSet; i--;) + m_set[i] = other[i]; + } + + const RegisterSetPOD& asPOD() const { return m_set; } + + void copyInfo(RegisterSetPOD& other) const + { + for (unsigned i = numberOfBytesInRegisterSet; i--;) + other[i] = m_set[i]; + } + + void set(GPRReg reg) + { + setBit(GPRInfo::toIndex(reg)); + } + + void setGPRByIndex(unsigned index) + { + ASSERT(index < GPRInfo::numberOfRegisters); + setBit(index); + } + + void clear(GPRReg reg) + { + clearBit(GPRInfo::toIndex(reg)); + } + + bool get(GPRReg reg) const + { + return getBit(GPRInfo::toIndex(reg)); + } + + bool getGPRByIndex(unsigned index) const + { + ASSERT(index < GPRInfo::numberOfRegisters); + return getBit(index); + } + + // Return the index'th free GPR. + GPRReg getFreeGPR(unsigned index = 0) const + { + for (unsigned i = GPRInfo::numberOfRegisters; i--;) { + if (!getGPRByIndex(i) && !index--) + return GPRInfo::toRegister(i); + } + return InvalidGPRReg; + } + + void set(FPRReg reg) + { + setBit(GPRInfo::numberOfRegisters + FPRInfo::toIndex(reg)); + } + + void setFPRByIndex(unsigned index) + { + ASSERT(index < FPRInfo::numberOfRegisters); + setBit(GPRInfo::numberOfRegisters + index); + } + + void clear(FPRReg reg) + { + clearBit(GPRInfo::numberOfRegisters + FPRInfo::toIndex(reg)); + } + + bool get(FPRReg reg) const + { + return getBit(GPRInfo::numberOfRegisters + FPRInfo::toIndex(reg)); + } + + bool getFPRByIndex(unsigned index) const + { + ASSERT(index < FPRInfo::numberOfRegisters); + return getBit(GPRInfo::numberOfRegisters + index); + } + + template<typename BankInfo> + void setByIndex(unsigned index) + { + set(BankInfo::toRegister(index)); + } + + template<typename BankInfo> + bool getByIndex(unsigned index) + { + return get(BankInfo::toRegister(index)); + } + + unsigned numberOfSetGPRs() const + { + unsigned result = 0; + for (unsigned i = GPRInfo::numberOfRegisters; i--;) { + if (!getBit(i)) + continue; + result++; + } + return result; + } + + unsigned numberOfSetFPRs() const + { + unsigned result = 0; + for (unsigned i = FPRInfo::numberOfRegisters; i--;) { + if (!getBit(GPRInfo::numberOfRegisters + i)) + continue; + result++; + } + return result; + } + + unsigned numberOfSetRegisters() const + { + unsigned result = 0; + for (unsigned i = totalNumberOfRegisters; i--;) { + if (!getBit(i)) + continue; + result++; + } + return result; + } + +private: + void setBit(unsigned i) + { + ASSERT(i < totalNumberOfRegisters); + m_set[i >> 3] |= (1 << (i & 7)); + } + + void clearBit(unsigned i) + { + ASSERT(i < totalNumberOfRegisters); + m_set[i >> 3] &= ~(1 << (i & 7)); + } + + bool getBit(unsigned i) const + { + ASSERT(i < totalNumberOfRegisters); + return !!(m_set[i >> 3] & (1 << (i & 7))); + } + + RegisterSetPOD m_set; +}; + +} } // namespace JSC::DFG + +#else // ENABLE(DFG_JIT) -> so if DFG is disabled + +namespace JSC { namespace DFG { + +// Define RegisterSetPOD to something that is a POD, but is otherwise useless, +// to make it easier to refer to this type in code that may be compiled when +// the DFG is disabled. + +struct RegisterSetPOD { }; + +} } // namespace JSC::DFG + +#endif // ENABLE(DFG_JIT) + +#endif // DFGRegisterSet_h + diff --git a/Source/JavaScriptCore/dfg/DFGRepatch.cpp b/Source/JavaScriptCore/dfg/DFGRepatch.cpp index e25c6aa27..cfc2cd664 100644 --- a/Source/JavaScriptCore/dfg/DFGRepatch.cpp +++ b/Source/JavaScriptCore/dfg/DFGRepatch.cpp @@ -29,6 +29,7 @@ #if ENABLE(DFG_JIT) #include "DFGCCallHelpers.h" +#include "DFGScratchRegisterAllocator.h" #include "DFGSpeculativeJIT.h" #include "DFGThunks.h" #include "GCAwareJITStubRoutine.h" @@ -161,11 +162,15 @@ static void generateProtoChainAccessStub(ExecState* exec, StructureStubInfo& stu GPRReg resultTagGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueTagGPR); #endif GPRReg resultGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueGPR); - GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.patch.dfg.scratchGPR); + GPRReg scratchGPR = RegisterSet(stubInfo.patch.dfg.usedRegisters).getFreeGPR(); bool needToRestoreScratch = false; if (scratchGPR == InvalidGPRReg) { +#if USE(JSVALUE64) scratchGPR = SpeculativeJIT::selectScratchGPR(baseGPR, resultGPR); +#else + scratchGPR = SpeculativeJIT::selectScratchGPR(baseGPR, resultGPR, resultTagGPR); +#endif stubJit.push(scratchGPR); needToRestoreScratch = true; } @@ -231,13 +236,17 @@ static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier GPRReg resultTagGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueTagGPR); #endif GPRReg resultGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueGPR); - GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.patch.dfg.scratchGPR); + GPRReg scratchGPR = RegisterSet(stubInfo.patch.dfg.usedRegisters).getFreeGPR(); bool needToRestoreScratch = false; MacroAssembler stubJit; if (scratchGPR == InvalidGPRReg) { +#if USE(JSVALUE64) scratchGPR = SpeculativeJIT::selectScratchGPR(baseGPR, resultGPR); +#else + scratchGPR = SpeculativeJIT::selectScratchGPR(baseGPR, resultGPR, resultTagGPR); +#endif stubJit.push(scratchGPR); needToRestoreScratch = true; } @@ -384,7 +393,7 @@ static bool tryBuildGetByIDList(ExecState* exec, JSValue baseValue, const Identi GPRReg resultTagGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueTagGPR); #endif GPRReg resultGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueGPR); - GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.patch.dfg.scratchGPR); + GPRReg scratchGPR = RegisterSet(stubInfo.patch.dfg.usedRegisters).getFreeGPR(); CCallHelpers stubJit(globalData, codeBlock); @@ -404,6 +413,7 @@ static bool tryBuildGetByIDList(ExecState* exec, JSValue baseValue, const Identi if (slot.cachedPropertyType() == PropertySlot::Getter || slot.cachedPropertyType() == PropertySlot::Custom) { if (slot.cachedPropertyType() == PropertySlot::Getter) { + ASSERT(scratchGPR != InvalidGPRReg); ASSERT(baseGPR != scratchGPR); if (isInlineOffset(slot.cachedOffset())) { #if USE(JSVALUE64) @@ -629,7 +639,7 @@ static void emitPutReplaceStub( GPRReg valueTagGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueTagGPR); #endif GPRReg valueGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueGPR); - GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.patch.dfg.scratchGPR); + GPRReg scratchGPR = RegisterSet(stubInfo.patch.dfg.usedRegisters).getFreeGPR(); bool needToRestoreScratch = false; #if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING) GPRReg scratchGPR2; @@ -641,7 +651,11 @@ static void emitPutReplaceStub( MacroAssembler stubJit; if (scratchGPR == InvalidGPRReg && (writeBarrierNeeded || isOutOfLineOffset(slot.cachedOffset()))) { +#if USE(JSVALUE64) scratchGPR = SpeculativeJIT::selectScratchGPR(baseGPR, valueGPR); +#else + scratchGPR = SpeculativeJIT::selectScratchGPR(baseGPR, valueGPR, valueTagGPR); +#endif needToRestoreScratch = true; stubJit.push(scratchGPR); } @@ -652,7 +666,11 @@ static void emitPutReplaceStub( MacroAssembler::TrustedImmPtr(structure)); #if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING) +#if USE(JSVALUE64) scratchGPR2 = SpeculativeJIT::selectScratchGPR(baseGPR, valueGPR, scratchGPR); +#else + scratchGPR2 = SpeculativeJIT::selectScratchGPR(baseGPR, valueGPR, valueTagGPR, scratchGPR); +#endif stubJit.push(scratchGPR2); SpeculativeJIT::writeBarrier(stubJit, baseGPR, scratchGPR, scratchGPR2, WriteBarrierForPropertyAccess); stubJit.pop(scratchGPR2); @@ -722,89 +740,203 @@ static void emitPutTransitionStub( GPRReg valueTagGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueTagGPR); #endif GPRReg valueGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueGPR); - GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.patch.dfg.scratchGPR); - bool needToRestoreScratch = false; - - ASSERT(scratchGPR != baseGPR); + + ScratchRegisterAllocator allocator(stubInfo.patch.dfg.usedRegisters); + allocator.lock(baseGPR); +#if USE(JSVALUE32_64) + allocator.lock(valueTagGPR); +#endif + allocator.lock(valueGPR); + + CCallHelpers stubJit(globalData); - MacroAssembler stubJit; + GPRReg scratchGPR1 = allocator.allocateScratchGPR(); + ASSERT(scratchGPR1 != baseGPR); + ASSERT(scratchGPR1 != valueGPR); + + bool needSecondScratch = false; + bool needThirdScratch = false; +#if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING) + needSecondScratch = true; +#endif + if (structure->outOfLineCapacity() != oldStructure->outOfLineCapacity() + && oldStructure->outOfLineCapacity()) { + needSecondScratch = true; + needThirdScratch = true; + } + + GPRReg scratchGPR2; + if (needSecondScratch) { + scratchGPR2 = allocator.allocateScratchGPR(); + ASSERT(scratchGPR2 != baseGPR); + ASSERT(scratchGPR2 != valueGPR); + ASSERT(scratchGPR2 != scratchGPR1); + } else + scratchGPR2 = InvalidGPRReg; + GPRReg scratchGPR3; + if (needThirdScratch) { + scratchGPR3 = allocator.allocateScratchGPR(); + ASSERT(scratchGPR3 != baseGPR); + ASSERT(scratchGPR3 != valueGPR); + ASSERT(scratchGPR3 != scratchGPR1); + ASSERT(scratchGPR3 != scratchGPR2); + } else + scratchGPR3 = InvalidGPRReg; + allocator.preserveReusedRegistersByPushing(stubJit); + MacroAssembler::JumpList failureCases; - if (scratchGPR == InvalidGPRReg) { - scratchGPR = SpeculativeJIT::selectScratchGPR(baseGPR, valueGPR); - stubJit.push(scratchGPR); - needToRestoreScratch = true; - } - ASSERT(oldStructure->transitionWatchpointSetHasBeenInvalidated()); failureCases.append(stubJit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(oldStructure))); addStructureTransitionCheck( oldStructure->storedPrototype(), exec->codeBlock(), stubInfo, stubJit, failureCases, - scratchGPR); + scratchGPR1); if (putKind == NotDirect) { for (WriteBarrier<Structure>* it = prototypeChain->head(); *it; ++it) { addStructureTransitionCheck( (*it)->storedPrototype(), exec->codeBlock(), stubInfo, stubJit, failureCases, - scratchGPR); + scratchGPR1); } } #if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING) + ASSERT(needSecondScratch); + ASSERT(scratchGPR2 != InvalidGPRReg); // Must always emit this write barrier as the structure transition itself requires it - GPRReg scratch2 = SpeculativeJIT::selectScratchGPR(baseGPR, valueGPR, scratchGPR); - stubJit.push(scratch2); - SpeculativeJIT::writeBarrier(stubJit, baseGPR, scratchGPR, scratch2, WriteBarrierForPropertyAccess); - stubJit.pop(scratch2); + SpeculativeJIT::writeBarrier(stubJit, baseGPR, scratchGPR1, scratchGPR2, WriteBarrierForPropertyAccess); #endif + + MacroAssembler::JumpList slowPath; + + bool scratchGPR1HasStorage = false; + + if (structure->outOfLineCapacity() != oldStructure->outOfLineCapacity()) { + size_t newSize = structure->outOfLineCapacity() * sizeof(JSValue); + CopiedAllocator* copiedAllocator = &globalData->heap.storageAllocator(); + + if (!oldStructure->outOfLineCapacity()) { + stubJit.loadPtr(&copiedAllocator->m_currentRemaining, scratchGPR1); + slowPath.append(stubJit.branchSubPtr(MacroAssembler::Signed, MacroAssembler::TrustedImm32(newSize), scratchGPR1)); + stubJit.storePtr(scratchGPR1, &copiedAllocator->m_currentRemaining); + stubJit.negPtr(scratchGPR1); + stubJit.addPtr(MacroAssembler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), scratchGPR1); + stubJit.subPtr(MacroAssembler::TrustedImm32(newSize), scratchGPR1); + } else { + size_t oldSize = oldStructure->outOfLineCapacity() * sizeof(JSValue); + ASSERT(newSize > oldSize); + + // Optimistically assume that the old storage was the very last thing + // allocated. + stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR3); + stubJit.loadPtr(&copiedAllocator->m_currentPayloadEnd, scratchGPR2); + stubJit.loadPtr(&copiedAllocator->m_currentRemaining, scratchGPR1); + stubJit.subPtr(scratchGPR1, scratchGPR2); + stubJit.subPtr(MacroAssembler::TrustedImm32(oldSize), scratchGPR2); + MacroAssembler::Jump needFullRealloc = + stubJit.branchPtr(MacroAssembler::NotEqual, scratchGPR2, scratchGPR3); + slowPath.append(stubJit.branchSubPtr(MacroAssembler::Signed, MacroAssembler::TrustedImm32(newSize - oldSize), scratchGPR1)); + stubJit.storePtr(scratchGPR1, &copiedAllocator->m_currentRemaining); + stubJit.move(scratchGPR2, scratchGPR1); + MacroAssembler::Jump doneRealloc = stubJit.jump(); + + needFullRealloc.link(&stubJit); + slowPath.append(stubJit.branchSubPtr(MacroAssembler::Signed, MacroAssembler::TrustedImm32(newSize), scratchGPR1)); + stubJit.storePtr(scratchGPR1, &copiedAllocator->m_currentRemaining); + stubJit.negPtr(scratchGPR1); + stubJit.addPtr(MacroAssembler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), scratchGPR1); + stubJit.subPtr(MacroAssembler::TrustedImm32(newSize), scratchGPR1); + // We have scratchGPR1 = new storage, scratchGPR3 = old storage, scratchGPR2 = available + for (size_t offset = 0; offset < oldSize; offset += sizeof(JSValue)) { + stubJit.loadPtr(MacroAssembler::Address(scratchGPR3, offset), scratchGPR2); + stubJit.storePtr(scratchGPR2, MacroAssembler::Address(scratchGPR1, offset)); + } + + doneRealloc.link(&stubJit); + } + + stubJit.storePtr(scratchGPR1, MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage())); + scratchGPR1HasStorage = true; + } stubJit.storePtr(MacroAssembler::TrustedImmPtr(structure), MacroAssembler::Address(baseGPR, JSCell::structureOffset())); #if USE(JSVALUE64) if (isInlineOffset(slot.cachedOffset())) stubJit.storePtr(valueGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue))); else { - stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR); - stubJit.storePtr(valueGPR, MacroAssembler::Address(scratchGPR, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue))); + if (!scratchGPR1HasStorage) + stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR1); + stubJit.storePtr(valueGPR, MacroAssembler::Address(scratchGPR1, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue))); } #elif USE(JSVALUE32_64) if (isInlineOffset(slot.cachedOffset())) { stubJit.store32(valueGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload))); stubJit.store32(valueTagGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag))); } else { - stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR); - stubJit.store32(valueGPR, MacroAssembler::Address(scratchGPR, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload))); - stubJit.store32(valueTagGPR, MacroAssembler::Address(scratchGPR, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag))); + if (!scratchGPR1HasStorage) + stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::offsetOfOutOfLineStorage()), scratchGPR1); + stubJit.store32(valueGPR, MacroAssembler::Address(scratchGPR1, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload))); + stubJit.store32(valueTagGPR, MacroAssembler::Address(scratchGPR1, offsetInOutOfLineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag))); } #endif MacroAssembler::Jump success; MacroAssembler::Jump failure; - if (needToRestoreScratch) { - stubJit.pop(scratchGPR); + if (allocator.didReuseRegisters()) { + allocator.restoreReusedRegistersByPopping(stubJit); success = stubJit.jump(); failureCases.link(&stubJit); - stubJit.pop(scratchGPR); + allocator.restoreReusedRegistersByPopping(stubJit); failure = stubJit.jump(); } else success = stubJit.jump(); - + + MacroAssembler::Call operationCall; + MacroAssembler::Jump successInSlowPath; + + if (structure->outOfLineCapacity() != oldStructure->outOfLineCapacity()) { + slowPath.link(&stubJit); + + allocator.restoreReusedRegistersByPopping(stubJit); + ScratchBuffer* scratchBuffer = globalData->scratchBufferForSize(allocator.desiredScratchBufferSize()); + allocator.preserveUsedRegistersToScratchBuffer(stubJit, scratchBuffer, scratchGPR1); +#if USE(JSVALUE64) + stubJit.setupArgumentsWithExecState(baseGPR, MacroAssembler::TrustedImmPtr(structure), MacroAssembler::TrustedImm32(slot.cachedOffset()), valueGPR); +#else + stubJit.setupArgumentsWithExecState(baseGPR, MacroAssembler::TrustedImmPtr(structure), MacroAssembler::TrustedImm32(slot.cachedOffset()), valueGPR, valueTagGPR); +#endif + operationCall = stubJit.call(); + allocator.restoreUsedRegistersFromScratchBuffer(stubJit, scratchBuffer, scratchGPR1); + successInSlowPath = stubJit.jump(); + } + LinkBuffer patchBuffer(*globalData, &stubJit, exec->codeBlock()); patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToDone)); - if (needToRestoreScratch) + if (allocator.didReuseRegisters()) patchBuffer.link(failure, failureLabel); else patchBuffer.link(failureCases, failureLabel); + if (structure->outOfLineCapacity() != oldStructure->outOfLineCapacity()) { + patchBuffer.link(operationCall, operationReallocateStorageAndFinishPut); + patchBuffer.link(successInSlowPath, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToDone)); + } - stubRoutine = FINALIZE_CODE_FOR_STUB( - patchBuffer, - ("DFG PutById transition stub for CodeBlock %p, return point %p", - exec->codeBlock(), stubInfo.callReturnLocation.labelAtOffset( - stubInfo.patch.dfg.deltaCallToDone).executableAddress())); + stubRoutine = + createJITStubRoutine( + FINALIZE_CODE( + patchBuffer, + ("DFG PutById transition stub for CodeBlock %p, return point %p", + exec->codeBlock(), stubInfo.callReturnLocation.labelAtOffset( + stubInfo.patch.dfg.deltaCallToDone).executableAddress())), + *globalData, + exec->codeBlock()->ownerExecutable(), + structure->outOfLineCapacity() != oldStructure->outOfLineCapacity(), + structure); } static bool tryCachePutByID(ExecState* exec, JSValue baseValue, const Identifier& ident, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind) @@ -829,8 +961,11 @@ static bool tryCachePutByID(ExecState* exec, JSValue baseValue, const Identifier if (structure->isDictionary()) return false; - // skip optimizing the case where we need a realloc - if (oldStructure->outOfLineCapacity() != structure->outOfLineCapacity()) + // Skip optimizing the case where we need a realloc, if we don't have + // enough registers to make it happen. + if (GPRInfo::numberOfRegisters < 6 + && oldStructure->outOfLineCapacity() != structure->outOfLineCapacity() + && oldStructure->outOfLineCapacity()) return false; normalizePrototypeChain(exec, baseCell); @@ -892,8 +1027,11 @@ static bool tryBuildPutByIdList(ExecState* exec, JSValue baseValue, const Identi if (structure->isDictionary()) return false; - // skip optimizing the case where we need a realloc - if (oldStructure->outOfLineCapacity() != structure->outOfLineCapacity()) + // Skip optimizing the case where we need a realloc, if we don't have + // enough registers to make it happen. + if (GPRInfo::numberOfRegisters < 6 + && oldStructure->outOfLineCapacity() != structure->outOfLineCapacity() + && oldStructure->outOfLineCapacity()) return false; normalizePrototypeChain(exec, baseCell); diff --git a/Source/JavaScriptCore/dfg/DFGScratchRegisterAllocator.h b/Source/JavaScriptCore/dfg/DFGScratchRegisterAllocator.h new file mode 100644 index 000000000..9a65e8b7d --- /dev/null +++ b/Source/JavaScriptCore/dfg/DFGScratchRegisterAllocator.h @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DFGScratchRegisterAllocator_h +#define DFGScratchRegisterAllocator_h + +#include <wtf/Platform.h> + +#if ENABLE(DFG_JIT) + +#include "DFGRegisterSet.h" +#include "MacroAssembler.h" + +namespace JSC { namespace DFG { + +// This class provides a low-level register allocator for use in stubs. + +class ScratchRegisterAllocator { +public: + ScratchRegisterAllocator(const RegisterSet& usedRegisters) + : m_usedRegisters(usedRegisters) + , m_didReuseRegisters(false) + { + } + + template<typename T> + void lock(T reg) { m_lockedRegisters.set(reg); } + + template<typename BankInfo> + typename BankInfo::RegisterType allocateScratch() + { + // First try to allocate a register that is totally free. + for (unsigned i = 0; i < BankInfo::numberOfRegisters; ++i) { + typename BankInfo::RegisterType reg = BankInfo::toRegister(i); + if (!m_lockedRegisters.get(reg) + && !m_usedRegisters.get(reg) + && !m_scratchRegisters.get(reg)) { + m_scratchRegisters.set(reg); + return reg; + } + } + + // Since that failed, try to allocate a register that is not yet + // locked or used for scratch. + for (unsigned i = 0; i < BankInfo::numberOfRegisters; ++i) { + typename BankInfo::RegisterType reg = BankInfo::toRegister(i); + if (!m_lockedRegisters.get(reg) && !m_scratchRegisters.get(reg)) { + m_scratchRegisters.set(reg); + m_didReuseRegisters = true; + return reg; + } + } + + // We failed. + CRASH(); + // Make some silly compilers happy. + return static_cast<typename BankInfo::RegisterType>(-1); + } + + GPRReg allocateScratchGPR() { return allocateScratch<GPRInfo>(); } + FPRReg allocateScratchFPR() { return allocateScratch<FPRInfo>(); } + + bool didReuseRegisters() const + { + return m_didReuseRegisters; + } + + void preserveReusedRegistersByPushing(MacroAssembler& jit) + { + if (!m_didReuseRegisters) + return; + + for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) { + if (m_scratchRegisters.getFPRByIndex(i) && m_usedRegisters.getFPRByIndex(i)) { + jit.subPtr(MacroAssembler::TrustedImm32(8), MacroAssembler::stackPointerRegister); + jit.storeDouble(FPRInfo::toRegister(i), MacroAssembler::stackPointerRegister); + } + } + for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) { + if (m_scratchRegisters.getGPRByIndex(i) && m_usedRegisters.getGPRByIndex(i)) + jit.push(GPRInfo::toRegister(i)); + } + } + + void restoreReusedRegistersByPopping(MacroAssembler& jit) + { + if (!m_didReuseRegisters) + return; + + for (unsigned i = GPRInfo::numberOfRegisters; i--;) { + if (m_scratchRegisters.getGPRByIndex(i) && m_usedRegisters.getGPRByIndex(i)) + jit.pop(GPRInfo::toRegister(i)); + } + for (unsigned i = FPRInfo::numberOfRegisters; i--;) { + if (m_scratchRegisters.getFPRByIndex(i) && m_usedRegisters.getFPRByIndex(i)) { + jit.loadDouble(MacroAssembler::stackPointerRegister, FPRInfo::toRegister(i)); + jit.addPtr(MacroAssembler::TrustedImm32(8), MacroAssembler::stackPointerRegister); + } + } + } + + unsigned desiredScratchBufferSize() const { return m_usedRegisters.numberOfSetRegisters() * sizeof(JSValue); } + + void preserveUsedRegistersToScratchBuffer(MacroAssembler& jit, ScratchBuffer* scratchBuffer, GPRReg scratchGPR = InvalidGPRReg) + { + unsigned count = 0; + for (unsigned i = GPRInfo::numberOfRegisters; i--;) { + if (m_usedRegisters.getGPRByIndex(i)) + jit.storePtr(GPRInfo::toRegister(i), scratchBuffer->m_buffer + (count++)); + if (scratchGPR == InvalidGPRReg && !m_lockedRegisters.getGPRByIndex(i) && !m_scratchRegisters.getGPRByIndex(i)) + scratchGPR = GPRInfo::toRegister(i); + } + ASSERT(scratchGPR != InvalidGPRReg); + for (unsigned i = FPRInfo::numberOfRegisters; i--;) { + if (m_usedRegisters.getFPRByIndex(i)) { + jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->m_buffer + (count++)), scratchGPR); + jit.storeDouble(FPRInfo::toRegister(i), scratchGPR); + } + } + ASSERT(count * sizeof(JSValue) == desiredScratchBufferSize()); + + jit.move(MacroAssembler::TrustedImmPtr(&scratchBuffer->m_activeLength), scratchGPR); + jit.storePtr(MacroAssembler::TrustedImmPtr(static_cast<size_t>(count * sizeof(JSValue))), scratchGPR); + } + + void restoreUsedRegistersFromScratchBuffer(MacroAssembler& jit, ScratchBuffer* scratchBuffer, GPRReg scratchGPR = InvalidGPRReg) + { + if (scratchGPR == InvalidGPRReg) { + // Find a scratch register. + for (unsigned i = GPRInfo::numberOfRegisters; i--;) { + if (m_lockedRegisters.getGPRByIndex(i) || m_scratchRegisters.getGPRByIndex(i)) + continue; + scratchGPR = GPRInfo::toRegister(i); + break; + } + } + ASSERT(scratchGPR != InvalidGPRReg); + + jit.move(MacroAssembler::TrustedImmPtr(&scratchBuffer->m_activeLength), scratchGPR); + jit.storePtr(MacroAssembler::TrustedImmPtr(0), scratchGPR); + + // Restore double registers first. + unsigned count = m_usedRegisters.numberOfSetGPRs(); + for (unsigned i = FPRInfo::numberOfRegisters; i--;) { + if (m_usedRegisters.getFPRByIndex(i)) { + jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->m_buffer + (count++)), scratchGPR); + jit.loadDouble(scratchGPR, FPRInfo::toRegister(i)); + } + } + + count = 0; + for (unsigned i = GPRInfo::numberOfRegisters; i--;) { + if (m_usedRegisters.getGPRByIndex(i)) + jit.loadPtr(scratchBuffer->m_buffer + (count++), GPRInfo::toRegister(i)); + } + } + +private: + RegisterSet m_usedRegisters; + RegisterSet m_lockedRegisters; + RegisterSet m_scratchRegisters; + bool m_didReuseRegisters; +}; + +} } // namespace JSC::DFG + +#endif // ENABLE(DFG_JIT) + +#endif // DFGScratchRegisterAllocator_h + diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp index c6ec62129..e8824b832 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp @@ -1911,8 +1911,8 @@ void SpeculativeJIT::compileGetByValOnIntTypedArray(const TypedArrayDescriptor& void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements, TypedArraySignedness signedness, TypedArrayRounding rounding) { - Edge baseUse = node.child1(); - Edge valueUse = node.child3(); + Edge baseUse = m_jit.graph().varArgChild(node, 0); + Edge valueUse = m_jit.graph().varArgChild(node, 2); if (speculationRequirements != NoTypedArrayTypeSpecCheck) speculationCheck(BadType, JSValueSource::unboxedCell(base), baseUse, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo))); @@ -2052,8 +2052,8 @@ void SpeculativeJIT::compileGetByValOnFloatTypedArray(const TypedArrayDescriptor void SpeculativeJIT::compilePutByValForFloatTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements) { - Edge baseUse = node.child1(); - Edge valueUse = node.child3(); + Edge baseUse = m_jit.graph().varArgChild(node, 0); + Edge valueUse = m_jit.graph().varArgChild(node, 2); SpeculateDoubleOperand valueOp(this, valueUse); diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h index 28d8033cb..487addd7f 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h @@ -272,6 +272,22 @@ public: { use(nodeUse.index()); } + + RegisterSet usedRegisters() + { + RegisterSet result; + for (unsigned i = GPRInfo::numberOfRegisters; i--;) { + GPRReg gpr = GPRInfo::toRegister(i); + if (m_gprs.isInUse(gpr)) + result.set(gpr); + } + for (unsigned i = FPRInfo::numberOfRegisters; i--;) { + FPRReg fpr = FPRInfo::toRegister(i); + if (m_fprs.isInUse(fpr)) + result.set(fpr); + } + return result; + } static void markCellCard(MacroAssembler&, GPRReg ownerGPR, GPRReg scratchGPR1, GPRReg scratchGPR2); static void writeBarrier(MacroAssembler&, GPRReg ownerGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, WriteBarrierUseKind); @@ -942,10 +958,10 @@ public: void nonSpeculativeUInt32ToNumber(Node&); #if USE(JSVALUE64) - void cachedGetById(CodeOrigin, GPRReg baseGPR, GPRReg resultGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill); + void cachedGetById(CodeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill); void cachedPutById(CodeOrigin, GPRReg base, GPRReg value, Edge valueUse, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump()); #elif USE(JSVALUE32_64) - void cachedGetById(CodeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill); + void cachedGetById(CodeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill); void cachedPutById(CodeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, Edge valueUse, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump()); #endif diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp index ec2377389..ed98e0800 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp @@ -503,7 +503,7 @@ void SpeculativeJIT::nonSpeculativeUInt32ToNumber(Node& node) jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex); } -void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode) +void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode) { JITCompiler::DataLabelPtr structureToCompare; JITCompiler::PatchableJump structureCheck = m_jit.patchableBranchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(basePayloadGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1))); @@ -553,7 +553,7 @@ void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseTagGPROrNon codeOrigin, structureToCompare, structureCheck, propertyStorageLoad, tagLoadWithPatch, payloadLoadWithPatch, slowPath.get(), doneLabel, safeCast<int8_t>(basePayloadGPR), safeCast<int8_t>(resultTagGPR), - safeCast<int8_t>(resultPayloadGPR), safeCast<int8_t>(scratchGPR), + safeCast<int8_t>(resultPayloadGPR), usedRegisters(), spillMode == NeedToSpill ? PropertyAccessRecord::RegistersInUse : PropertyAccessRecord::RegistersFlushed)); addSlowPathGenerator(slowPath.release()); } @@ -595,6 +595,11 @@ void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg basePayloadGPR, slowCases, this, optimizedCall, NoResult, valueTagGPR, valuePayloadGPR, basePayloadGPR, identifier(identifierNumber)); } + RegisterSet currentlyUsedRegisters = usedRegisters(); + currentlyUsedRegisters.clear(scratchGPR); + ASSERT(currentlyUsedRegisters.get(basePayloadGPR)); + ASSERT(currentlyUsedRegisters.get(valueTagGPR)); + ASSERT(currentlyUsedRegisters.get(valuePayloadGPR)); m_jit.addPropertyAccess( PropertyAccessRecord( codeOrigin, structureToCompare, structureCheck, propertyStorageLoad, @@ -602,7 +607,7 @@ void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg basePayloadGPR, JITCompiler::DataLabelCompact(payloadStoreWithPatch.label()), slowPath.get(), doneLabel, safeCast<int8_t>(basePayloadGPR), safeCast<int8_t>(valueTagGPR), safeCast<int8_t>(valuePayloadGPR), - safeCast<int8_t>(scratchGPR))); + usedRegisters())); addSlowPathGenerator(slowPath.release()); } @@ -2471,17 +2476,21 @@ void SpeculativeJIT::compile(Node& node) } case PutByVal: { - if (!at(node.child1()).prediction() || !at(node.child2()).prediction()) { + Edge child1 = m_jit.graph().varArgChild(node, 0); + Edge child2 = m_jit.graph().varArgChild(node, 1); + Edge child3 = m_jit.graph().varArgChild(node, 2); + + if (!at(child1).prediction() || !at(child2).prediction()) { terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode); break; } - if (!at(node.child2()).shouldSpeculateInteger() - || !isActionableMutableArraySpeculation(at(node.child1()).prediction()) - || at(node.child1()).shouldSpeculateArguments()) { - SpeculateCellOperand base(this, node.child1()); // Save a register, speculate cell. We'll probably be right. - JSValueOperand property(this, node.child2()); - JSValueOperand value(this, node.child3()); + if (!at(child2).shouldSpeculateInteger() + || !isActionableMutableArraySpeculation(at(child1).prediction()) + || at(child1).shouldSpeculateArguments()) { + SpeculateCellOperand base(this, child1); // Save a register, speculate cell. We'll probably be right. + JSValueOperand property(this, child2); + JSValueOperand value(this, child3); GPRReg baseGPR = base.gpr(); GPRReg propertyTagGPR = property.tagGPR(); GPRReg propertyPayloadGPR = property.payloadGPR(); @@ -2495,74 +2504,74 @@ void SpeculativeJIT::compile(Node& node) break; } - SpeculateCellOperand base(this, node.child1()); - SpeculateStrictInt32Operand property(this, node.child2()); - if (at(node.child1()).shouldSpeculateInt8Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), isInt8ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); + SpeculateCellOperand base(this, child1); + SpeculateStrictInt32Operand property(this, child2); + if (at(child1).shouldSpeculateInt8Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), isInt8ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateInt16Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), isInt16ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); + if (at(child1).shouldSpeculateInt16Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), isInt16ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateInt32Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), isInt32ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); + if (at(child1).shouldSpeculateInt32Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), isInt32ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint8Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), isUint8ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); + if (at(child1).shouldSpeculateUint8Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), isUint8ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint8ClampedArray()) { - compilePutByValForIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), isUint8ClampedArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray, ClampRounding); + if (at(child1).shouldSpeculateUint8ClampedArray()) { + compilePutByValForIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), isUint8ClampedArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray, ClampRounding); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint16Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), isUint16ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); + if (at(child1).shouldSpeculateUint16Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), isUint16ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint32Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), isUint32ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); + if (at(child1).shouldSpeculateUint32Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), isUint32ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateFloat32Array()) { - compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float), isFloat32ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks); + if (at(child1).shouldSpeculateFloat32Array()) { + compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float), isFloat32ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateFloat64Array()) { - compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double), isFloat64ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks); + if (at(child1).shouldSpeculateFloat64Array()) { + compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double), isFloat64ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks); if (!m_compileOkay) return; break; } - ASSERT(at(node.child1()).shouldSpeculateArray()); + ASSERT(at(child1).shouldSpeculateArray()); - JSValueOperand value(this, node.child3()); + JSValueOperand value(this, child3); GPRTemporary scratch(this); // Map base, property & value into registers, allocate a scratch register. @@ -2575,12 +2584,12 @@ void SpeculativeJIT::compile(Node& node) if (!m_compileOkay) return; - writeBarrier(baseReg, valueTagReg, node.child3(), WriteBarrierForPropertyAccess, scratchReg); + writeBarrier(baseReg, valueTagReg, child3, WriteBarrierForPropertyAccess, scratchReg); // Check that base is an array, and that property is contained within m_vector (< m_vectorLength). // If we have predicted the base to be type array, we can skip the check. - if (!isArraySpeculation(m_state.forNode(node.child1()).m_type)) - speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info))); + if (!isArraySpeculation(m_state.forNode(child1).m_type)) + speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), child1, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info))); base.use(); property.use(); @@ -2620,89 +2629,93 @@ void SpeculativeJIT::compile(Node& node) } case PutByValAlias: { - if (!at(node.child1()).prediction() || !at(node.child2()).prediction()) { + Edge child1 = m_jit.graph().varArgChild(node, 0); + Edge child2 = m_jit.graph().varArgChild(node, 1); + Edge child3 = m_jit.graph().varArgChild(node, 2); + + if (!at(child1).prediction() || !at(child2).prediction()) { terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode); break; } - ASSERT(isActionableMutableArraySpeculation(at(node.child1()).prediction())); - ASSERT(at(node.child2()).shouldSpeculateInteger()); + ASSERT(isActionableMutableArraySpeculation(at(child1).prediction())); + ASSERT(at(child2).shouldSpeculateInteger()); - SpeculateCellOperand base(this, node.child1()); - SpeculateStrictInt32Operand property(this, node.child2()); + SpeculateCellOperand base(this, child1); + SpeculateStrictInt32Operand property(this, child2); - if (at(node.child1()).shouldSpeculateInt8Array()) { + if (at(child1).shouldSpeculateInt8Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), NoTypedArraySpecCheck, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateInt16Array()) { + if (at(child1).shouldSpeculateInt16Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), NoTypedArraySpecCheck, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateInt32Array()) { + if (at(child1).shouldSpeculateInt32Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), NoTypedArraySpecCheck, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint8Array()) { + if (at(child1).shouldSpeculateUint8Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), NoTypedArraySpecCheck, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint8ClampedArray()) { + if (at(child1).shouldSpeculateUint8ClampedArray()) { compilePutByValForIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), NoTypedArraySpecCheck, UnsignedTypedArray, ClampRounding); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint16Array()) { + if (at(child1).shouldSpeculateUint16Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), NoTypedArraySpecCheck, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint32Array()) { + if (at(child1).shouldSpeculateUint32Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), NoTypedArraySpecCheck, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateFloat32Array()) { + if (at(child1).shouldSpeculateFloat32Array()) { compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float), NoTypedArraySpecCheck); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateFloat64Array()) { + if (at(child1).shouldSpeculateFloat64Array()) { compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double), NoTypedArraySpecCheck); if (!m_compileOkay) return; break; } - ASSERT(at(node.child1()).shouldSpeculateArray()); + ASSERT(at(child1).shouldSpeculateArray()); - JSValueOperand value(this, node.child3()); + JSValueOperand value(this, child3); GPRTemporary scratch(this, base); GPRReg baseReg = base.gpr(); GPRReg scratchReg = scratch.gpr(); - writeBarrier(baseReg, value.tagGPR(), node.child3(), WriteBarrierForPropertyAccess, scratchReg); + writeBarrier(baseReg, value.tagGPR(), child3, WriteBarrierForPropertyAccess, scratchReg); // Get the array storage. GPRReg storageReg = scratchReg; @@ -3290,16 +3303,10 @@ void SpeculativeJIT::compile(Node& node) GPRReg baseGPR = base.gpr(); GPRReg resultTagGPR = resultTag.gpr(); GPRReg resultPayloadGPR = resultPayload.gpr(); - GPRReg scratchGPR; - - if (resultTagGPR == baseGPR) - scratchGPR = resultPayloadGPR; - else - scratchGPR = resultTagGPR; - + base.use(); - cachedGetById(node.codeOrigin, InvalidGPRReg, baseGPR, resultTagGPR, resultPayloadGPR, scratchGPR, node.identifierNumber()); + cachedGetById(node.codeOrigin, InvalidGPRReg, baseGPR, resultTagGPR, resultPayloadGPR, node.identifierNumber()); jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly); break; @@ -3313,18 +3320,12 @@ void SpeculativeJIT::compile(Node& node) GPRReg basePayloadGPR = base.payloadGPR(); GPRReg resultTagGPR = resultTag.gpr(); GPRReg resultPayloadGPR = resultPayload.gpr(); - GPRReg scratchGPR; - - if (resultTagGPR == basePayloadGPR) - scratchGPR = resultPayloadGPR; - else - scratchGPR = resultTagGPR; base.use(); JITCompiler::Jump notCell = m_jit.branch32(JITCompiler::NotEqual, baseTagGPR, TrustedImm32(JSValue::CellTag)); - cachedGetById(node.codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, scratchGPR, node.identifierNumber(), notCell); + cachedGetById(node.codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node.identifierNumber(), notCell); jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly); break; @@ -3346,13 +3347,11 @@ void SpeculativeJIT::compile(Node& node) GPRReg resultTagGPR = resultTag.gpr(); GPRReg resultPayloadGPR = resultPayload.gpr(); - GPRReg scratchGPR = selectScratchGPR(baseGPR, resultTagGPR, resultPayloadGPR); - base.use(); flushRegisters(); - cachedGetById(node.codeOrigin, InvalidGPRReg, baseGPR, resultTagGPR, resultPayloadGPR, scratchGPR, node.identifierNumber(), JITCompiler::Jump(), DontSpill); + cachedGetById(node.codeOrigin, InvalidGPRReg, baseGPR, resultTagGPR, resultPayloadGPR, node.identifierNumber(), JITCompiler::Jump(), DontSpill); jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly); break; @@ -3367,15 +3366,13 @@ void SpeculativeJIT::compile(Node& node) GPRReg resultTagGPR = resultTag.gpr(); GPRReg resultPayloadGPR = resultPayload.gpr(); - GPRReg scratchGPR = selectScratchGPR(baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR); - base.use(); flushRegisters(); JITCompiler::Jump notCell = m_jit.branch32(JITCompiler::NotEqual, baseTagGPR, TrustedImm32(JSValue::CellTag)); - cachedGetById(node.codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, scratchGPR, node.identifierNumber(), notCell, DontSpill); + cachedGetById(node.codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node.identifierNumber(), notCell, DontSpill); jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly); break; diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp index b5058e35a..9e468e758 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp @@ -492,7 +492,7 @@ void SpeculativeJIT::nonSpeculativeUInt32ToNumber(Node& node) jsValueResult(result.gpr(), m_compileIndex); } -void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg resultGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode) +void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode) { JITCompiler::DataLabelPtr structureToCompare; JITCompiler::PatchableJump structureCheck = m_jit.patchableBranchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1))); @@ -520,13 +520,9 @@ void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg PropertyAccessRecord( codeOrigin, structureToCompare, structureCheck, propertyStorageLoad, loadWithPatch, slowPath.get(), doneLabel, safeCast<int8_t>(baseGPR), safeCast<int8_t>(resultGPR), - safeCast<int8_t>(scratchGPR), + usedRegisters(), spillMode == NeedToSpill ? PropertyAccessRecord::RegistersInUse : PropertyAccessRecord::RegistersFlushed)); addSlowPathGenerator(slowPath.release()); - - - if (scratchGPR != resultGPR && scratchGPR != InvalidGPRReg && spillMode == NeedToSpill) - unlock(scratchGPR); } void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg valueGPR, Edge valueUse, GPRReg scratchGPR, unsigned identifierNumber, PutKind putKind, JITCompiler::Jump slowPathTarget) @@ -568,11 +564,15 @@ void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg slowCases, this, optimizedCall, NoResult, valueGPR, baseGPR, identifier(identifierNumber)); } + RegisterSet currentlyUsedRegisters = usedRegisters(); + currentlyUsedRegisters.clear(scratchGPR); + ASSERT(currentlyUsedRegisters.get(baseGPR)); + ASSERT(currentlyUsedRegisters.get(valueGPR)); m_jit.addPropertyAccess( PropertyAccessRecord( codeOrigin, structureToCompare, structureCheck, propertyStorageLoad, JITCompiler::DataLabelCompact(storeWithPatch.label()), slowPath.get(), doneLabel, - safeCast<int8_t>(baseGPR), safeCast<int8_t>(valueGPR), safeCast<int8_t>(scratchGPR))); + safeCast<int8_t>(baseGPR), safeCast<int8_t>(valueGPR), currentlyUsedRegisters)); addSlowPathGenerator(slowPath.release()); } @@ -2501,15 +2501,19 @@ void SpeculativeJIT::compile(Node& node) } case PutByVal: { - if (!at(node.child1()).prediction() || !at(node.child2()).prediction()) { + Edge child1 = m_jit.graph().varArgChild(node, 0); + Edge child2 = m_jit.graph().varArgChild(node, 1); + Edge child3 = m_jit.graph().varArgChild(node, 2); + + if (!at(child1).prediction() || !at(child2).prediction()) { terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode); break; } - if (!at(node.child2()).shouldSpeculateInteger() || !isActionableMutableArraySpeculation(at(node.child1()).prediction())) { - JSValueOperand arg1(this, node.child1()); - JSValueOperand arg2(this, node.child2()); - JSValueOperand arg3(this, node.child3()); + if (!at(child2).shouldSpeculateInteger() || !isActionableMutableArraySpeculation(at(child1).prediction())) { + JSValueOperand arg1(this, child1); + JSValueOperand arg2(this, child2); + JSValueOperand arg3(this, child3); GPRReg arg1GPR = arg1.gpr(); GPRReg arg2GPR = arg2.gpr(); GPRReg arg3GPR = arg3.gpr(); @@ -2521,12 +2525,12 @@ void SpeculativeJIT::compile(Node& node) break; } - SpeculateCellOperand base(this, node.child1()); - SpeculateStrictInt32Operand property(this, node.child2()); - if (at(node.child1()).shouldSpeculateArguments()) { - JSValueOperand value(this, node.child3()); - SpeculateCellOperand base(this, node.child1()); - SpeculateStrictInt32Operand property(this, node.child2()); + SpeculateCellOperand base(this, child1); + SpeculateStrictInt32Operand property(this, child2); + if (at(child1).shouldSpeculateArguments()) { + JSValueOperand value(this, child3); + SpeculateCellOperand base(this, child1); + SpeculateStrictInt32Operand property(this, child2); GPRTemporary scratch(this); GPRTemporary scratch2(this); @@ -2539,9 +2543,9 @@ void SpeculativeJIT::compile(Node& node) if (!m_compileOkay) return; - if (!isArgumentsSpeculation(m_state.forNode(node.child1()).m_type)) { + if (!isArgumentsSpeculation(m_state.forNode(child1).m_type)) { speculationCheck( - BadType, JSValueSource::unboxedCell(baseReg), node.child1(), + BadType, JSValueSource::unboxedCell(baseReg), child1, m_jit.branchPtr( MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), @@ -2582,70 +2586,70 @@ void SpeculativeJIT::compile(Node& node) break; } - if (at(node.child1()).shouldSpeculateInt8Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), isInt8ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); + if (at(child1).shouldSpeculateInt8Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), isInt8ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateInt16Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), isInt16ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); + if (at(child1).shouldSpeculateInt16Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), isInt16ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateInt32Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), isInt32ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); + if (at(child1).shouldSpeculateInt32Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), isInt32ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint8Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), isUint8ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); + if (at(child1).shouldSpeculateUint8Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), isUint8ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint8ClampedArray()) { - compilePutByValForIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), isUint8ClampedArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray, ClampRounding); + if (at(child1).shouldSpeculateUint8ClampedArray()) { + compilePutByValForIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), isUint8ClampedArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray, ClampRounding); break; } - if (at(node.child1()).shouldSpeculateUint16Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), isUint16ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); + if (at(child1).shouldSpeculateUint16Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), isUint16ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint32Array()) { - compilePutByValForIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), isUint32ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); + if (at(child1).shouldSpeculateUint32Array()) { + compilePutByValForIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), isUint32ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateFloat32Array()) { - compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float), isFloat32ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks); + if (at(child1).shouldSpeculateFloat32Array()) { + compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float), isFloat32ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateFloat64Array()) { - compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double), isFloat64ArraySpeculation(m_state.forNode(node.child1()).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks); + if (at(child1).shouldSpeculateFloat64Array()) { + compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double), isFloat64ArraySpeculation(m_state.forNode(child1).m_type) ? NoTypedArrayTypeSpecCheck : AllTypedArraySpecChecks); if (!m_compileOkay) return; break; } - ASSERT(at(node.child1()).shouldSpeculateArray()); + ASSERT(at(child1).shouldSpeculateArray()); - JSValueOperand value(this, node.child3()); + JSValueOperand value(this, child3); GPRTemporary scratch(this); // Map base, property & value into registers, allocate a scratch register. @@ -2657,12 +2661,12 @@ void SpeculativeJIT::compile(Node& node) if (!m_compileOkay) return; - writeBarrier(baseReg, value.gpr(), node.child3(), WriteBarrierForPropertyAccess, scratchReg); + writeBarrier(baseReg, value.gpr(), child3, WriteBarrierForPropertyAccess, scratchReg); // Check that base is an array, and that property is contained within m_vector (< m_vectorLength). // If we have predicted the base to be type array, we can skip the check. - if (!isArraySpeculation(m_state.forNode(node.child1()).m_type)) - speculationCheck(BadType, JSValueRegs(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info))); + if (!isArraySpeculation(m_state.forNode(child1).m_type)) + speculationCheck(BadType, JSValueRegs(baseReg), child1, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info))); base.use(); property.use(); @@ -2701,88 +2705,92 @@ void SpeculativeJIT::compile(Node& node) } case PutByValAlias: { - if (!at(node.child1()).prediction() || !at(node.child2()).prediction()) { + Edge child1 = m_jit.graph().varArgChild(node, 0); + Edge child2 = m_jit.graph().varArgChild(node, 1); + Edge child3 = m_jit.graph().varArgChild(node, 2); + + if (!at(child1).prediction() || !at(child2).prediction()) { terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode); break; } - ASSERT(isActionableMutableArraySpeculation(at(node.child1()).prediction())); - ASSERT(at(node.child2()).shouldSpeculateInteger()); + ASSERT(isActionableMutableArraySpeculation(at(child1).prediction())); + ASSERT(at(child2).shouldSpeculateInteger()); - SpeculateCellOperand base(this, node.child1()); - SpeculateStrictInt32Operand property(this, node.child2()); - if (at(node.child1()).shouldSpeculateInt8Array()) { + SpeculateCellOperand base(this, child1); + SpeculateStrictInt32Operand property(this, child2); + if (at(child1).shouldSpeculateInt8Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), NoTypedArraySpecCheck, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateInt16Array()) { + if (at(child1).shouldSpeculateInt16Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), NoTypedArraySpecCheck, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateInt32Array()) { + if (at(child1).shouldSpeculateInt32Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), NoTypedArraySpecCheck, SignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint8Array()) { + if (at(child1).shouldSpeculateUint8Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), NoTypedArraySpecCheck, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint8ClampedArray()) { + if (at(child1).shouldSpeculateUint8ClampedArray()) { compilePutByValForIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), NoTypedArraySpecCheck, UnsignedTypedArray, ClampRounding); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint16Array()) { + if (at(child1).shouldSpeculateUint16Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), NoTypedArraySpecCheck, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateUint32Array()) { + if (at(child1).shouldSpeculateUint32Array()) { compilePutByValForIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), NoTypedArraySpecCheck, UnsignedTypedArray); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateFloat32Array()) { + if (at(child1).shouldSpeculateFloat32Array()) { compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float), NoTypedArraySpecCheck); if (!m_compileOkay) return; break; } - if (at(node.child1()).shouldSpeculateFloat64Array()) { + if (at(child1).shouldSpeculateFloat64Array()) { compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double), NoTypedArraySpecCheck); if (!m_compileOkay) return; break; } - ASSERT(at(node.child1()).shouldSpeculateArray()); + ASSERT(at(child1).shouldSpeculateArray()); - JSValueOperand value(this, node.child3()); + JSValueOperand value(this, child3); GPRTemporary scratch(this); GPRReg baseReg = base.gpr(); GPRReg scratchReg = scratch.gpr(); - writeBarrier(base.gpr(), value.gpr(), node.child3(), WriteBarrierForPropertyAccess, scratchReg); + writeBarrier(base.gpr(), value.gpr(), child3, WriteBarrierForPropertyAccess, scratchReg); // Get the array storage. GPRReg storageReg = scratchReg; @@ -3319,16 +3327,10 @@ void SpeculativeJIT::compile(Node& node) GPRReg baseGPR = base.gpr(); GPRReg resultGPR = result.gpr(); - GPRReg scratchGPR; - - if (resultGPR == baseGPR) - scratchGPR = tryAllocate(); - else - scratchGPR = resultGPR; base.use(); - cachedGetById(node.codeOrigin, baseGPR, resultGPR, scratchGPR, node.identifierNumber()); + cachedGetById(node.codeOrigin, baseGPR, resultGPR, node.identifierNumber()); jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly); break; @@ -3339,18 +3341,12 @@ void SpeculativeJIT::compile(Node& node) GPRReg baseGPR = base.gpr(); GPRReg resultGPR = result.gpr(); - GPRReg scratchGPR; - - if (resultGPR == baseGPR) - scratchGPR = tryAllocate(); - else - scratchGPR = resultGPR; base.use(); JITCompiler::Jump notCell = m_jit.branchTestPtr(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister); - cachedGetById(node.codeOrigin, baseGPR, resultGPR, scratchGPR, node.identifierNumber(), notCell); + cachedGetById(node.codeOrigin, baseGPR, resultGPR, node.identifierNumber(), notCell); jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly); @@ -3371,13 +3367,11 @@ void SpeculativeJIT::compile(Node& node) GPRReg resultGPR = result.gpr(); - GPRReg scratchGPR = selectScratchGPR(baseGPR, resultGPR); - base.use(); flushRegisters(); - cachedGetById(node.codeOrigin, baseGPR, resultGPR, scratchGPR, node.identifierNumber(), JITCompiler::Jump(), DontSpill); + cachedGetById(node.codeOrigin, baseGPR, resultGPR, node.identifierNumber(), JITCompiler::Jump(), DontSpill); jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly); break; @@ -3389,14 +3383,12 @@ void SpeculativeJIT::compile(Node& node) GPRResult result(this); GPRReg resultGPR = result.gpr(); - GPRReg scratchGPR = selectScratchGPR(baseGPR, resultGPR); - base.use(); flushRegisters(); JITCompiler::Jump notCell = m_jit.branchTestPtr(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister); - cachedGetById(node.codeOrigin, baseGPR, resultGPR, scratchGPR, node.identifierNumber(), notCell, DontSpill); + cachedGetById(node.codeOrigin, baseGPR, resultGPR, node.identifierNumber(), notCell, DontSpill); jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly); diff --git a/Source/JavaScriptCore/heap/CopiedAllocator.h b/Source/JavaScriptCore/heap/CopiedAllocator.h index 7455ec816..32b84f008 100644 --- a/Source/JavaScriptCore/heap/CopiedAllocator.h +++ b/Source/JavaScriptCore/heap/CopiedAllocator.h @@ -27,72 +27,128 @@ #define CopiedAllocator_h #include "CopiedBlock.h" +#include <wtf/CheckedBoolean.h> +#include <wtf/DataLog.h> namespace JSC { class CopiedAllocator { - friend class JIT; public: CopiedAllocator(); - void* allocate(size_t); - bool fitsInCurrentBlock(size_t); - bool wasLastAllocation(void*, size_t); - void startedCopying(); - void resetCurrentBlock(CopiedBlock*); + + bool fastPathShouldSucceed(size_t bytes) const; + CheckedBoolean tryAllocate(size_t bytes, void** outPtr); + CheckedBoolean tryReallocate(void *oldPtr, size_t oldBytes, size_t newBytes); + void* forceAllocate(size_t bytes); + CopiedBlock* resetCurrentBlock(); + void setCurrentBlock(CopiedBlock*); size_t currentCapacity(); + + bool isValid() { return !!m_currentBlock; } -private: CopiedBlock* currentBlock() { return m_currentBlock; } - char* m_currentOffset; + // Yes, these are public. No, that doesn't mean you can play with them. + // If I had made them private then I'd have to list off all of the JIT + // classes and functions that are entitled to modify these directly, and + // that would have been gross. + size_t m_currentRemaining; + char* m_currentPayloadEnd; CopiedBlock* m_currentBlock; }; inline CopiedAllocator::CopiedAllocator() - : m_currentOffset(0) + : m_currentRemaining(0) + , m_currentPayloadEnd(0) , m_currentBlock(0) { } -inline void* CopiedAllocator::allocate(size_t bytes) +inline bool CopiedAllocator::fastPathShouldSucceed(size_t bytes) const { - ASSERT(m_currentOffset); ASSERT(is8ByteAligned(reinterpret_cast<void*>(bytes))); - ASSERT(fitsInCurrentBlock(bytes)); - void* ptr = static_cast<void*>(m_currentOffset); - m_currentOffset += bytes; - ASSERT(is8ByteAligned(ptr)); - return ptr; + + return bytes <= m_currentRemaining; } -inline bool CopiedAllocator::fitsInCurrentBlock(size_t bytes) +inline CheckedBoolean CopiedAllocator::tryAllocate(size_t bytes, void** outPtr) { - return m_currentOffset + bytes < reinterpret_cast<char*>(m_currentBlock) + HeapBlock::s_blockSize && m_currentOffset + bytes > m_currentOffset; + ASSERT(is8ByteAligned(reinterpret_cast<void*>(bytes))); + + // This code is written in a gratuitously low-level manner, in order to + // serve as a kind of template for what the JIT would do. Note that the + // way it's written it ought to only require one register, which doubles + // as the result, provided that the compiler does a minimal amount of + // control flow simplification and the bytes argument is a constant. + + size_t currentRemaining = m_currentRemaining; + if (bytes > currentRemaining) + return false; + currentRemaining -= bytes; + m_currentRemaining = currentRemaining; + *outPtr = m_currentPayloadEnd - currentRemaining - bytes; + + ASSERT(is8ByteAligned(*outPtr)); + + return true; +} + +inline CheckedBoolean CopiedAllocator::tryReallocate( + void* oldPtr, size_t oldBytes, size_t newBytes) +{ + ASSERT(is8ByteAligned(oldPtr)); + ASSERT(is8ByteAligned(reinterpret_cast<void*>(oldBytes))); + ASSERT(is8ByteAligned(reinterpret_cast<void*>(newBytes))); + + ASSERT(newBytes > oldBytes); + + size_t additionalBytes = newBytes - oldBytes; + + size_t currentRemaining = m_currentRemaining; + if (m_currentPayloadEnd - currentRemaining - oldBytes != static_cast<char*>(oldPtr)) + return false; + + if (additionalBytes > currentRemaining) + return false; + + m_currentRemaining = currentRemaining - additionalBytes; + + return true; } -inline bool CopiedAllocator::wasLastAllocation(void* ptr, size_t size) +inline void* CopiedAllocator::forceAllocate(size_t bytes) { - return static_cast<char*>(ptr) + size == m_currentOffset && ptr > m_currentBlock && ptr < reinterpret_cast<char*>(m_currentBlock) + HeapBlock::s_blockSize; + void* result = 0; // Needed because compilers don't realize this will always be assigned. + CheckedBoolean didSucceed = tryAllocate(bytes, &result); + ASSERT(didSucceed); + return result; } -inline void CopiedAllocator::startedCopying() +inline CopiedBlock* CopiedAllocator::resetCurrentBlock() { - if (m_currentBlock) - m_currentBlock->m_offset = static_cast<void*>(m_currentOffset); - m_currentOffset = 0; - m_currentBlock = 0; + CopiedBlock* result = m_currentBlock; + if (result) { + result->m_remaining = m_currentRemaining; + m_currentBlock = 0; + m_currentRemaining = 0; + m_currentPayloadEnd = 0; + } + return result; } -inline void CopiedAllocator::resetCurrentBlock(CopiedBlock* newBlock) +inline void CopiedAllocator::setCurrentBlock(CopiedBlock* newBlock) { - if (m_currentBlock) - m_currentBlock->m_offset = static_cast<void*>(m_currentOffset); + ASSERT(!m_currentBlock); m_currentBlock = newBlock; - m_currentOffset = static_cast<char*>(newBlock->m_offset); + ASSERT(newBlock); + m_currentRemaining = newBlock->m_remaining; + m_currentPayloadEnd = newBlock->payloadEnd(); } inline size_t CopiedAllocator::currentCapacity() { + if (!m_currentBlock) + return 0; return m_currentBlock->capacity(); } diff --git a/Source/JavaScriptCore/heap/CopiedBlock.h b/Source/JavaScriptCore/heap/CopiedBlock.h index 5ed58008e..6717a6835 100644 --- a/Source/JavaScriptCore/heap/CopiedBlock.h +++ b/Source/JavaScriptCore/heap/CopiedBlock.h @@ -42,15 +42,30 @@ public: static CopiedBlock* createNoZeroFill(const PageAllocationAligned&); static PageAllocationAligned destroy(CopiedBlock*); + // The payload is the region of the block that is usable for allocations. char* payload(); + char* payloadEnd(); + size_t payloadCapacity(); + + // The data is the region of the block that has been used for allocations. + char* data(); + char* dataEnd(); + size_t dataSize(); + + // The wilderness is the region of the block that is usable for allocations + // but has not been so used. + char* wilderness(); + char* wildernessEnd(); + size_t wildernessSize(); + size_t size(); size_t capacity(); private: CopiedBlock(const PageAllocationAligned&); - void zeroFillToEnd(); // Can be called at any time to zero-fill to the end of the block. + void zeroFillWilderness(); // Can be called at any time to zero-fill to the end of the block. - void* m_offset; + size_t m_remaining; uintptr_t m_isPinned; }; @@ -62,19 +77,18 @@ inline CopiedBlock* CopiedBlock::createNoZeroFill(const PageAllocationAligned& a inline CopiedBlock* CopiedBlock::create(const PageAllocationAligned& allocation) { CopiedBlock* block = createNoZeroFill(allocation); - block->zeroFillToEnd(); + block->zeroFillWilderness(); return block; } -inline void CopiedBlock::zeroFillToEnd() +inline void CopiedBlock::zeroFillWilderness() { #if USE(JSVALUE64) - char* offset = static_cast<char*>(m_offset); - memset(static_cast<void*>(offset), 0, static_cast<size_t>((reinterpret_cast<char*>(this) + m_allocation.size()) - offset)); + memset(wilderness(), 0, wildernessSize()); #else JSValue emptyValue; - JSValue* limit = reinterpret_cast_ptr<JSValue*>(reinterpret_cast<char*>(this) + m_allocation.size()); - for (JSValue* currentValue = reinterpret_cast<JSValue*>(m_offset); currentValue < limit; currentValue++) + JSValue* limit = reinterpret_cast_ptr<JSValue*>(wildernessEnd()); + for (JSValue* currentValue = reinterpret_cast<JSValue*>(wilderness()); currentValue < limit; currentValue++) *currentValue = emptyValue; #endif } @@ -90,10 +104,10 @@ inline PageAllocationAligned CopiedBlock::destroy(CopiedBlock* block) inline CopiedBlock::CopiedBlock(const PageAllocationAligned& allocation) : HeapBlock(allocation) - , m_offset(payload()) + , m_remaining(payloadCapacity()) , m_isPinned(false) { - ASSERT(is8ByteAligned(static_cast<void*>(m_offset))); + ASSERT(is8ByteAligned(reinterpret_cast<void*>(m_remaining))); } inline char* CopiedBlock::payload() @@ -101,9 +115,49 @@ inline char* CopiedBlock::payload() return reinterpret_cast<char*>(this) + ((sizeof(CopiedBlock) + 7) & ~7); } +inline char* CopiedBlock::payloadEnd() +{ + return reinterpret_cast<char*>(this) + m_allocation.size(); +} + +inline size_t CopiedBlock::payloadCapacity() +{ + return payloadEnd() - payload(); +} + +inline char* CopiedBlock::data() +{ + return payload(); +} + +inline char* CopiedBlock::dataEnd() +{ + return payloadEnd() - m_remaining; +} + +inline size_t CopiedBlock::dataSize() +{ + return dataEnd() - data(); +} + +inline char* CopiedBlock::wilderness() +{ + return dataEnd(); +} + +inline char* CopiedBlock::wildernessEnd() +{ + return payloadEnd(); +} + +inline size_t CopiedBlock::wildernessSize() +{ + return wildernessEnd() - wilderness(); +} + inline size_t CopiedBlock::size() { - return static_cast<size_t>(static_cast<char*>(m_offset) - payload()); + return dataSize(); } inline size_t CopiedBlock::capacity() diff --git a/Source/JavaScriptCore/heap/CopiedSpace.cpp b/Source/JavaScriptCore/heap/CopiedSpace.cpp index 9eb70a556..147dfa4b3 100644 --- a/Source/JavaScriptCore/heap/CopiedSpace.cpp +++ b/Source/JavaScriptCore/heap/CopiedSpace.cpp @@ -71,8 +71,7 @@ CheckedBoolean CopiedSpace::tryAllocateSlowCase(size_t bytes, void** outPtr) allocateBlock(); - *outPtr = m_allocator.allocate(bytes); - ASSERT(*outPtr); + *outPtr = m_allocator.forceAllocate(bytes); return true; } @@ -93,7 +92,10 @@ CheckedBoolean CopiedSpace::tryAllocateOversize(size_t bytes, void** outPtr) m_blockFilter.add(reinterpret_cast<Bits>(block)); m_blockSet.add(block); - *outPtr = allocateFromBlock(block, bytes); + CopiedAllocator allocator; + allocator.setCurrentBlock(block); + *outPtr = allocator.forceAllocate(bytes); + allocator.resetCurrentBlock(); m_heap->didAllocate(blockSize); @@ -107,17 +109,12 @@ CheckedBoolean CopiedSpace::tryReallocate(void** ptr, size_t oldSize, size_t new void* oldPtr = *ptr; ASSERT(!m_heap->globalData()->isInitializingObject()); - + if (isOversize(oldSize) || isOversize(newSize)) return tryReallocateOversize(ptr, oldSize, newSize); - - if (m_allocator.wasLastAllocation(oldPtr, oldSize)) { - size_t delta = newSize - oldSize; - if (m_allocator.fitsInCurrentBlock(delta)) { - (void)m_allocator.allocate(delta); - return true; - } - } + + if (m_allocator.tryReallocate(oldPtr, oldSize, newSize)) + return true; void* result = 0; if (!tryAllocate(newSize, &result)) { @@ -157,16 +154,17 @@ CheckedBoolean CopiedSpace::tryReallocateOversize(void** ptr, size_t oldSize, si void CopiedSpace::doneFillingBlock(CopiedBlock* block) { - ASSERT(block); - ASSERT(block->m_offset < reinterpret_cast<char*>(block) + HeapBlock::s_blockSize); ASSERT(m_inCopyingPhase); + + if (!block) + return; - if (block->m_offset == block->payload()) { + if (!block->dataSize()) { recycleBlock(block); return; } - block->zeroFillToEnd(); + block->zeroFillWilderness(); { SpinLockHolder locker(&m_toSpaceLock); @@ -226,7 +224,7 @@ void CopiedSpace::doneCopying() if (!m_toSpace->head()) allocateBlock(); else - m_allocator.resetCurrentBlock(static_cast<CopiedBlock*>(m_toSpace->head())); + m_allocator.setCurrentBlock(static_cast<CopiedBlock*>(m_toSpace->head())); } size_t CopiedSpace::size() diff --git a/Source/JavaScriptCore/heap/CopiedSpace.h b/Source/JavaScriptCore/heap/CopiedSpace.h index 530e989da..de682a4c1 100644 --- a/Source/JavaScriptCore/heap/CopiedSpace.h +++ b/Source/JavaScriptCore/heap/CopiedSpace.h @@ -77,9 +77,7 @@ public: static CopiedBlock* blockFor(void*); private: - static void* allocateFromBlock(CopiedBlock*, size_t); static bool isOversize(size_t); - static bool fitsInBlock(CopiedBlock*, size_t); static CopiedBlock* oversizeBlockFor(void* ptr); CheckedBoolean tryAllocateSlowCase(size_t, void**); diff --git a/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h b/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h index 1366cd8a7..f702e1dd9 100644 --- a/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h +++ b/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h @@ -64,7 +64,7 @@ inline void CopiedSpace::startedCopying() m_toSpace = temp; m_blockFilter.reset(); - m_allocator.startedCopying(); + m_allocator.resetCurrentBlock(); ASSERT(!m_inCopyingPhase); ASSERT(!m_numberOfLoanedBlocks); @@ -94,7 +94,7 @@ inline CopiedBlock* CopiedSpace::allocateBlockForCopyingPhase() m_numberOfLoanedBlocks++; } - ASSERT(block->m_offset == block->payload()); + ASSERT(!block->dataSize()); return block; } @@ -103,45 +103,27 @@ inline void CopiedSpace::allocateBlock() if (m_heap->shouldCollect()) m_heap->collect(Heap::DoNotSweep); + m_allocator.resetCurrentBlock(); + CopiedBlock* block = CopiedBlock::create(m_heap->blockAllocator().allocate()); m_toSpace->push(block); m_blockFilter.add(reinterpret_cast<Bits>(block)); m_blockSet.add(block); - m_allocator.resetCurrentBlock(block); -} - -inline bool CopiedSpace::fitsInBlock(CopiedBlock* block, size_t bytes) -{ - return static_cast<char*>(block->m_offset) + bytes < reinterpret_cast<char*>(block) + block->capacity() && static_cast<char*>(block->m_offset) + bytes > block->m_offset; + m_allocator.setCurrentBlock(block); } inline CheckedBoolean CopiedSpace::tryAllocate(size_t bytes, void** outPtr) { ASSERT(!m_heap->globalData()->isInitializingObject()); - if (isOversize(bytes) || !m_allocator.fitsInCurrentBlock(bytes)) + if (isOversize(bytes) || !m_allocator.tryAllocate(bytes, outPtr)) return tryAllocateSlowCase(bytes, outPtr); - *outPtr = m_allocator.allocate(bytes); ASSERT(*outPtr); return true; } -inline void* CopiedSpace::allocateFromBlock(CopiedBlock* block, size_t bytes) -{ - ASSERT(fitsInBlock(block, bytes)); - ASSERT(is8ByteAligned(block->m_offset)); - - void* ptr = block->m_offset; - ASSERT(block->m_offset >= block->payload() && block->m_offset < reinterpret_cast<char*>(block) + block->capacity()); - block->m_offset = static_cast<void*>((static_cast<char*>(ptr) + bytes)); - ASSERT(block->m_offset >= block->payload() && block->m_offset < reinterpret_cast<char*>(block) + block->capacity()); - - ASSERT(is8ByteAligned(ptr)); - return ptr; -} - inline bool CopiedSpace::isOversize(size_t bytes) { return bytes > s_maxAllocationSize; diff --git a/Source/JavaScriptCore/heap/MachineStackMarker.cpp b/Source/JavaScriptCore/heap/MachineStackMarker.cpp index 8e0c57b6a..7eb57479b 100644 --- a/Source/JavaScriptCore/heap/MachineStackMarker.cpp +++ b/Source/JavaScriptCore/heap/MachineStackMarker.cpp @@ -141,8 +141,10 @@ MachineThreads::MachineThreads(Heap* heap) MachineThreads::~MachineThreads() { - if (m_threadSpecific) - ThreadSpecificKeyDelete(m_threadSpecific); + if (m_threadSpecific) { + int error = pthread_key_delete(m_threadSpecific); + ASSERT_UNUSED(error, !error); + } MutexLocker registeredThreadsLock(m_registeredThreadsMutex); for (Thread* t = m_registeredThreads; t;) { @@ -179,17 +181,19 @@ void MachineThreads::makeUsableFromMultipleThreads() if (m_threadSpecific) return; - ThreadSpecificKeyCreate(&m_threadSpecific, removeThread); + int error = pthread_key_create(&m_threadSpecific, removeThread); + if (error) + CRASH(); } void MachineThreads::addCurrentThread() { ASSERT(!m_heap->globalData()->exclusiveThread || m_heap->globalData()->exclusiveThread == currentThread()); - if (!m_threadSpecific || ThreadSpecificGet(m_threadSpecific)) + if (!m_threadSpecific || pthread_getspecific(m_threadSpecific)) return; - ThreadSpecificSet(m_threadSpecific, this); + pthread_setspecific(m_threadSpecific, this); Thread* thread = new Thread(getCurrentPlatformThread(), wtfThreadData().stack().origin()); MutexLocker lock(m_registeredThreadsMutex); diff --git a/Source/JavaScriptCore/heap/MachineStackMarker.h b/Source/JavaScriptCore/heap/MachineStackMarker.h index 3d4aa22d4..5c7705fcf 100644 --- a/Source/JavaScriptCore/heap/MachineStackMarker.h +++ b/Source/JavaScriptCore/heap/MachineStackMarker.h @@ -22,8 +22,8 @@ #ifndef MachineThreads_h #define MachineThreads_h +#include <pthread.h> #include <wtf/Noncopyable.h> -#include <wtf/ThreadSpecific.h> #include <wtf/ThreadingPrimitives.h> namespace JSC { @@ -55,7 +55,7 @@ namespace JSC { Heap* m_heap; Mutex m_registeredThreadsMutex; Thread* m_registeredThreads; - WTF::ThreadSpecificKey m_threadSpecific; + pthread_key_t m_threadSpecific; }; } // namespace JSC diff --git a/Source/JavaScriptCore/heap/MarkStack.cpp b/Source/JavaScriptCore/heap/MarkStack.cpp index 9d9130026..9c679b0ed 100644 --- a/Source/JavaScriptCore/heap/MarkStack.cpp +++ b/Source/JavaScriptCore/heap/MarkStack.cpp @@ -515,9 +515,8 @@ void MarkStack::mergeOpaqueRoots() void SlotVisitor::startCopying() { - ASSERT(!m_copyBlock); - m_copyBlock = m_shared.m_copiedSpace->allocateBlockForCopyingPhase(); -} + ASSERT(!m_copiedAllocator.isValid()); +} void* SlotVisitor::allocateNewSpace(void* ptr, size_t bytes) { @@ -528,18 +527,17 @@ void* SlotVisitor::allocateNewSpace(void* ptr, size_t bytes) if (m_shared.m_copiedSpace->isPinned(ptr)) return 0; + + void* result = 0; // Compilers don't realize that this will be assigned. + if (m_copiedAllocator.tryAllocate(bytes, &result)) + return result; + + m_shared.m_copiedSpace->doneFillingBlock(m_copiedAllocator.resetCurrentBlock()); + m_copiedAllocator.setCurrentBlock(m_shared.m_copiedSpace->allocateBlockForCopyingPhase()); - // The only time it's possible to have a null copy block is if we have just started copying. - if (!m_copyBlock) - startCopying(); - - if (!CopiedSpace::fitsInBlock(m_copyBlock, bytes)) { - // We don't need to lock across these two calls because the master thread won't - // call doneCopying() because this thread is considered active. - m_shared.m_copiedSpace->doneFillingBlock(m_copyBlock); - m_copyBlock = m_shared.m_copiedSpace->allocateBlockForCopyingPhase(); - } - return CopiedSpace::allocateFromBlock(m_copyBlock, bytes); + CheckedBoolean didSucceed = m_copiedAllocator.tryAllocate(bytes, &result); + ASSERT(didSucceed); + return result; } ALWAYS_INLINE bool JSString::tryHashConstLock() @@ -639,12 +637,10 @@ void SlotVisitor::copyAndAppend(void** ptr, size_t bytes, JSValue* values, unsig void SlotVisitor::doneCopying() { - if (!m_copyBlock) + if (!m_copiedAllocator.isValid()) return; - m_shared.m_copiedSpace->doneFillingBlock(m_copyBlock); - - m_copyBlock = 0; + m_shared.m_copiedSpace->doneFillingBlock(m_copiedAllocator.resetCurrentBlock()); } void SlotVisitor::harvestWeakReferences() diff --git a/Source/JavaScriptCore/heap/SlotVisitor.h b/Source/JavaScriptCore/heap/SlotVisitor.h index 70d68bb04..d16602f15 100644 --- a/Source/JavaScriptCore/heap/SlotVisitor.h +++ b/Source/JavaScriptCore/heap/SlotVisitor.h @@ -70,12 +70,11 @@ private: void donateKnownParallel(); - CopiedBlock* m_copyBlock; + CopiedAllocator m_copiedAllocator; }; inline SlotVisitor::SlotVisitor(MarkStackThreadSharedData& shared) : MarkStack(shared) - , m_copyBlock(0) { } diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h index 987c4a163..5529551d6 100644 --- a/Source/JavaScriptCore/jit/JIT.h +++ b/Source/JavaScriptCore/jit/JIT.h @@ -435,7 +435,7 @@ namespace JSC { void emitWriteBarrier(JSCell* owner, RegisterID value, RegisterID scratch, WriteBarrierMode, WriteBarrierUseKind); template<typename ClassType, bool destructor, typename StructureType> void emitAllocateBasicJSObject(StructureType, RegisterID result, RegisterID storagePtr); - void emitAllocateBasicStorage(size_t, RegisterID result, RegisterID storagePtr); + void emitAllocateBasicStorage(size_t, RegisterID result); template<typename T> void emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID storagePtr); void emitAllocateJSArray(unsigned valuesRegister, unsigned length, RegisterID cellResult, RegisterID storageResult, RegisterID storagePtr); diff --git a/Source/JavaScriptCore/jit/JITInlineMethods.h b/Source/JavaScriptCore/jit/JITInlineMethods.h index d1cee7ef7..42a61ecdb 100644 --- a/Source/JavaScriptCore/jit/JITInlineMethods.h +++ b/Source/JavaScriptCore/jit/JITInlineMethods.h @@ -437,25 +437,16 @@ template <typename T> inline void JIT::emitAllocateJSFinalObject(T structure, Re emitAllocateBasicJSObject<JSFinalObject, false, T>(structure, result, scratch); } -inline void JIT::emitAllocateBasicStorage(size_t size, RegisterID result, RegisterID storagePtr) +inline void JIT::emitAllocateBasicStorage(size_t size, RegisterID result) { CopiedAllocator* allocator = &m_globalData->heap.storageAllocator(); - // FIXME: We need to check for wrap-around. - // Check to make sure that the allocation will fit in the current block. - loadPtr(&allocator->m_currentOffset, result); - addPtr(TrustedImm32(size), result); - loadPtr(&allocator->m_currentBlock, storagePtr); - addPtr(TrustedImm32(HeapBlock::s_blockSize), storagePtr); - addSlowCase(branchPtr(AboveOrEqual, result, storagePtr)); - - // Load the original offset. - loadPtr(&allocator->m_currentOffset, result); - - // Bump the pointer forward. - move(result, storagePtr); - addPtr(TrustedImm32(size), storagePtr); - storePtr(storagePtr, &allocator->m_currentOffset); + loadPtr(&allocator->m_currentRemaining, result); + addSlowCase(branchSubPtr(Signed, TrustedImm32(size), result)); + storePtr(result, &allocator->m_currentRemaining); + negPtr(result); + addPtr(AbsoluteAddress(&allocator->m_currentPayloadEnd), result); + subPtr(TrustedImm32(size), result); } inline void JIT::emitAllocateJSArray(unsigned valuesRegister, unsigned length, RegisterID cellResult, RegisterID storageResult, RegisterID storagePtr) @@ -465,7 +456,7 @@ inline void JIT::emitAllocateJSArray(unsigned valuesRegister, unsigned length, R // We allocate the backing store first to ensure that garbage collection // doesn't happen during JSArray initialization. - emitAllocateBasicStorage(initialStorage, storageResult, storagePtr); + emitAllocateBasicStorage(initialStorage, storageResult); // Allocate the cell for the array. emitAllocateBasicJSObject<JSArray, false>(TrustedImmPtr(m_codeBlock->globalObject()->arrayStructure()), cellResult, storagePtr); diff --git a/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj b/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj index a33c5ce1f..ea3d7c2e5 100644 --- a/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj +++ b/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj @@ -38,6 +38,48 @@ A0AABE4513AFE94500F2EBD1 /* OutputESSL.h in Headers */ = {isa = PBXBuildFile; fileRef = A0AABE4313AFE94500F2EBD1 /* OutputESSL.h */; }; A0AABE4813AFE96100F2EBD1 /* TranslatorESSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A0AABE4613AFE96100F2EBD1 /* TranslatorESSL.cpp */; }; A0AABE4913AFE96100F2EBD1 /* TranslatorESSL.h in Headers */ = {isa = PBXBuildFile; fileRef = A0AABE4713AFE96100F2EBD1 /* TranslatorESSL.h */; }; + A26567BB159C21B100398539 /* Diagnostics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A26567B0159C21B100398539 /* Diagnostics.cpp */; }; + A26567BC159C21B100398539 /* Diagnostics.h in Headers */ = {isa = PBXBuildFile; fileRef = A26567B1159C21B100398539 /* Diagnostics.h */; }; + A26567BD159C21B100398539 /* DirectiveHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A26567B2159C21B100398539 /* DirectiveHandler.cpp */; }; + A26567BE159C21B100398539 /* DirectiveHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = A26567B3159C21B100398539 /* DirectiveHandler.h */; }; + A26567BF159C21B100398539 /* InitializeParseContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A26567B4159C21B100398539 /* InitializeParseContext.cpp */; }; + A26567C0159C21B100398539 /* Pragma.h in Headers */ = {isa = PBXBuildFile; fileRef = A26567B5159C21B100398539 /* Pragma.h */; }; + A26567C1159C21B100398539 /* RenameFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = A26567B6159C21B100398539 /* RenameFunction.h */; }; + A26567EC159C21CE00398539 /* DiagnosticsBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A26567C8159C21CE00398539 /* DiagnosticsBase.cpp */; }; + A26567ED159C21CE00398539 /* Diagnostics.h in Headers */ = {isa = PBXBuildFile; fileRef = A26567C9159C21CE00398539 /* Diagnostics.h */; }; + A26567EE159C21CE00398539 /* DirectiveHandlerBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A26567CA159C21CE00398539 /* DirectiveHandlerBase.cpp */; }; + A26567EF159C21CE00398539 /* DirectiveHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = A26567CB159C21CE00398539 /* DirectiveHandler.h */; }; + A26567F0159C21CE00398539 /* DirectiveParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A26567CC159C21CE00398539 /* DirectiveParser.cpp */; }; + A26567F1159C21CE00398539 /* DirectiveParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A26567CD159C21CE00398539 /* DirectiveParser.h */; }; + A26567F2159C21CE00398539 /* ExpressionParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A26567CE159C21CE00398539 /* ExpressionParser.cpp */; }; + A26567F3159C21CE00398539 /* ExpressionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A26567CF159C21CE00398539 /* ExpressionParser.h */; }; + A26567F5159C21CE00398539 /* Input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A26567D2159C21CE00398539 /* Input.cpp */; }; + A26567F6159C21CE00398539 /* Input.h in Headers */ = {isa = PBXBuildFile; fileRef = A26567D3159C21CE00398539 /* Input.h */; }; + A26567F7159C21CE00398539 /* Lexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A26567D4159C21CE00398539 /* Lexer.cpp */; }; + A26567F8159C21CE00398539 /* Lexer.h in Headers */ = {isa = PBXBuildFile; fileRef = A26567D5159C21CE00398539 /* Lexer.h */; }; + A26567F9159C21CE00398539 /* Macro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A26567D6159C21CE00398539 /* Macro.cpp */; }; + A26567FA159C21CE00398539 /* Macro.h in Headers */ = {isa = PBXBuildFile; fileRef = A26567D7159C21CE00398539 /* Macro.h */; }; + A26567FB159C21CE00398539 /* MacroExpander.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A26567D8159C21CE00398539 /* MacroExpander.cpp */; }; + A26567FC159C21CE00398539 /* MacroExpander.h in Headers */ = {isa = PBXBuildFile; fileRef = A26567D9159C21CE00398539 /* MacroExpander.h */; }; + A2656803159C21CE00398539 /* Preprocessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A26567E0159C21CE00398539 /* Preprocessor.cpp */; }; + A2656804159C21CE00398539 /* Preprocessor.h in Headers */ = {isa = PBXBuildFile; fileRef = A26567E1159C21CE00398539 /* Preprocessor.h */; }; + A2656805159C21CE00398539 /* SourceLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = A26567E2159C21CE00398539 /* SourceLocation.h */; }; + A2656807159C21CE00398539 /* Token.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A26567E4159C21CE00398539 /* Token.cpp */; }; + A2656808159C21CE00398539 /* Token.h in Headers */ = {isa = PBXBuildFile; fileRef = A26567E5159C21CE00398539 /* Token.h */; }; + A265680A159C21CE00398539 /* Tokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A26567E7159C21CE00398539 /* Tokenizer.cpp */; }; + A265680B159C21CE00398539 /* Tokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = A26567E8159C21CE00398539 /* Tokenizer.h */; }; + A265682B159C238800398539 /* pp_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = A265682A159C238800398539 /* pp_utils.h */; }; + A2656839159C23E100398539 /* DependencyGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265682D159C23E100398539 /* DependencyGraph.cpp */; }; + A265683A159C23E100398539 /* DependencyGraph.h in Headers */ = {isa = PBXBuildFile; fileRef = A265682E159C23E100398539 /* DependencyGraph.h */; }; + A265683B159C23E100398539 /* DependencyGraphBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A265682F159C23E100398539 /* DependencyGraphBuilder.cpp */; }; + A265683C159C23E100398539 /* DependencyGraphBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = A2656830159C23E100398539 /* DependencyGraphBuilder.h */; }; + A265683D159C23E100398539 /* DependencyGraphOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2656831159C23E100398539 /* DependencyGraphOutput.cpp */; }; + A265683E159C23E100398539 /* DependencyGraphOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = A2656832159C23E100398539 /* DependencyGraphOutput.h */; }; + A265683F159C23E100398539 /* DependencyGraphTraverse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2656833159C23E100398539 /* DependencyGraphTraverse.cpp */; }; + A2656840159C23E100398539 /* RestrictFragmentShaderTiming.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2656835159C23E100398539 /* RestrictFragmentShaderTiming.cpp */; }; + A2656841159C23E100398539 /* RestrictFragmentShaderTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = A2656836159C23E100398539 /* RestrictFragmentShaderTiming.h */; }; + A2656842159C23E100398539 /* RestrictVertexShaderTiming.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2656837159C23E100398539 /* RestrictVertexShaderTiming.cpp */; }; + A2656843159C23E100398539 /* RestrictVertexShaderTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = A2656838159C23E100398539 /* RestrictVertexShaderTiming.h */; }; FB39D2711200F35A00088E69 /* CodeGenGLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D2221200F35A00088E69 /* CodeGenGLSL.cpp */; }; FB39D2751200F35A00088E69 /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D2261200F35A00088E69 /* debug.cpp */; }; FB39D2791200F35A00088E69 /* InfoSink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D22A1200F35A00088E69 /* InfoSink.cpp */; }; @@ -63,7 +105,6 @@ FB39D2A81200F35A00088E69 /* ShaderLang.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D25A1200F35A00088E69 /* ShaderLang.cpp */; }; FB39D2AA1200F35A00088E69 /* SymbolTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D25C1200F35A00088E69 /* SymbolTable.cpp */; }; FB39D2AC1200F35A00088E69 /* TranslatorGLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D2681200F35A00088E69 /* TranslatorGLSL.cpp */; }; - FB39D2B11200F35A00088E69 /* UnfoldSelect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D26D1200F35A00088E69 /* UnfoldSelect.cpp */; }; FB39D76E120110FC00088E69 /* ShaderLang.h in Headers */ = {isa = PBXBuildFile; fileRef = FB39D2BF1200F3E600088E69 /* ShaderLang.h */; settings = {ATTRIBUTES = (Public, ); }; }; /* End PBXBuildFile section */ @@ -103,6 +144,52 @@ A0AABE4313AFE94500F2EBD1 /* OutputESSL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OutputESSL.h; sourceTree = "<group>"; }; A0AABE4613AFE96100F2EBD1 /* TranslatorESSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TranslatorESSL.cpp; sourceTree = "<group>"; }; A0AABE4713AFE96100F2EBD1 /* TranslatorESSL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TranslatorESSL.h; sourceTree = "<group>"; }; + A26567AE159C21B100398539 /* DetectDiscontinuity.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DetectDiscontinuity.cpp; sourceTree = "<group>"; }; + A26567AF159C21B100398539 /* DetectDiscontinuity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetectDiscontinuity.h; sourceTree = "<group>"; }; + A26567B0159C21B100398539 /* Diagnostics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Diagnostics.cpp; sourceTree = "<group>"; }; + A26567B1159C21B100398539 /* Diagnostics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Diagnostics.h; sourceTree = "<group>"; }; + A26567B2159C21B100398539 /* DirectiveHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectiveHandler.cpp; sourceTree = "<group>"; }; + A26567B3159C21B100398539 /* DirectiveHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectiveHandler.h; sourceTree = "<group>"; }; + A26567B4159C21B100398539 /* InitializeParseContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeParseContext.cpp; sourceTree = "<group>"; }; + A26567B5159C21B100398539 /* Pragma.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pragma.h; sourceTree = "<group>"; }; + A26567B6159C21B100398539 /* RenameFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenameFunction.h; sourceTree = "<group>"; }; + A26567B7159C21B100398539 /* UnfoldShortCircuit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnfoldShortCircuit.cpp; sourceTree = "<group>"; }; + A26567B8159C21B100398539 /* UnfoldShortCircuit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnfoldShortCircuit.h; sourceTree = "<group>"; }; + A26567C8159C21CE00398539 /* DiagnosticsBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DiagnosticsBase.cpp; sourceTree = "<group>"; }; + A26567C9159C21CE00398539 /* Diagnostics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Diagnostics.h; sourceTree = "<group>"; }; + A26567CA159C21CE00398539 /* DirectiveHandlerBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectiveHandlerBase.cpp; sourceTree = "<group>"; }; + A26567CB159C21CE00398539 /* DirectiveHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectiveHandler.h; sourceTree = "<group>"; }; + A26567CC159C21CE00398539 /* DirectiveParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectiveParser.cpp; sourceTree = "<group>"; }; + A26567CD159C21CE00398539 /* DirectiveParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectiveParser.h; sourceTree = "<group>"; }; + A26567CE159C21CE00398539 /* ExpressionParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExpressionParser.cpp; sourceTree = "<group>"; }; + A26567CF159C21CE00398539 /* ExpressionParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExpressionParser.h; sourceTree = "<group>"; }; + A26567D2159C21CE00398539 /* Input.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Input.cpp; sourceTree = "<group>"; }; + A26567D3159C21CE00398539 /* Input.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Input.h; sourceTree = "<group>"; }; + A26567D4159C21CE00398539 /* Lexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Lexer.cpp; sourceTree = "<group>"; }; + A26567D5159C21CE00398539 /* Lexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Lexer.h; sourceTree = "<group>"; }; + A26567D6159C21CE00398539 /* Macro.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Macro.cpp; sourceTree = "<group>"; }; + A26567D7159C21CE00398539 /* Macro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Macro.h; sourceTree = "<group>"; }; + A26567D8159C21CE00398539 /* MacroExpander.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroExpander.cpp; sourceTree = "<group>"; }; + A26567D9159C21CE00398539 /* MacroExpander.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroExpander.h; sourceTree = "<group>"; }; + A26567E0159C21CE00398539 /* Preprocessor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Preprocessor.cpp; sourceTree = "<group>"; }; + A26567E1159C21CE00398539 /* Preprocessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Preprocessor.h; sourceTree = "<group>"; }; + A26567E2159C21CE00398539 /* SourceLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceLocation.h; sourceTree = "<group>"; }; + A26567E4159C21CE00398539 /* Token.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Token.cpp; sourceTree = "<group>"; }; + A26567E5159C21CE00398539 /* Token.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Token.h; sourceTree = "<group>"; }; + A26567E7159C21CE00398539 /* Tokenizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Tokenizer.cpp; sourceTree = "<group>"; }; + A26567E8159C21CE00398539 /* Tokenizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tokenizer.h; sourceTree = "<group>"; }; + A265682A159C238800398539 /* pp_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pp_utils.h; sourceTree = "<group>"; }; + A265682D159C23E100398539 /* DependencyGraph.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DependencyGraph.cpp; sourceTree = "<group>"; }; + A265682E159C23E100398539 /* DependencyGraph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DependencyGraph.h; sourceTree = "<group>"; }; + A265682F159C23E100398539 /* DependencyGraphBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DependencyGraphBuilder.cpp; sourceTree = "<group>"; }; + A2656830159C23E100398539 /* DependencyGraphBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DependencyGraphBuilder.h; sourceTree = "<group>"; }; + A2656831159C23E100398539 /* DependencyGraphOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DependencyGraphOutput.cpp; sourceTree = "<group>"; }; + A2656832159C23E100398539 /* DependencyGraphOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DependencyGraphOutput.h; sourceTree = "<group>"; }; + A2656833159C23E100398539 /* DependencyGraphTraverse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DependencyGraphTraverse.cpp; sourceTree = "<group>"; }; + A2656835159C23E100398539 /* RestrictFragmentShaderTiming.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RestrictFragmentShaderTiming.cpp; sourceTree = "<group>"; }; + A2656836159C23E100398539 /* RestrictFragmentShaderTiming.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RestrictFragmentShaderTiming.h; sourceTree = "<group>"; }; + A2656837159C23E100398539 /* RestrictVertexShaderTiming.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RestrictVertexShaderTiming.cpp; sourceTree = "<group>"; }; + A2656838159C23E100398539 /* RestrictVertexShaderTiming.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RestrictVertexShaderTiming.h; sourceTree = "<group>"; }; FB39D0D11200F0E300088E69 /* libANGLE.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libANGLE.a; sourceTree = BUILT_PRODUCTS_DIR; }; FB39D1861200F26200088E69 /* BaseTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BaseTypes.h; sourceTree = "<group>"; }; FB39D1871200F26200088E69 /* CodeGenGLSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGenGLSL.cpp; sourceTree = "<group>"; }; @@ -162,15 +249,11 @@ FB39D1C01200F26200088E69 /* ShHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShHandle.h; sourceTree = "<group>"; }; FB39D1C11200F26200088E69 /* SymbolTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolTable.cpp; sourceTree = "<group>"; }; FB39D1C21200F26200088E69 /* SymbolTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolTable.h; sourceTree = "<group>"; }; - FB39D1CB1200F26200088E69 /* translator_common.vcproj */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = translator_common.vcproj; sourceTree = "<group>"; }; - FB39D1CC1200F26200088E69 /* translator_hlsl.vcproj */ = {isa = PBXFileReference; explicitFileType = text.xml; fileEncoding = 4; path = translator_hlsl.vcproj; sourceTree = "<group>"; }; FB39D1CD1200F26200088E69 /* TranslatorGLSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.cpp.cpp; path = TranslatorGLSL.cpp; sourceTree = "<group>"; }; FB39D1CE1200F26200088E69 /* TranslatorGLSL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TranslatorGLSL.h; sourceTree = "<group>"; }; FB39D1CF1200F26200088E69 /* TranslatorHLSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.cpp.cpp; path = TranslatorHLSL.cpp; sourceTree = "<group>"; }; FB39D1D01200F26200088E69 /* TranslatorHLSL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TranslatorHLSL.h; sourceTree = "<group>"; }; FB39D1D11200F26200088E69 /* Types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Types.h; sourceTree = "<group>"; }; - FB39D1D21200F26200088E69 /* UnfoldSelect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.cpp.cpp; path = UnfoldSelect.cpp; sourceTree = "<group>"; }; - FB39D1D31200F26200088E69 /* UnfoldSelect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnfoldSelect.h; sourceTree = "<group>"; }; FB39D2211200F35A00088E69 /* BaseTypes.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = BaseTypes.h; sourceTree = "<group>"; }; FB39D2221200F35A00088E69 /* CodeGenGLSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGenGLSL.cpp; sourceTree = "<group>"; }; FB39D2241200F35A00088E69 /* Common.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = Common.h; sourceTree = "<group>"; }; @@ -229,8 +312,6 @@ FB39D2681200F35A00088E69 /* TranslatorGLSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TranslatorGLSL.cpp; sourceTree = "<group>"; }; FB39D2691200F35A00088E69 /* TranslatorGLSL.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = TranslatorGLSL.h; sourceTree = "<group>"; }; FB39D26C1200F35A00088E69 /* Types.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = Types.h; sourceTree = "<group>"; }; - FB39D26D1200F35A00088E69 /* UnfoldSelect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnfoldSelect.cpp; sourceTree = "<group>"; }; - FB39D26E1200F35A00088E69 /* UnfoldSelect.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = UnfoldSelect.h; sourceTree = "<group>"; }; FB39D2BF1200F3E600088E69 /* ShaderLang.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = ShaderLang.h; sourceTree = "<group>"; }; /* End PBXFileReference section */ @@ -255,6 +336,62 @@ path = Configurations; sourceTree = "<group>"; }; + A26567C5159C21CE00398539 /* new */ = { + isa = PBXGroup; + children = ( + A265682A159C238800398539 /* pp_utils.h */, + A26567C8159C21CE00398539 /* DiagnosticsBase.cpp */, + A26567C9159C21CE00398539 /* Diagnostics.h */, + A26567CA159C21CE00398539 /* DirectiveHandlerBase.cpp */, + A26567CB159C21CE00398539 /* DirectiveHandler.h */, + A26567CC159C21CE00398539 /* DirectiveParser.cpp */, + A26567CD159C21CE00398539 /* DirectiveParser.h */, + A26567CE159C21CE00398539 /* ExpressionParser.cpp */, + A26567CF159C21CE00398539 /* ExpressionParser.h */, + A26567D2159C21CE00398539 /* Input.cpp */, + A26567D3159C21CE00398539 /* Input.h */, + A26567D4159C21CE00398539 /* Lexer.cpp */, + A26567D5159C21CE00398539 /* Lexer.h */, + A26567D6159C21CE00398539 /* Macro.cpp */, + A26567D7159C21CE00398539 /* Macro.h */, + A26567D8159C21CE00398539 /* MacroExpander.cpp */, + A26567D9159C21CE00398539 /* MacroExpander.h */, + A26567E0159C21CE00398539 /* Preprocessor.cpp */, + A26567E1159C21CE00398539 /* Preprocessor.h */, + A26567E2159C21CE00398539 /* SourceLocation.h */, + A26567E4159C21CE00398539 /* Token.cpp */, + A26567E5159C21CE00398539 /* Token.h */, + A26567E7159C21CE00398539 /* Tokenizer.cpp */, + A26567E8159C21CE00398539 /* Tokenizer.h */, + ); + path = new; + sourceTree = "<group>"; + }; + A265682C159C23E100398539 /* depgraph */ = { + isa = PBXGroup; + children = ( + A265682D159C23E100398539 /* DependencyGraph.cpp */, + A265682E159C23E100398539 /* DependencyGraph.h */, + A265682F159C23E100398539 /* DependencyGraphBuilder.cpp */, + A2656830159C23E100398539 /* DependencyGraphBuilder.h */, + A2656831159C23E100398539 /* DependencyGraphOutput.cpp */, + A2656832159C23E100398539 /* DependencyGraphOutput.h */, + A2656833159C23E100398539 /* DependencyGraphTraverse.cpp */, + ); + path = depgraph; + sourceTree = "<group>"; + }; + A2656834159C23E100398539 /* timing */ = { + isa = PBXGroup; + children = ( + A2656835159C23E100398539 /* RestrictFragmentShaderTiming.cpp */, + A2656836159C23E100398539 /* RestrictFragmentShaderTiming.h */, + A2656837159C23E100398539 /* RestrictVertexShaderTiming.cpp */, + A2656838159C23E100398539 /* RestrictVertexShaderTiming.h */, + ); + path = timing; + sourceTree = "<group>"; + }; FB39D06E1200ED9200088E69 = { isa = PBXGroup; children = ( @@ -268,8 +405,8 @@ FB39D0841200EDEB00088E69 /* Source */ = { isa = PBXGroup; children = ( - FB39D2BD1200F3E600088E69 /* GLSLANG */, FB39D1851200F26200088E69 /* compiler */, + FB39D2BD1200F3E600088E69 /* GLSLANG */, ); name = Source; sourceTree = "<group>"; @@ -292,6 +429,8 @@ FB39D18A1200F26200088E69 /* ConstantUnion.h */, FB39D18B1200F26200088E69 /* debug.cpp */, FB39D18C1200F26200088E69 /* debug.h */, + A26567AE159C21B100398539 /* DetectDiscontinuity.cpp */, + A26567AF159C21B100398539 /* DetectDiscontinuity.h */, FB39D18F1200F26200088E69 /* InfoSink.cpp */, FB39D1901200F26200088E69 /* InfoSink.h */, FB39D1911200F26200088E69 /* Initialize.cpp */, @@ -327,15 +466,13 @@ FB39D1C01200F26200088E69 /* ShHandle.h */, FB39D1C11200F26200088E69 /* SymbolTable.cpp */, FB39D1C21200F26200088E69 /* SymbolTable.h */, - FB39D1CB1200F26200088E69 /* translator_common.vcproj */, - FB39D1CC1200F26200088E69 /* translator_hlsl.vcproj */, FB39D1CD1200F26200088E69 /* TranslatorGLSL.cpp */, FB39D1CE1200F26200088E69 /* TranslatorGLSL.h */, FB39D1CF1200F26200088E69 /* TranslatorHLSL.cpp */, FB39D1D01200F26200088E69 /* TranslatorHLSL.h */, FB39D1D11200F26200088E69 /* Types.h */, - FB39D1D21200F26200088E69 /* UnfoldSelect.cpp */, - FB39D1D31200F26200088E69 /* UnfoldSelect.h */, + A26567B7159C21B100398539 /* UnfoldShortCircuit.cpp */, + A26567B8159C21B100398539 /* UnfoldShortCircuit.h */, ); includeInIndex = 0; name = compiler; @@ -370,17 +507,6 @@ FB39D2201200F35A00088E69 /* compiler */ = { isa = PBXGroup; children = ( - A0AABE3213AFE84700F2EBD1 /* OutputGLSLBase.cpp */, - A0AABE3313AFE84700F2EBD1 /* OutputGLSLBase.h */, - A0AABE4613AFE96100F2EBD1 /* TranslatorESSL.cpp */, - A0AABE4713AFE96100F2EBD1 /* TranslatorESSL.h */, - A0AABE4213AFE94500F2EBD1 /* OutputESSL.cpp */, - A0AABE4313AFE94500F2EBD1 /* OutputESSL.h */, - A0AABE2E13AFE83000F2EBD1 /* MapLongVariableNames.cpp */, - A0AABE2F13AFE83000F2EBD1 /* MapLongVariableNames.h */, - A0AABE2A13AFE81000F2EBD1 /* ForLoopUnroll.cpp */, - A0AABE2B13AFE81000F2EBD1 /* ForLoopUnroll.h */, - FB39D2441200F35A00088E69 /* preprocessor */, FB39D2211200F35A00088E69 /* BaseTypes.h */, 49951C0514B7AAD70060E96E /* BuiltInFunctionEmulator.cpp */, 49951C0614B7AAD80060E96E /* BuiltInFunctionEmulator.h */, @@ -390,13 +516,20 @@ FB39D2251200F35A00088E69 /* ConstantUnion.h */, FB39D2261200F35A00088E69 /* debug.cpp */, FB39D2271200F35A00088E69 /* debug.h */, + A265682C159C23E100398539 /* depgraph */, 49951C0714B7AAD80060E96E /* DetectRecursion.cpp */, 49951C0814B7AAD80060E96E /* DetectRecursion.h */, + A26567B0159C21B100398539 /* Diagnostics.cpp */, + A26567B1159C21B100398539 /* Diagnostics.h */, + A26567B2159C21B100398539 /* DirectiveHandler.cpp */, + A26567B3159C21B100398539 /* DirectiveHandler.h */, 90D9B0FA12E11DCB002D4255 /* ExtensionBehavior.h */, + A0AABE2A13AFE81000F2EBD1 /* ForLoopUnroll.cpp */, + A0AABE2B13AFE81000F2EBD1 /* ForLoopUnroll.h */, + 90D9B0FE12E11DCB002D4255 /* glslang.h */, 90D9B0FB12E11DCB002D4255 /* glslang_lex.cpp */, 90D9B0FC12E11DCB002D4255 /* glslang_tab.cpp */, 90D9B0FD12E11DCB002D4255 /* glslang_tab.h */, - 90D9B0FE12E11DCB002D4255 /* glslang.h */, FB39D22A1200F35A00088E69 /* InfoSink.cpp */, FB39D22B1200F35A00088E69 /* InfoSink.h */, FB39D22C1200F35A00088E69 /* Initialize.cpp */, @@ -404,39 +537,50 @@ FB39D22E1200F35A00088E69 /* InitializeDll.cpp */, FB39D22F1200F35A00088E69 /* InitializeDll.h */, FB39D2301200F35A00088E69 /* InitializeGlobals.h */, + A26567B4159C21B100398539 /* InitializeParseContext.cpp */, FB39D2311200F35A00088E69 /* InitializeParseContext.h */, FB39D2321200F35A00088E69 /* Intermediate.cpp */, FB39D2331200F35A00088E69 /* intermediate.h */, FB39D2341200F35A00088E69 /* intermOut.cpp */, FB39D2351200F35A00088E69 /* IntermTraverse.cpp */, FB39D2361200F35A00088E69 /* localintermediate.h */, + A0AABE2E13AFE83000F2EBD1 /* MapLongVariableNames.cpp */, + A0AABE2F13AFE83000F2EBD1 /* MapLongVariableNames.h */, FB39D2371200F35A00088E69 /* MMap.h */, FB39D2381200F35A00088E69 /* osinclude.h */, 90D9B0FF12E11DCB002D4255 /* ossource_nspr.cpp */, FB39D2391200F35A00088E69 /* ossource_posix.cpp */, FB39D23A1200F35A00088E69 /* ossource_win.cpp */, + A0AABE4213AFE94500F2EBD1 /* OutputESSL.cpp */, + A0AABE4313AFE94500F2EBD1 /* OutputESSL.h */, FB39D23B1200F35A00088E69 /* OutputGLSL.cpp */, FB39D23C1200F35A00088E69 /* OutputGLSL.h */, + A0AABE3213AFE84700F2EBD1 /* OutputGLSLBase.cpp */, + A0AABE3313AFE84700F2EBD1 /* OutputGLSLBase.h */, FB39D23F1200F35A00088E69 /* parseConst.cpp */, FB39D2401200F35A00088E69 /* ParseHelper.cpp */, FB39D2411200F35A00088E69 /* ParseHelper.h */, FB39D2421200F35A00088E69 /* PoolAlloc.cpp */, FB39D2431200F35A00088E69 /* PoolAlloc.h */, + A26567B5159C21B100398539 /* Pragma.h */, + FB39D2441200F35A00088E69 /* preprocessor */, FB39D2561200F35A00088E69 /* QualifierAlive.cpp */, FB39D2571200F35A00088E69 /* QualifierAlive.h */, FB39D2581200F35A00088E69 /* RemoveTree.cpp */, FB39D2591200F35A00088E69 /* RemoveTree.h */, + A26567B6159C21B100398539 /* RenameFunction.h */, 90D9B10012E11DCB002D4255 /* SearchSymbol.cpp */, 90D9B10112E11DCB002D4255 /* SearchSymbol.h */, FB39D25A1200F35A00088E69 /* ShaderLang.cpp */, FB39D25B1200F35A00088E69 /* ShHandle.h */, FB39D25C1200F35A00088E69 /* SymbolTable.cpp */, FB39D25D1200F35A00088E69 /* SymbolTable.h */, + A2656834159C23E100398539 /* timing */, + A0AABE4613AFE96100F2EBD1 /* TranslatorESSL.cpp */, + A0AABE4713AFE96100F2EBD1 /* TranslatorESSL.h */, FB39D2681200F35A00088E69 /* TranslatorGLSL.cpp */, FB39D2691200F35A00088E69 /* TranslatorGLSL.h */, FB39D26C1200F35A00088E69 /* Types.h */, - FB39D26D1200F35A00088E69 /* UnfoldSelect.cpp */, - FB39D26E1200F35A00088E69 /* UnfoldSelect.h */, 90D9B10B12E11DD6002D4255 /* util.cpp */, 90D9B10C12E11DD6002D4255 /* util.h */, 90D9B10D12E11DD6002D4255 /* ValidateLimitations.cpp */, @@ -453,6 +597,7 @@ FB39D2441200F35A00088E69 /* preprocessor */ = { isa = PBXGroup; children = ( + A26567C5159C21CE00398539 /* new */, FB39D2451200F35A00088E69 /* atom.c */, FB39D2461200F35A00088E69 /* atom.h */, FB39D2471200F35A00088E69 /* compile.h */, @@ -508,6 +653,28 @@ 49951C0314B7AAB30060E96E /* length_limits.h in Headers */, 49951C0A14B7AAD80060E96E /* BuiltInFunctionEmulator.h in Headers */, 49951C0C14B7AAD80060E96E /* DetectRecursion.h in Headers */, + A26567BC159C21B100398539 /* Diagnostics.h in Headers */, + A26567BE159C21B100398539 /* DirectiveHandler.h in Headers */, + A26567C0159C21B100398539 /* Pragma.h in Headers */, + A26567C1159C21B100398539 /* RenameFunction.h in Headers */, + A26567ED159C21CE00398539 /* Diagnostics.h in Headers */, + A26567EF159C21CE00398539 /* DirectiveHandler.h in Headers */, + A26567F1159C21CE00398539 /* DirectiveParser.h in Headers */, + A26567F3159C21CE00398539 /* ExpressionParser.h in Headers */, + A26567F6159C21CE00398539 /* Input.h in Headers */, + A26567F8159C21CE00398539 /* Lexer.h in Headers */, + A26567FA159C21CE00398539 /* Macro.h in Headers */, + A26567FC159C21CE00398539 /* MacroExpander.h in Headers */, + A2656804159C21CE00398539 /* Preprocessor.h in Headers */, + A2656805159C21CE00398539 /* SourceLocation.h in Headers */, + A2656808159C21CE00398539 /* Token.h in Headers */, + A265680B159C21CE00398539 /* Tokenizer.h in Headers */, + A265682B159C238800398539 /* pp_utils.h in Headers */, + A265683A159C23E100398539 /* DependencyGraph.h in Headers */, + A265683C159C23E100398539 /* DependencyGraphBuilder.h in Headers */, + A265683E159C23E100398539 /* DependencyGraphOutput.h in Headers */, + A2656841159C23E100398539 /* RestrictFragmentShaderTiming.h in Headers */, + A2656843159C23E100398539 /* RestrictVertexShaderTiming.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -588,7 +755,6 @@ FB39D2A81200F35A00088E69 /* ShaderLang.cpp in Sources */, FB39D2AA1200F35A00088E69 /* SymbolTable.cpp in Sources */, FB39D2AC1200F35A00088E69 /* TranslatorGLSL.cpp in Sources */, - FB39D2B11200F35A00088E69 /* UnfoldSelect.cpp in Sources */, 90D9B10212E11DCB002D4255 /* Compiler.cpp in Sources */, 90D9B10412E11DCB002D4255 /* glslang_lex.cpp in Sources */, 90D9B10512E11DCB002D4255 /* glslang_tab.cpp in Sources */, @@ -604,6 +770,26 @@ A0AABE4813AFE96100F2EBD1 /* TranslatorESSL.cpp in Sources */, 49951C0914B7AAD80060E96E /* BuiltInFunctionEmulator.cpp in Sources */, 49951C0B14B7AAD80060E96E /* DetectRecursion.cpp in Sources */, + A26567BB159C21B100398539 /* Diagnostics.cpp in Sources */, + A26567BD159C21B100398539 /* DirectiveHandler.cpp in Sources */, + A26567BF159C21B100398539 /* InitializeParseContext.cpp in Sources */, + A26567EC159C21CE00398539 /* DiagnosticsBase.cpp in Sources */, + A26567EE159C21CE00398539 /* DirectiveHandlerBase.cpp in Sources */, + A26567F0159C21CE00398539 /* DirectiveParser.cpp in Sources */, + A26567F2159C21CE00398539 /* ExpressionParser.cpp in Sources */, + A26567F5159C21CE00398539 /* Input.cpp in Sources */, + A26567F7159C21CE00398539 /* Lexer.cpp in Sources */, + A26567F9159C21CE00398539 /* Macro.cpp in Sources */, + A26567FB159C21CE00398539 /* MacroExpander.cpp in Sources */, + A2656803159C21CE00398539 /* Preprocessor.cpp in Sources */, + A2656807159C21CE00398539 /* Token.cpp in Sources */, + A265680A159C21CE00398539 /* Tokenizer.cpp in Sources */, + A2656839159C23E100398539 /* DependencyGraph.cpp in Sources */, + A265683B159C23E100398539 /* DependencyGraphBuilder.cpp in Sources */, + A265683D159C23E100398539 /* DependencyGraphOutput.cpp in Sources */, + A265683F159C23E100398539 /* DependencyGraphTraverse.cpp in Sources */, + A2656840159C23E100398539 /* RestrictFragmentShaderTiming.cpp in Sources */, + A2656842159C23E100398539 /* RestrictVertexShaderTiming.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Source/ThirdParty/ANGLE/ChangeLog b/Source/ThirdParty/ANGLE/ChangeLog index 863605261..8e82c8474 100644 --- a/Source/ThirdParty/ANGLE/ChangeLog +++ b/Source/ThirdParty/ANGLE/ChangeLog @@ -1,3 +1,925 @@ +2012-07-18 Kristóf Kosztyó <kkristof@inf.u-szeged.hu> + + [Qt] Buildfix after r122870. + https://bugs.webkit.org/show_bug.cgi?id=89039 + + Reviewed by Csaba Osztrogonác + + * src/compiler/preprocessor/new/MacroExpander.cpp: + (pp::MacroExpander::ungetToken): + +2012-07-17 Max Vujovic <mvujovic@adobe.com> + + Update ANGLE in WebKit + https://bugs.webkit.org/show_bug.cgi?id=89039 + + Reviewed by Dean Jackson and Mark Rowe. + + Update ANGLE to r1170, with the following modifications: + + (1) Use Bison 2.3 instead of Bison 2.4.2 to generate ExpressionParser.cpp and + glslang_tab.cpp. I had to modify ExpressionParser.y to make it compatible with Bison + 2.3. The changes have been contributed back to ANGLE in r1224. + + (2) Continue to recognize QNX as POSIX in ANGLE. This has been contributed back to ANGLE + in r1223. + + (3) Rename ANGLE/src/compiler/preprocessor/new/Diagnostic.cpp to DiagnosticBase.cpp. + Rename ANGLE/src/compiler/preprocessor/new/DirectiveHandler.cpp to DirectiveHandlerBase.cpp. + + With the introduction of ANGLE's new preprocessor, there were two files named Diagnostic.cpp + in ANGLE under different folders. This caused problems on the QT build when their object + files, both named Diagnostic.o, tried to go in the same folder. Renaming one of them to + DiagnosticBase.cpp avoids this conflict. The same situation occurred with + DirectiveHandler.cpp. I will work on contributing this change back to ANGLE for future + updates. + + (4) Add the following lines to glslang.y and ExpressionParser.y: + #define YYENABLE_NLS 0 + #define YYLTYPE_IS_TRIVIAL 1 + + Bison 2.3 doesn't first check that these macros are defined before reading their value, + which causes the QT build to fail. + + We work around this issue in the same way in CSSGrammar.y. + + I will work on contributing this change back to ANGLE. + + * ANGLE.xcodeproj/project.pbxproj: + * include/GLES2/gl2ext.h: + * include/GLSLANG/ShaderLang.h: + * src/build_angle.xcodeproj/project.pbxproj: + * src/common/angleutils.h: + * src/common/debug.cpp: + (gl): + (gl::output): + (gl::trace): + (gl::perfActive): + (gl::ScopedPerfEventHelper::ScopedPerfEventHelper): + (gl::ScopedPerfEventHelper::~ScopedPerfEventHelper): + * src/common/version.h: + * src/compiler/BuiltInFunctionEmulator.cpp: + (BuiltInFunctionEmulator::IdentifyFunction): + * src/compiler/BuiltInFunctionEmulator.h: + * src/compiler/Compiler.cpp: + (isWebGLBasedSpec): + (TCompiler::compile): + (TCompiler::rewriteCSSShader): + (TCompiler::enforceTimingRestrictions): + (TCompiler::enforceFragmentShaderTimingRestrictions): + (TCompiler::enforceVertexShaderTimingRestrictions): + * src/compiler/DetectDiscontinuity.cpp: Added. + (sh::DetectLoopDiscontinuity::traverse): + (sh): + (sh::DetectLoopDiscontinuity::visitBranch): + (sh::DetectLoopDiscontinuity::visitAggregate): + (sh::containsLoopDiscontinuity): + (sh::DetectGradientOperation::traverse): + (sh::DetectGradientOperation::visitUnary): + (sh::DetectGradientOperation::visitAggregate): + (sh::containsGradientOperation): + * src/compiler/DetectDiscontinuity.h: Added. + (sh): + (DetectLoopDiscontinuity): + (DetectGradientOperation): + * src/compiler/Diagnostics.cpp: Added. + (TDiagnostics::TDiagnostics): + (TDiagnostics::~TDiagnostics): + (TDiagnostics::writeInfo): + (TDiagnostics::writeDebug): + (TDiagnostics::print): + * src/compiler/Diagnostics.h: Added. + (TDiagnostics): + (TDiagnostics::infoSink): + * src/compiler/DirectiveHandler.cpp: Added. + (getBehavior): + (TDirectiveHandler::TDirectiveHandler): + (TDirectiveHandler::~TDirectiveHandler): + (TDirectiveHandler::handleError): + (TDirectiveHandler::handlePragma): + (TDirectiveHandler::handleExtension): + (TDirectiveHandler::handleVersion): + * src/compiler/DirectiveHandler.h: Added. + (TDirectiveHandler): + (TDirectiveHandler::pragma): + (TDirectiveHandler::extensionBehavior): + * src/compiler/ExtensionBehavior.h: + (getBehaviorString): + * src/compiler/Initialize.cpp: + (BuiltInConstants): + (TBuiltIns::initialize): + (IdentifyBuiltIns): + * src/compiler/InitializeParseContext.cpp: Added. + (InitializeParseContextIndex): + (FreeParseContextIndex): + (InitializeGlobalParseContext): + (FreeParseContext): + (GetGlobalParseContext): + * src/compiler/InitializeParseContext.h: + (TThreadParseContextRec): + * src/compiler/Intermediate.cpp: + (TIntermediate::addSelection): + * src/compiler/MapLongVariableNames.cpp: + * src/compiler/OutputHLSL.cpp: + (sh::str): + (sh::OutputHLSL::OutputHLSL): + (sh::OutputHLSL::~OutputHLSL): + (sh::OutputHLSL::output): + (sh::OutputHLSL::header): + (sh::OutputHLSL::visitBinary): + (sh::OutputHLSL::visitUnary): + (sh::OutputHLSL::visitAggregate): + (sh::OutputHLSL::visitSelection): + (sh::OutputHLSL::visitLoop): + (sh::OutputHLSL::traverseStatements): + (sh): + (sh::OutputHLSL::handleExcessiveLoop): + (sh::OutputHLSL::typeString): + (sh::OutputHLSL::addConstructor): + (sh::OutputHLSL::decorateField): + * src/compiler/OutputHLSL.h: + (sh): + (OutputHLSL): + * src/compiler/ParseHelper.cpp: + (TParseContext::parseVectorFields): + (TParseContext::parseMatrixFields): + (TParseContext::error): + (TParseContext::warning): + (TParseContext::trace): + (TParseContext::assignError): + (TParseContext::unaryOpError): + (TParseContext::binaryOpError): + (TParseContext::precisionErrorCheck): + (TParseContext::lValueErrorCheck): + (TParseContext::constErrorCheck): + (TParseContext::integerErrorCheck): + (TParseContext::globalErrorCheck): + (TParseContext::reservedErrorCheck): + (TParseContext::constructorErrorCheck): + (TParseContext::voidErrorCheck): + (TParseContext::boolErrorCheck): + (TParseContext::samplerErrorCheck): + (TParseContext::structQualifierErrorCheck): + (TParseContext::parameterSamplerErrorCheck): + (TParseContext::arraySizeErrorCheck): + (TParseContext::arrayQualifierErrorCheck): + (TParseContext::arrayTypeErrorCheck): + (TParseContext::arrayErrorCheck): + (TParseContext::arraySetMaxSize): + (TParseContext::nonInitConstErrorCheck): + (TParseContext::nonInitErrorCheck): + (TParseContext::paramErrorCheck): + (TParseContext::extensionErrorCheck): + (TParseContext::supportsExtension): + (TParseContext::handleExtensionDirective): + (TParseContext::handlePragmaDirective): + (TParseContext::findFunction): + (TParseContext::executeInitializer): + (TParseContext::constructBuiltIn): + (TParseContext::constructStruct): + (TParseContext::addConstVectorNode): + (TParseContext::addConstMatrixNode): + (TParseContext::addConstArrayNode): + (TParseContext::addConstStruct): + (TParseContext::enterStructDeclaration): + (TParseContext::structNestingErrorCheck): + (PaParseStrings): + * src/compiler/ParseHelper.h: + (TParseContext::TParseContext): + (TParseContext): + (TParseContext::infoSink): + (TParseContext::extensionBehavior): + (TParseContext::pragma): + * src/compiler/PoolAlloc.cpp: + (TAllocation::checkGuardBlock): + * src/compiler/Pragma.h: Added. + (TPragma): + (TPragma::TPragma): + * src/compiler/RenameFunction.h: Added. + (RenameFunction): + (RenameFunction::RenameFunction): + (RenameFunction::visitAggregate): + * src/compiler/ShHandle.h: + (TCompiler): + * src/compiler/ShaderLang.cpp: + (getVariableInfo): + * src/compiler/SymbolTable.cpp: + (TType::buildMangledName): + * src/compiler/TranslatorHLSL.cpp: + * src/compiler/UnfoldSelect.cpp: Removed. + * src/compiler/UnfoldSelect.h: Removed. + * src/compiler/UnfoldShortCircuit.cpp: Added. + (sh::UnfoldShortCircuit::UnfoldShortCircuit): + (sh): + (sh::UnfoldShortCircuit::traverse): + (sh::UnfoldShortCircuit::visitBinary): + (sh::UnfoldShortCircuit::visitSelection): + (sh::UnfoldShortCircuit::visitLoop): + (sh::UnfoldShortCircuit::getNextTemporaryIndex): + * src/compiler/UnfoldShortCircuit.h: Added. + (sh): + (UnfoldShortCircuit): + * src/compiler/ValidateLimitations.cpp: + * src/compiler/debug.cpp: + * src/compiler/depgraph: Added. + * src/compiler/depgraph/DependencyGraph.cpp: Added. + (TDependencyGraph::TDependencyGraph): + (TDependencyGraph::~TDependencyGraph): + (TDependencyGraph::createArgument): + (TDependencyGraph::createFunctionCall): + (TDependencyGraph::getOrCreateSymbol): + (TDependencyGraph::createSelection): + (TDependencyGraph::createLoop): + (TDependencyGraph::createLogicalOp): + (TGraphLogicalOp::getOpString): + * src/compiler/depgraph/DependencyGraph.h: Added. + (TGraphNode): + (TGraphNode::TGraphNode): + (TGraphNode::~TGraphNode): + (TGraphParentNode): + (TGraphParentNode::TGraphParentNode): + (TGraphParentNode::~TGraphParentNode): + (TGraphParentNode::addDependentNode): + (TGraphArgument): + (TGraphArgument::TGraphArgument): + (TGraphArgument::~TGraphArgument): + (TGraphArgument::getIntermFunctionCall): + (TGraphArgument::getArgumentNumber): + (TGraphFunctionCall): + (TGraphFunctionCall::TGraphFunctionCall): + (TGraphFunctionCall::~TGraphFunctionCall): + (TGraphFunctionCall::getIntermFunctionCall): + (TGraphSymbol): + (TGraphSymbol::TGraphSymbol): + (TGraphSymbol::~TGraphSymbol): + (TGraphSymbol::getIntermSymbol): + (TGraphSelection): + (TGraphSelection::TGraphSelection): + (TGraphSelection::~TGraphSelection): + (TGraphSelection::getIntermSelection): + (TGraphLoop): + (TGraphLoop::TGraphLoop): + (TGraphLoop::~TGraphLoop): + (TGraphLoop::getIntermLoop): + (TGraphLogicalOp): + (TGraphLogicalOp::TGraphLogicalOp): + (TGraphLogicalOp::~TGraphLogicalOp): + (TGraphLogicalOp::getIntermLogicalOp): + (TDependencyGraph): + (TDependencyGraph::begin): + (TDependencyGraph::end): + (TDependencyGraph::beginSamplerSymbols): + (TDependencyGraph::endSamplerSymbols): + (TDependencyGraph::beginUserDefinedFunctionCalls): + (TDependencyGraph::endUserDefinedFunctionCalls): + (TDependencyGraphTraverser): + (TDependencyGraphTraverser::TDependencyGraphTraverser): + (TDependencyGraphTraverser::visitSymbol): + (TDependencyGraphTraverser::visitArgument): + (TDependencyGraphTraverser::visitFunctionCall): + (TDependencyGraphTraverser::visitSelection): + (TDependencyGraphTraverser::visitLoop): + (TDependencyGraphTraverser::visitLogicalOp): + (TDependencyGraphTraverser::getDepth): + (TDependencyGraphTraverser::incrementDepth): + (TDependencyGraphTraverser::decrementDepth): + (TDependencyGraphTraverser::clearVisited): + (TDependencyGraphTraverser::markVisited): + (TDependencyGraphTraverser::isVisited): + * src/compiler/depgraph/DependencyGraphBuilder.cpp: Added. + (TDependencyGraphBuilder::build): + (TDependencyGraphBuilder::visitAggregate): + (TDependencyGraphBuilder::visitFunctionDefinition): + (TDependencyGraphBuilder::visitFunctionCall): + (TDependencyGraphBuilder::visitAggregateChildren): + (TDependencyGraphBuilder::visitSymbol): + (TDependencyGraphBuilder::visitBinary): + (TDependencyGraphBuilder::visitAssignment): + (TDependencyGraphBuilder::visitLogicalOp): + (TDependencyGraphBuilder::visitBinaryChildren): + (TDependencyGraphBuilder::visitSelection): + (TDependencyGraphBuilder::visitLoop): + (TDependencyGraphBuilder::connectMultipleNodesToSingleNode): + * src/compiler/depgraph/DependencyGraphBuilder.h: Added. + (TDependencyGraphBuilder): + (TNodeSetStack): + (TDependencyGraphBuilder::TNodeSetStack::TNodeSetStack): + (TDependencyGraphBuilder::TNodeSetStack::~TNodeSetStack): + (TDependencyGraphBuilder::TNodeSetStack::getTopSet): + (TDependencyGraphBuilder::TNodeSetStack::pushSet): + (TDependencyGraphBuilder::TNodeSetStack::popSet): + (TDependencyGraphBuilder::TNodeSetStack::popSetIntoNext): + (TDependencyGraphBuilder::TNodeSetStack::insertIntoTopSet): + (TDependencyGraphBuilder::TNodeSetStack::clear): + (TNodeSetMaintainer): + (TDependencyGraphBuilder::TNodeSetMaintainer::TNodeSetMaintainer): + (TDependencyGraphBuilder::TNodeSetMaintainer::~TNodeSetMaintainer): + (TNodeSetPropagatingMaintainer): + (TDependencyGraphBuilder::TNodeSetPropagatingMaintainer::TNodeSetPropagatingMaintainer): + (TDependencyGraphBuilder::TNodeSetPropagatingMaintainer::~TNodeSetPropagatingMaintainer): + (TLeftmostSymbolMaintainer): + (TDependencyGraphBuilder::TLeftmostSymbolMaintainer::TLeftmostSymbolMaintainer): + (TDependencyGraphBuilder::TLeftmostSymbolMaintainer::~TLeftmostSymbolMaintainer): + (TDependencyGraphBuilder::TDependencyGraphBuilder): + (TDependencyGraphBuilder::build): + * src/compiler/depgraph/DependencyGraphOutput.cpp: Added. + (TDependencyGraphOutput::outputIndentation): + (TDependencyGraphOutput::visitArgument): + (TDependencyGraphOutput::visitFunctionCall): + (TDependencyGraphOutput::visitSymbol): + (TDependencyGraphOutput::visitSelection): + (TDependencyGraphOutput::visitLoop): + (TDependencyGraphOutput::visitLogicalOp): + (TDependencyGraphOutput::outputAllSpanningTrees): + * src/compiler/depgraph/DependencyGraphOutput.h: Added. + (TDependencyGraphOutput): + (TDependencyGraphOutput::TDependencyGraphOutput): + * src/compiler/depgraph/DependencyGraphTraverse.cpp: Added. + (TGraphNode::traverse): + (TGraphParentNode::traverse): + (TGraphArgument::traverse): + (TGraphFunctionCall::traverse): + (TGraphSymbol::traverse): + (TGraphSelection::traverse): + (TGraphLoop::traverse): + (TGraphLogicalOp::traverse): + * src/compiler/glslang.h: + * src/compiler/glslang.l: + * src/compiler/glslang.y: + * src/compiler/glslang_lex.cpp: + (yy_buffer_state): + (yyguts_t): + (yy_get_previous_state): + (yy_try_NUL_trans): + (input): + (yyensure_buffer_stack): + (yy_scan_bytes): + (yyget_leng): + (string_input): + (yyerror): + (glslang_finalize): + (glslang_scan): + * src/compiler/glslang_tab.cpp: + * src/compiler/intermediate.h: + (TIntermAggregate::TIntermAggregate): + (TIntermAggregate::~TIntermAggregate): + (TIntermAggregate::isUserDefined): + (TIntermAggregate): + (TIntermTraverser::~TIntermTraverser): + * src/compiler/osinclude.h: + * src/compiler/preprocessor/atom.c: + (FindHashLoc): + (PrintAtomTable): + * src/compiler/preprocessor/cpp.c: + (CPPpragma): + (readCPPline): + (PredefineIntMacro): + (MacroExpand): + * src/compiler/preprocessor/cpp.h: + * src/compiler/preprocessor/memory.h: + * src/compiler/preprocessor/new: Added properties allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs, allow-tabs and allow-tabs. + * src/compiler/preprocessor/new/Context.cpp: Removed. + * src/compiler/preprocessor/new/Context.h: Removed. + * src/compiler/preprocessor/new/Diagnostics.h: Added. + (pp): + (Diagnostics): + * src/compiler/preprocessor/new/DiagnosticsBase.cpp: Added. + (pp): + (pp::Diagnostics::~Diagnostics): + (pp::Diagnostics::report): + (pp::Diagnostics::severity): + * src/compiler/preprocessor/new/DirectiveHandler.h: Added. + (pp): + (DirectiveHandler): + * src/compiler/preprocessor/new/DirectiveHandlerBase.cpp: Added. + (pp): + (pp::DirectiveHandler::~DirectiveHandler): + * src/compiler/preprocessor/new/DirectiveParser.cpp: Added. + (getDirective): + (isConditionalDirective): + (isEOD): + (skipUntilEOD): + (isMacroNameReserved): + (isMacroPredefined): + (pp): + (DefinedParser): + (pp::DefinedParser::DefinedParser): + (pp::DefinedParser::lex): + (pp::DirectiveParser::DirectiveParser): + (pp::DirectiveParser::lex): + (pp::DirectiveParser::parseDirective): + (pp::DirectiveParser::parseDefine): + (pp::DirectiveParser::parseUndef): + (pp::DirectiveParser::parseIf): + (pp::DirectiveParser::parseIfdef): + (pp::DirectiveParser::parseIfndef): + (pp::DirectiveParser::parseElse): + (pp::DirectiveParser::parseElif): + (pp::DirectiveParser::parseEndif): + (pp::DirectiveParser::parseError): + (pp::DirectiveParser::parsePragma): + (pp::DirectiveParser::parseExtension): + (pp::DirectiveParser::parseVersion): + (pp::DirectiveParser::parseLine): + (pp::DirectiveParser::skipping): + (pp::DirectiveParser::parseConditionalIf): + (pp::DirectiveParser::parseExpressionIf): + (pp::DirectiveParser::parseExpressionIfdef): + * src/compiler/preprocessor/new/DirectiveParser.h: Added. + (pp): + (DirectiveParser): + (ConditionalBlock): + (pp::DirectiveParser::ConditionalBlock::ConditionalBlock): + * src/compiler/preprocessor/new/ExpressionParser.cpp: Added. + (yysyntax_error): + (yylex): + (yyerror): + (pp): + (pp::ExpressionParser::ExpressionParser): + (pp::ExpressionParser::parse): + * src/compiler/preprocessor/new/ExpressionParser.h: Added. + (pp): + (ExpressionParser): + * src/compiler/preprocessor/new/ExpressionParser.y: Added. + * src/compiler/preprocessor/new/Input.cpp: Added property allow-tabs. + (pp::Input::Input): + (pp::Input::read): + * src/compiler/preprocessor/new/Input.h: Added property allow-tabs. + (pp): + (Input): + (pp::Input::count): + (pp::Input::string): + (pp::Input::length): + (Location): + (pp::Input::Location::Location): + (pp::Input::readLoc): + * src/compiler/preprocessor/new/Lexer.cpp: Added. + (pp): + (pp::Lexer::~Lexer): + * src/compiler/preprocessor/new/Lexer.h: Added. + (pp): + (Lexer): + * src/compiler/preprocessor/new/Macro.cpp: Added property allow-tabs. + (pp::Macro::equals): + * src/compiler/preprocessor/new/Macro.h: Added property allow-tabs. + (pp): + (pp::Macro::Macro): + (Macro): + * src/compiler/preprocessor/new/MacroExpander.cpp: Added. + (pp): + (TokenLexer): + (pp::TokenLexer::TokenLexer): + (pp::TokenLexer::lex): + (pp::MacroExpander::MacroExpander): + (pp::MacroExpander::~MacroExpander): + (pp::MacroExpander::lex): + (pp::MacroExpander::getToken): + (pp::MacroExpander::ungetToken): + (pp::MacroExpander::isNextTokenLeftParen): + (pp::MacroExpander::pushMacro): + (pp::MacroExpander::popMacro): + (pp::MacroExpander::expandMacro): + (pp::MacroExpander::collectMacroArgs): + (pp::MacroExpander::replaceMacroParams): + * src/compiler/preprocessor/new/MacroExpander.h: Added. + (pp): + (MacroExpander): + (MacroContext): + (pp::MacroExpander::MacroContext::MacroContext): + (pp::MacroExpander::MacroContext::empty): + (pp::MacroExpander::MacroContext::get): + (pp::MacroExpander::MacroContext::unget): + * src/compiler/preprocessor/new/Preprocessor.cpp: Added property allow-tabs. + (PreprocessorImpl): + (pp::PreprocessorImpl::PreprocessorImpl): + (pp): + (pp::Preprocessor::Preprocessor): + (pp::Preprocessor::~Preprocessor): + (pp::Preprocessor::init): + (pp::Preprocessor::predefineMacro): + (pp::Preprocessor::lex): + * src/compiler/preprocessor/new/Preprocessor.h: Added property allow-tabs. + (pp): + (Preprocessor): + * src/compiler/preprocessor/new/SourceLocation.h: Added. + (pp): + (pp::SourceLocation::SourceLocation): + (SourceLocation): + (pp::SourceLocation::equals): + (pp::operator==): + (pp::operator!=): + * src/compiler/preprocessor/new/Token.cpp: Added property allow-tabs. + (pp::Token::reset): + (pp::Token::equals): + (pp::Token::setAtStartOfLine): + (pp::Token::setHasLeadingSpace): + (pp): + (pp::Token::setExpansionDisabled): + (pp::operator<<): + * src/compiler/preprocessor/new/Token.h: Added property allow-tabs. + (pp::Token::Token): + (Token): + (pp::Token::atStartOfLine): + (pp::Token::hasLeadingSpace): + (pp::Token::expansionDisabled): + (pp::operator==): + (pp): + (pp::operator!=): + * src/compiler/preprocessor/new/Tokenizer.cpp: Added. + (yy_buffer_state): + (yy_trans_info): + (yyguts_t): + (yy_get_previous_state): + (yy_try_NUL_trans): + (input): + (pprestart): + (pp_switch_to_buffer): + (pp_load_buffer_state): + (pp_create_buffer): + (pp_delete_buffer): + (pp_init_buffer): + (pp_flush_buffer): + (pppush_buffer_state): + (pppop_buffer_state): + (ppensure_buffer_stack): + (pp_scan_buffer): + (pp_scan_string): + (pp_scan_bytes): + (yy_fatal_error): + (ppget_extra): + (ppget_lineno): + (ppget_column): + (ppget_in): + (ppget_out): + (ppget_leng): + (ppget_text): + (ppset_extra): + (ppset_lineno): + (ppset_column): + (ppset_in): + (ppset_out): + (ppget_debug): + (ppset_debug): + (ppget_lval): + (ppset_lval): + (ppget_lloc): + (ppset_lloc): + (pplex_init): + (pplex_init_extra): + (yy_init_globals): + (pplex_destroy): + (yy_flex_strncpy): + (yy_flex_strlen): + (ppalloc): + (pprealloc): + (ppfree): + (pp): + (pp::Tokenizer::Tokenizer): + (pp::Tokenizer::~Tokenizer): + (pp::Tokenizer::init): + (pp::Tokenizer::setFileNumber): + (pp::Tokenizer::setLineNumber): + (pp::Tokenizer::lex): + (pp::Tokenizer::initScanner): + (pp::Tokenizer::destroyScanner): + * src/compiler/preprocessor/new/Tokenizer.h: Added. + (pp): + (Tokenizer): + (Context): + * src/compiler/preprocessor/new/Tokenizer.l: Added. + * src/compiler/preprocessor/new/generate_parser.sh: Added property allow-tabs. + * src/compiler/preprocessor/new/pp.l: Removed. + * src/compiler/preprocessor/new/pp.y: Removed. + * src/compiler/preprocessor/new/pp_lex.cpp: Removed. + * src/compiler/preprocessor/new/pp_tab.cpp: Removed. + * src/compiler/preprocessor/new/pp_tab.h: Removed. + * src/compiler/preprocessor/new/pp_utils.h: Added. + * src/compiler/preprocessor/new/preprocessor.vcproj: Added. + * src/compiler/preprocessor/new/stl_utils.h: Removed. + * src/compiler/preprocessor/new/token_type.h: Removed. + * src/compiler/preprocessor/preprocess.h: + * src/compiler/preprocessor/scanner.c: + (InitScannerInput): + * src/compiler/preprocessor/scanner.h: + * src/compiler/preprocessor/symbols.h: + * src/compiler/preprocessor/tokens.c: + (ReadToken): + (DumpTokenStream): + * src/compiler/preprocessor/tokens.h: + * src/compiler/timing: Added. + * src/compiler/timing/RestrictFragmentShaderTiming.cpp: Added. + (RestrictFragmentShaderTiming::RestrictFragmentShaderTiming): + (RestrictFragmentShaderTiming::enforceRestrictions): + (RestrictFragmentShaderTiming::validateUserDefinedFunctionCallUsage): + (RestrictFragmentShaderTiming::beginError): + (RestrictFragmentShaderTiming::isSamplingOp): + (RestrictFragmentShaderTiming::visitArgument): + (RestrictFragmentShaderTiming::visitSelection): + (RestrictFragmentShaderTiming::visitLoop): + (RestrictFragmentShaderTiming::visitLogicalOp): + * src/compiler/timing/RestrictFragmentShaderTiming.h: Added. + (RestrictFragmentShaderTiming): + (RestrictFragmentShaderTiming::numErrors): + * src/compiler/timing/RestrictVertexShaderTiming.cpp: Added. + (RestrictVertexShaderTiming::visitSymbol): + * src/compiler/timing/RestrictVertexShaderTiming.h: Added. + (RestrictVertexShaderTiming): + (RestrictVertexShaderTiming::RestrictVertexShaderTiming): + (RestrictVertexShaderTiming::enforceRestrictions): + (RestrictVertexShaderTiming::numErrors): + * src/libEGL/Display.cpp: + (egl): + (egl::Display::getDepthTextureSupport): + (egl::Display::getTexturePool): + * src/libEGL/Display.h: + (Display): + * src/libEGL/Surface.cpp: + (egl::Surface::Surface): + (egl::Surface::release): + (egl::Surface::resetSwapChain): + (egl::Surface::swapRect): + (egl): + (egl::Surface::swap): + (egl::Surface::postSubBuffer): + * src/libEGL/Surface.h: + (Surface): + * src/libEGL/libEGL.cpp: + * src/libGLESv2/Context.cpp: + (gl::Context::makeCurrent): + (gl::Context::markDxUniformsDirty): + (gl): + (gl::Context::getIntegerv): + (gl::Context::getQueryParameterInfo): + (gl::Context::applyRenderTarget): + (gl::Context::applyState): + (gl::Context::applyShaders): + (gl::Context::applyTextures): + (gl::Context::readPixels): + (gl::Context::clear): + (gl::Context::drawArrays): + (gl::Context::drawElements): + (gl::Context::supportsDepthTextures): + (gl::Context::initExtensionString): + (gl::Context::blitFramebuffer): + (gl::VertexDeclarationCache::applyDeclaration): + * src/libGLESv2/Context.h: + (Context): + * src/libGLESv2/Framebuffer.cpp: + (gl::Framebuffer::~Framebuffer): + (gl): + (gl::Framebuffer::getNullColorbuffer): + (gl::Framebuffer::completeness): + * src/libGLESv2/Framebuffer.h: + (Framebuffer): + * src/libGLESv2/Program.cpp: + (gl): + (gl::AttributeBindings::AttributeBindings): + (gl::AttributeBindings::~AttributeBindings): + (gl::InfoLog::InfoLog): + (gl::InfoLog::~InfoLog): + (gl::InfoLog::getLength): + (gl::InfoLog::getLog): + (gl::InfoLog::appendSanitized): + (gl::InfoLog::append): + (gl::InfoLog::reset): + (gl::Program::Program): + (gl::Program::~Program): + (gl::Program::attachShader): + (gl::Program::detachShader): + (gl::Program::getAttachedShadersCount): + (gl::AttributeBindings::bindAttributeLocation): + (gl::Program::bindAttributeLocation): + (gl::Program::link): + (gl::AttributeBindings::getAttributeBinding): + (gl::Program::unlink): + (gl::Program::getProgramBinary): + (gl::Program::setProgramBinary): + (gl::Program::getInfoLogLength): + (gl::Program::getInfoLog): + (gl::Program::getActiveAttribute): + (gl::Program::getActiveAttributeCount): + (gl::Program::getActiveAttributeMaxLength): + (gl::Program::getActiveUniform): + (gl::Program::getActiveUniformCount): + (gl::Program::getActiveUniformMaxLength): + (gl::Program::validate): + (gl::Program::isValidated): + * src/libGLESv2/Program.h: + (gl): + (AttributeBindings): + (InfoLog): + (Program): + * src/libGLESv2/ProgramBinary.cpp: Added. + (gl::str): + (gl): + (gl::Uniform::Uniform): + (gl::Uniform::~Uniform): + (gl::Uniform::isArray): + (gl::UniformLocation::UniformLocation): + (gl::ProgramBinary::ProgramBinary): + (gl::ProgramBinary::~ProgramBinary): + (gl::ProgramBinary::getPixelShader): + (gl::ProgramBinary::getVertexShader): + (gl::ProgramBinary::getAttributeLocation): + (gl::ProgramBinary::getSemanticIndex): + (gl::ProgramBinary::getUsedSamplerRange): + (gl::ProgramBinary::getSamplerMapping): + (gl::ProgramBinary::getSamplerTextureType): + (gl::ProgramBinary::getUniformLocation): + (gl::ProgramBinary::setUniform1fv): + (gl::ProgramBinary::setUniform2fv): + (gl::ProgramBinary::setUniform3fv): + (gl::ProgramBinary::setUniform4fv): + (gl::transposeMatrix): + (gl::ProgramBinary::setUniformMatrix2fv): + (gl::ProgramBinary::setUniformMatrix3fv): + (gl::ProgramBinary::setUniformMatrix4fv): + (gl::ProgramBinary::setUniform1iv): + (gl::ProgramBinary::setUniform2iv): + (gl::ProgramBinary::setUniform3iv): + (gl::ProgramBinary::setUniform4iv): + (gl::ProgramBinary::getUniformfv): + (gl::ProgramBinary::getUniformiv): + (gl::ProgramBinary::dirtyAllUniforms): + (gl::ProgramBinary::applyUniforms): + (gl::ProgramBinary::compileToBinary): + (gl::ProgramBinary::packVaryings): + (gl::ProgramBinary::linkVaryings): + (gl::ProgramBinary::link): + (gl::ProgramBinary::linkAttributes): + (gl::ProgramBinary::linkUniforms): + (gl::ProgramBinary::defineUniform): + (gl::ProgramBinary::createUniform): + (gl::ProgramBinary::decorateAttribute): + (gl::ProgramBinary::undecorateUniform): + (gl::ProgramBinary::applyUniformnbv): + (gl::ProgramBinary::applyUniformnfv): + (gl::ProgramBinary::applyUniform1iv): + (gl::ProgramBinary::applyUniform2iv): + (gl::ProgramBinary::applyUniform3iv): + (gl::ProgramBinary::applyUniform4iv): + (gl::ProgramBinary::applyUniformniv): + (gl::ProgramBinary::isValidated): + (gl::ProgramBinary::getActiveAttribute): + (gl::ProgramBinary::getActiveAttributeCount): + (gl::ProgramBinary::getActiveAttributeMaxLength): + (gl::ProgramBinary::getActiveUniform): + (gl::ProgramBinary::getActiveUniformCount): + (gl::ProgramBinary::getActiveUniformMaxLength): + (gl::ProgramBinary::validate): + (gl::ProgramBinary::validateSamplers): + (gl::ProgramBinary::getDxDepthRangeLocation): + (gl::ProgramBinary::getDxDepthLocation): + (gl::ProgramBinary::getDxCoordLocation): + (gl::ProgramBinary::getDxHalfPixelSizeLocation): + (gl::ProgramBinary::getDxFrontCCWLocation): + (gl::ProgramBinary::getDxPointsOrLinesLocation): + * src/libGLESv2/ProgramBinary.h: Added. + (gl): + (Uniform): + (gl::Uniform::RegisterInfo::RegisterInfo): + (RegisterInfo): + (gl::Uniform::RegisterInfo::set): + (UniformLocation): + (ProgramBinary): + (Sampler): + * src/libGLESv2/Renderbuffer.cpp: + (gl): + (gl::RenderbufferTexture2D::RenderbufferTexture2D): + (gl::RenderbufferTexture2D::~RenderbufferTexture2D): + (gl::RenderbufferTexture2D::addProxyRef): + (gl::RenderbufferTexture2D::releaseProxy): + (gl::RenderbufferTexture2D::getRenderTarget): + (gl::RenderbufferTexture2D::getDepthStencil): + (gl::RenderbufferTexture2D::getWidth): + (gl::RenderbufferTexture2D::getHeight): + (gl::RenderbufferTexture2D::getInternalFormat): + (gl::RenderbufferTexture2D::getD3DFormat): + (gl::RenderbufferTexture2D::getSamples): + (gl::RenderbufferTexture2D::getSerial): + (gl::RenderbufferTextureCubeMap::RenderbufferTextureCubeMap): + (gl::RenderbufferTextureCubeMap::~RenderbufferTextureCubeMap): + (gl::RenderbufferTextureCubeMap::addProxyRef): + (gl::RenderbufferTextureCubeMap::releaseProxy): + (gl::RenderbufferTextureCubeMap::getRenderTarget): + (gl::RenderbufferTextureCubeMap::getDepthStencil): + (gl::RenderbufferTextureCubeMap::getWidth): + (gl::RenderbufferTextureCubeMap::getHeight): + (gl::RenderbufferTextureCubeMap::getInternalFormat): + (gl::RenderbufferTextureCubeMap::getD3DFormat): + (gl::RenderbufferTextureCubeMap::getSamples): + (gl::RenderbufferTextureCubeMap::getSerial): + (gl::DepthStencilbuffer::getDepthStencil): + * src/libGLESv2/Renderbuffer.h: + (gl): + (RenderbufferTexture2D): + (RenderbufferTextureCubeMap): + * src/libGLESv2/Shader.cpp: + (gl::Shader::getInfoLog): + (gl::Shader::getSourceImpl): + * src/libGLESv2/Shader.h: + (Shader): + (VertexShader): + * src/libGLESv2/Texture.cpp: + (gl::ConvertTextureFormatType): + (gl::IsTextureFormatRenderable): + (gl::GetTextureUsage): + (gl): + (gl::Image::createSurface): + (gl::Image::updateSurface): + (gl::Image::loadData): + (gl::Image::loadAlphaData): + (gl::Image::loadAlphaDataSSE2): + (gl::Image::loadAlphaFloatData): + (gl::Image::loadAlphaHalfFloatData): + (gl::Image::loadLuminanceData): + (gl::Image::loadLuminanceFloatData): + (gl::Image::loadLuminanceHalfFloatData): + (gl::Image::loadLuminanceAlphaData): + (gl::Image::loadLuminanceAlphaFloatData): + (gl::Image::loadLuminanceAlphaHalfFloatData): + (gl::Image::loadRGBUByteData): + (gl::Image::loadRGB565Data): + (gl::Image::loadRGBFloatData): + (gl::Image::loadRGBHalfFloatData): + (gl::Image::loadRGBAUByteDataSSE2): + (gl::Image::loadRGBAUByteData): + (gl::Image::loadRGBA4444Data): + (gl::Image::loadRGBA5551Data): + (gl::Image::loadRGBAFloatData): + (gl::Image::loadRGBAHalfFloatData): + (gl::Image::loadBGRAData): + (gl::Image::loadCompressedData): + (gl::Image::copy): + (gl::TextureStorage::TextureStorage): + (gl::TextureStorage::isRenderTarget): + (gl::TextureStorage::getUsage): + (gl::Texture::setImage): + (gl::Texture::setCompressedImage): + (gl::Texture::subImage): + (gl::Texture::subImageCompressed): + (gl::TextureStorage2D::TextureStorage2D): + (gl::Texture2D::getInternalFormat): + (gl::Texture2D::getD3DFormat): + (gl::Texture2D::copyImage): + (gl::Texture2D::copySubImage): + (gl::Texture2D::storage): + (gl::Texture2D::isSamplerComplete): + (gl::Texture2D::isCompressed): + (gl::Texture2D::isDepth): + (gl::Texture2D::createTexture): + (gl::Texture2D::convertToRenderTarget): + (gl::Texture2D::getRenderbuffer): + (gl::Texture2D::getRenderTarget): + (gl::Texture2D::getDepthStencil): + (gl::TextureStorageCubeMap::TextureStorageCubeMap): + (gl::TextureCubeMap::getWidth): + (gl::TextureCubeMap::getHeight): + (gl::TextureCubeMap::getInternalFormat): + (gl::TextureCubeMap::getD3DFormat): + (gl::TextureCubeMap::isSamplerComplete): + (gl::TextureCubeMap::isCompressed): + (gl::TextureCubeMap::createTexture): + (gl::TextureCubeMap::convertToRenderTarget): + (gl::TextureCubeMap::copyImage): + (gl::TextureCubeMap::copySubImage): + (gl::TextureCubeMap::storage): + (gl::TextureCubeMap::getRenderbuffer): + * src/libGLESv2/Texture.h: + (Image): + (TextureStorage): + (Texture): + (TextureStorage2D): + (Texture2D): + (TextureStorageCubeMap): + (TextureCubeMap): + * src/libGLESv2/VertexDataManager.cpp: + (gl::VertexDataManager::prepareVertexData): + * src/libGLESv2/libGLESv2.cpp: + (checkTextureFormatType): + (validateSubImageParams2D): + (validateSubImageParamsCube): + * src/libGLESv2/libGLESv2.vcproj: + * src/libGLESv2/mathutil.h: + (gl): + * src/libGLESv2/utilities.cpp: + (gl::IsDepthTexture): + (gl): + (gl::ComputePixelSize): + (gl::ExtractFormat): + (gl::ExtractType): + (es2dx::ConvertCubeFace): + (es2dx::ConvertRenderbufferFormat): + (dx2es::GetStencilSize): + (dx2es::GetDepthSize): + (dx2es::IsDepthTextureFormat): + (dx2es): + (dx2es::IsStencilTextureFormat): + (dx2es::ConvertDepthStencilFormat): + * src/libGLESv2/utilities.h: + (gl): + (dx2es): + 2012-07-11 Mark Rowe <mrowe@apple.com> <http://webkit.org/b/91024> Build against the latest SDK when targeting older OS X versions. diff --git a/Source/ThirdParty/ANGLE/include/GLES2/gl2ext.h b/Source/ThirdParty/ANGLE/include/GLES2/gl2ext.h index a12401417..e297fbfe8 100644 --- a/Source/ThirdParty/ANGLE/include/GLES2/gl2ext.h +++ b/Source/ThirdParty/ANGLE/include/GLES2/gl2ext.h @@ -238,6 +238,11 @@ typedef void* GLeglImageOES; #define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE #endif +/* GL_ANGLE_program_binary */ +#ifndef GL_ANGLE_program_binary +#define GL_PROGRAM_BINARY_ANGLE 0x93A6 +#endif + /*------------------------------------------------------------------------* * APPLE extension tokens *------------------------------------------------------------------------*/ @@ -1487,6 +1492,11 @@ typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask); #define GL_VIV_shader_binary 1 #endif +/* GL_ANGLE_program_binary */ +#ifndef GL_ANGLE_program_binary +#define GL_ANGLE_program_binary 1 +#endif + #ifdef __cplusplus } #endif diff --git a/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h b/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h index a3fc93513..9a4a36dbf 100644 --- a/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h +++ b/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h @@ -34,7 +34,7 @@ extern "C" { // Version number for shader translation API. // It is incremented everytime the API changes. -#define SH_VERSION 105 +#define SH_VERSION 107 // // The names of the following enums have been derived by replacing GL prefix @@ -49,7 +49,29 @@ typedef enum { typedef enum { SH_GLES2_SPEC = 0x8B40, - SH_WEBGL_SPEC = 0x8B41 + SH_WEBGL_SPEC = 0x8B41, + + // The CSS Shaders spec is a subset of the WebGL spec. + // + // In both CSS vertex and fragment shaders, ANGLE: + // (1) Reserves the "css_" prefix. + // (2) Renames the main function to css_main. + // (3) Disables the gl_MaxDrawBuffers built-in. + // + // In CSS fragment shaders, ANGLE: + // (1) Disables the gl_FragColor built-in. + // (2) Disables the gl_FragData built-in. + // (3) Enables the css_MixColor built-in. + // (4) Enables the css_ColorMatrix built-in. + // + // After passing a CSS shader through ANGLE, the browser is expected to append + // a new main function to it. + // This new main function will call the css_main function. + // It may also perform additional operations like varying assignment, texture + // access, and gl_FragColor assignment in order to implement the CSS Shaders + // blend modes. + // + SH_CSS_SHADERS_SPEC = 0x8B42 } ShShaderSpec; typedef enum { @@ -104,7 +126,23 @@ typedef enum { SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX = 0x0080, // This is needed only as a workaround for certain OpenGL driver bugs. - SH_EMULATE_BUILT_IN_FUNCTIONS = 0x0100 + SH_EMULATE_BUILT_IN_FUNCTIONS = 0x0100, + + // This is an experimental flag to enforce restrictions that aim to prevent + // timing attacks. + // It generates compilation errors for shaders that could expose sensitive + // texture information via the timing channel. + // To use this flag, you must compile the shader under the WebGL spec + // (using the SH_WEBGL_SPEC flag). + SH_TIMING_RESTRICTIONS = 0x0200, + + // This flag prints the dependency graph that is used to enforce timing + // restrictions on fragment shaders. + // This flag only has an effect if all of the following are true: + // - The shader spec is SH_WEBGL_SPEC. + // - The compile options contain the SH_TIMING_RESTRICTIONS flag. + // - The shader type is SH_FRAGMENT_SHADER. + SH_DEPENDENCY_GRAPH = 0x0400 } ShCompileOptions; // diff --git a/Source/ThirdParty/ANGLE/src/build_angle.xcodeproj/project.pbxproj b/Source/ThirdParty/ANGLE/src/build_angle.xcodeproj/project.pbxproj index 409b62278..565db7d99 100644 --- a/Source/ThirdParty/ANGLE/src/build_angle.xcodeproj/project.pbxproj +++ b/Source/ThirdParty/ANGLE/src/build_angle.xcodeproj/project.pbxproj @@ -47,9 +47,32 @@ 888F1382498E2D74AF2801C8 /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4ABA230FEA3654B030E4C4FB /* debug.cpp */; }; 896B720BD21F6749A7D83F30 /* MapLongVariableNames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57CF1F83E842901C42D44825 /* MapLongVariableNames.cpp */; }; 93A41AF036E5EF87B366B563 /* TranslatorESSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0A3A260F5379A7E2655D40F3 /* TranslatorESSL.cpp */; }; - 9886BCD5D0DD69B6FDE09DD8 /* UnfoldSelect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3711A48A0BF16B1CBD77AC9 /* UnfoldSelect.cpp */; }; 9B111B83FB636FD5CDEC32A0 /* OutputGLSLBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCDF01F002ADE9DB8A3EF4FE /* OutputGLSLBase.cpp */; }; 9E8DFE1CCEF038BF2B65428C /* parseConst.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D2C9C8EB4A7EFF5B67FF9DBF /* parseConst.cpp */; }; + A201083B159C31A000E57BBE /* Diagnostics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A201081F159C31A000E57BBE /* Diagnostics.cpp */; }; + A201083C159C31A000E57BBE /* DirectiveHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2010821159C31A000E57BBE /* DirectiveHandler.cpp */; }; + A201083D159C31A000E57BBE /* DirectiveParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2010823159C31A000E57BBE /* DirectiveParser.cpp */; }; + A201083E159C31A000E57BBE /* ExpressionParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2010825159C31A000E57BBE /* ExpressionParser.cpp */; }; + A2010840159C31A000E57BBE /* Input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2010829159C31A000E57BBE /* Input.cpp */; }; + A2010841159C31A000E57BBE /* Lexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A201082B159C31A000E57BBE /* Lexer.cpp */; }; + A2010842159C31A000E57BBE /* Macro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A201082D159C31A000E57BBE /* Macro.cpp */; }; + A2010843159C31A000E57BBE /* MacroExpander.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A201082F159C31A000E57BBE /* MacroExpander.cpp */; }; + A2010844159C31A000E57BBE /* Preprocessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2010832159C31A000E57BBE /* Preprocessor.cpp */; }; + A2010845159C31A000E57BBE /* Token.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2010836159C31A000E57BBE /* Token.cpp */; }; + A2010846159C31A000E57BBE /* Tokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2010838159C31A000E57BBE /* Tokenizer.cpp */; }; + A2010862159C324F00E57BBE /* BuiltInFunctionEmulator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2010849159C324F00E57BBE /* BuiltInFunctionEmulator.cpp */; }; + A2010863159C324F00E57BBE /* DependencyGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A201084C159C324F00E57BBE /* DependencyGraph.cpp */; }; + A2010864159C324F00E57BBE /* DependencyGraphBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A201084E159C324F00E57BBE /* DependencyGraphBuilder.cpp */; }; + A2010865159C324F00E57BBE /* DependencyGraphOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2010850159C324F00E57BBE /* DependencyGraphOutput.cpp */; }; + A2010866159C324F00E57BBE /* DependencyGraphTraverse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2010852159C324F00E57BBE /* DependencyGraphTraverse.cpp */; }; + A2010867159C324F00E57BBE /* DetectRecursion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2010853159C324F00E57BBE /* DetectRecursion.cpp */; }; + A2010868159C324F00E57BBE /* Diagnostics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2010855159C324F00E57BBE /* Diagnostics.cpp */; }; + A2010869159C324F00E57BBE /* DirectiveHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2010857159C324F00E57BBE /* DirectiveHandler.cpp */; }; + A201086A159C324F00E57BBE /* InitializeParseContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A201085A159C324F00E57BBE /* InitializeParseContext.cpp */; }; + A201086B159C324F00E57BBE /* RestrictFragmentShaderTiming.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A201085E159C324F00E57BBE /* RestrictFragmentShaderTiming.cpp */; }; + A201086C159C324F00E57BBE /* RestrictVertexShaderTiming.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A2010860159C324F00E57BBE /* RestrictVertexShaderTiming.cpp */; }; + A2010871159C326200E57BBE /* DetectDiscontinuity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A201086D159C326200E57BBE /* DetectDiscontinuity.cpp */; }; + A2010872159C326200E57BBE /* UnfoldShortCircuit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A201086F159C326200E57BBE /* UnfoldShortCircuit.cpp */; }; AC23F58FDD3C55F5CA18EED7 /* RemoveTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B436EFF06913FCB19C3522A7 /* RemoveTree.cpp */; }; AD85517F086FDCEF3947C403 /* symbols.c in Sources */ = {isa = PBXBuildFile; fileRef = F013A7240BDAE8A61413D8C0 /* symbols.c */; }; B4858417E54365BE8CDE3919 /* ossource_posix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE258486005F6696CC031622 /* ossource_posix.cpp */; }; @@ -104,7 +127,6 @@ 27C11EE10FED2979931FFC11 /* VariableInfo.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = VariableInfo.cpp; sourceTree = "<group>"; }; 27E4C7ED0B82E18DCBEDF1C9 /* BaseTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseTypes.h; sourceTree = "<group>"; }; 294F442A2606FEC55F12A28E /* memory.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memory.c; sourceTree = "<group>"; }; - 2A765B86CBAF0D4A3E69DCA7 /* UnfoldSelect.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UnfoldSelect.h; sourceTree = "<group>"; }; 2D00745DA9914FDE274D03D5 /* tokens.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = tokens.c; sourceTree = "<group>"; }; 2E7C9B6E6DB751E12A2F6CB6 /* InitializeGlobals.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InitializeGlobals.h; sourceTree = "<group>"; }; 3DDDC77216202A4DE1808BDB /* libtranslator_common.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libtranslator_common.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -147,6 +169,59 @@ 9D47B1AC82E4EE859AC54243 /* QualifierAlive.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QualifierAlive.h; sourceTree = "<group>"; }; A0CE43631849276A31187C7B /* InitializeDll.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InitializeDll.h; sourceTree = "<group>"; }; A1644B00E9304C407FDC5F47 /* libtranslator_glsl.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libtranslator_glsl.a; sourceTree = BUILT_PRODUCTS_DIR; }; + A20107FF159C313C00E57BBE /* libtranslator_common copy.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libtranslator_common copy.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + A201081F159C31A000E57BBE /* Diagnostics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Diagnostics.cpp; sourceTree = "<group>"; }; + A2010820159C31A000E57BBE /* Diagnostics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Diagnostics.h; sourceTree = "<group>"; }; + A2010821159C31A000E57BBE /* DirectiveHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectiveHandler.cpp; sourceTree = "<group>"; }; + A2010822159C31A000E57BBE /* DirectiveHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectiveHandler.h; sourceTree = "<group>"; }; + A2010823159C31A000E57BBE /* DirectiveParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectiveParser.cpp; sourceTree = "<group>"; }; + A2010824159C31A000E57BBE /* DirectiveParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectiveParser.h; sourceTree = "<group>"; }; + A2010825159C31A000E57BBE /* ExpressionParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExpressionParser.cpp; sourceTree = "<group>"; }; + A2010826159C31A000E57BBE /* ExpressionParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExpressionParser.h; sourceTree = "<group>"; }; + A2010829159C31A000E57BBE /* Input.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Input.cpp; sourceTree = "<group>"; }; + A201082A159C31A000E57BBE /* Input.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Input.h; sourceTree = "<group>"; }; + A201082B159C31A000E57BBE /* Lexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Lexer.cpp; sourceTree = "<group>"; }; + A201082C159C31A000E57BBE /* Lexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Lexer.h; sourceTree = "<group>"; }; + A201082D159C31A000E57BBE /* Macro.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Macro.cpp; sourceTree = "<group>"; }; + A201082E159C31A000E57BBE /* Macro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Macro.h; sourceTree = "<group>"; }; + A201082F159C31A000E57BBE /* MacroExpander.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroExpander.cpp; sourceTree = "<group>"; }; + A2010830159C31A000E57BBE /* MacroExpander.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroExpander.h; sourceTree = "<group>"; }; + A2010831159C31A000E57BBE /* pp_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pp_utils.h; sourceTree = "<group>"; }; + A2010832159C31A000E57BBE /* Preprocessor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Preprocessor.cpp; sourceTree = "<group>"; }; + A2010833159C31A000E57BBE /* Preprocessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Preprocessor.h; sourceTree = "<group>"; }; + A2010835159C31A000E57BBE /* SourceLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceLocation.h; sourceTree = "<group>"; }; + A2010836159C31A000E57BBE /* Token.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Token.cpp; sourceTree = "<group>"; }; + A2010837159C31A000E57BBE /* Token.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Token.h; sourceTree = "<group>"; }; + A2010838159C31A000E57BBE /* Tokenizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Tokenizer.cpp; sourceTree = "<group>"; }; + A2010839159C31A000E57BBE /* Tokenizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tokenizer.h; sourceTree = "<group>"; }; + A2010848159C320900E57BBE /* length_limits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = length_limits.h; sourceTree = "<group>"; }; + A2010849159C324F00E57BBE /* BuiltInFunctionEmulator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BuiltInFunctionEmulator.cpp; sourceTree = "<group>"; }; + A201084A159C324F00E57BBE /* BuiltInFunctionEmulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BuiltInFunctionEmulator.h; sourceTree = "<group>"; }; + A201084C159C324F00E57BBE /* DependencyGraph.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DependencyGraph.cpp; sourceTree = "<group>"; }; + A201084D159C324F00E57BBE /* DependencyGraph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DependencyGraph.h; sourceTree = "<group>"; }; + A201084E159C324F00E57BBE /* DependencyGraphBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DependencyGraphBuilder.cpp; sourceTree = "<group>"; }; + A201084F159C324F00E57BBE /* DependencyGraphBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DependencyGraphBuilder.h; sourceTree = "<group>"; }; + A2010850159C324F00E57BBE /* DependencyGraphOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DependencyGraphOutput.cpp; sourceTree = "<group>"; }; + A2010851159C324F00E57BBE /* DependencyGraphOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DependencyGraphOutput.h; sourceTree = "<group>"; }; + A2010852159C324F00E57BBE /* DependencyGraphTraverse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DependencyGraphTraverse.cpp; sourceTree = "<group>"; }; + A2010853159C324F00E57BBE /* DetectRecursion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DetectRecursion.cpp; sourceTree = "<group>"; }; + A2010854159C324F00E57BBE /* DetectRecursion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetectRecursion.h; sourceTree = "<group>"; }; + A2010855159C324F00E57BBE /* Diagnostics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Diagnostics.cpp; sourceTree = "<group>"; }; + A2010856159C324F00E57BBE /* Diagnostics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Diagnostics.h; sourceTree = "<group>"; }; + A2010857159C324F00E57BBE /* DirectiveHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectiveHandler.cpp; sourceTree = "<group>"; }; + A2010858159C324F00E57BBE /* DirectiveHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectiveHandler.h; sourceTree = "<group>"; }; + A2010859159C324F00E57BBE /* ExtensionBehavior.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtensionBehavior.h; sourceTree = "<group>"; }; + A201085A159C324F00E57BBE /* InitializeParseContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeParseContext.cpp; sourceTree = "<group>"; }; + A201085B159C324F00E57BBE /* Pragma.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pragma.h; sourceTree = "<group>"; }; + A201085C159C324F00E57BBE /* RenameFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenameFunction.h; sourceTree = "<group>"; }; + A201085E159C324F00E57BBE /* RestrictFragmentShaderTiming.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RestrictFragmentShaderTiming.cpp; sourceTree = "<group>"; }; + A201085F159C324F00E57BBE /* RestrictFragmentShaderTiming.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RestrictFragmentShaderTiming.h; sourceTree = "<group>"; }; + A2010860159C324F00E57BBE /* RestrictVertexShaderTiming.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RestrictVertexShaderTiming.cpp; sourceTree = "<group>"; }; + A2010861159C324F00E57BBE /* RestrictVertexShaderTiming.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RestrictVertexShaderTiming.h; sourceTree = "<group>"; }; + A201086D159C326200E57BBE /* DetectDiscontinuity.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DetectDiscontinuity.cpp; sourceTree = "<group>"; }; + A201086E159C326200E57BBE /* DetectDiscontinuity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetectDiscontinuity.h; sourceTree = "<group>"; }; + A201086F159C326200E57BBE /* UnfoldShortCircuit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnfoldShortCircuit.cpp; sourceTree = "<group>"; }; + A2010870159C326200E57BBE /* UnfoldShortCircuit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnfoldShortCircuit.h; sourceTree = "<group>"; }; A447F75F33DA4C4C123AC952 /* libtranslator_hlsl.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libtranslator_hlsl.a; sourceTree = BUILT_PRODUCTS_DIR; }; A51C728B615B41E1D59E9902 /* util.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = "<group>"; }; A54F2ED0D82D7BBCA4E9EEEA /* Initialize.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Initialize.cpp; sourceTree = "<group>"; }; @@ -178,7 +253,6 @@ DDD3B7E3B7B35A0B8469AB87 /* TranslatorGLSL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TranslatorGLSL.h; sourceTree = "<group>"; }; DEAF6F3126C2EC4397785C3F /* intermOut.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = intermOut.cpp; sourceTree = "<group>"; }; DEEAFC618A3B33F1FBFE3536 /* MMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MMap.h; sourceTree = "<group>"; }; - E3711A48A0BF16B1CBD77AC9 /* UnfoldSelect.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UnfoldSelect.cpp; sourceTree = "<group>"; }; E3A29B6E9C21B67C25FF0D2B /* TranslatorHLSL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TranslatorHLSL.h; sourceTree = "<group>"; }; F013A7240BDAE8A61413D8C0 /* symbols.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = symbols.c; sourceTree = "<group>"; }; F3E09DC8E1BF5D2958AACEDE /* SearchSymbol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SearchSymbol.h; sourceTree = "<group>"; }; @@ -190,6 +264,13 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + A20107FB159C313C00E57BBE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; A5C994E74DB1E60338E7BC11 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -223,8 +304,10 @@ B75707B393B7EAB7DD9999CB /* cpp.c */, 528FF201839C6F233E26FFDA /* cpp.h */, 8058A0A2A0A02386867517EA /* cppstruct.c */, + A2010848159C320900E57BBE /* length_limits.h */, 294F442A2606FEC55F12A28E /* memory.c */, 831399DEE5DABA09570FB3E7 /* memory.h */, + A201081E159C31A000E57BBE /* new */, CFD12C6E46EBE0839BBE52B5 /* parser.h */, 6BBC8224B9D8E234D117FA0C /* preprocess.h */, FF3AA694DF9A4455A813234D /* scanner.c */, @@ -241,15 +324,32 @@ 196DB6AB006BB83503C7D786 /* Source */ = { isa = PBXGroup; children = ( - 0E8D65F584FDB84DAABD3969 /* preprocessor */, 27E4C7ED0B82E18DCBEDF1C9 /* BaseTypes.h */, + A2010849159C324F00E57BBE /* BuiltInFunctionEmulator.cpp */, + A201084A159C324F00E57BBE /* BuiltInFunctionEmulator.h */, B7B1127C75B576FC00D74AED /* CodeGenGLSL.cpp */, C49549DCCAF450EB761520E1 /* CodeGenHLSL.cpp */, F74618F18FE5448115017C44 /* Common.h */, 0A118E5003E5C0E253C53839 /* Compiler.cpp */, B2F5CA11EEA92DF2384EFD93 /* ConstantUnion.h */, + 4ABA230FEA3654B030E4C4FB /* debug.cpp */, + 95276AA6B36FC1B1D913FCE4 /* debug.h */, + A201084B159C324F00E57BBE /* depgraph */, + A201086D159C326200E57BBE /* DetectDiscontinuity.cpp */, + A201086E159C326200E57BBE /* DetectDiscontinuity.h */, + A2010853159C324F00E57BBE /* DetectRecursion.cpp */, + A2010854159C324F00E57BBE /* DetectRecursion.h */, + A2010855159C324F00E57BBE /* Diagnostics.cpp */, + A2010856159C324F00E57BBE /* Diagnostics.h */, + A2010857159C324F00E57BBE /* DirectiveHandler.cpp */, + A2010858159C324F00E57BBE /* DirectiveHandler.h */, + A2010859159C324F00E57BBE /* ExtensionBehavior.h */, 5DC9B647E10F65F66142ECC1 /* ForLoopUnroll.cpp */, 182BAD50D4E58B884F5EB9F3 /* ForLoopUnroll.h */, + 497C5C24EEF466FB4B50A259 /* glslang.h */, + 73A57C6D413773AEBA3C47A6 /* glslang_lex.cpp */, + 3F68A6AA811495718A6938C0 /* glslang_tab.cpp */, + 4FCF32CB2D8A42C930A66B00 /* glslang_tab.h */, 6E6927BE5D3C2C82F86111DF /* InfoSink.cpp */, F7B2971D4EB3836B94B7ECAF /* InfoSink.h */, A54F2ED0D82D7BBCA4E9EEEA /* Initialize.cpp */, @@ -257,12 +357,18 @@ 60C3998C9CE66DE0C5B0FD99 /* InitializeDll.cpp */, A0CE43631849276A31187C7B /* InitializeDll.h */, 2E7C9B6E6DB751E12A2F6CB6 /* InitializeGlobals.h */, + A201085A159C324F00E57BBE /* InitializeParseContext.cpp */, 85845FFF5A8E63364308236D /* InitializeParseContext.h */, - C4FE988EF9A293867E5C771B /* IntermTraverse.cpp */, 3F7C486C370A72938FE8160F /* Intermediate.cpp */, - DEEAFC618A3B33F1FBFE3536 /* MMap.h */, + 799DC9611EE2EA3BA7CF5477 /* intermediate.h */, + DEAF6F3126C2EC4397785C3F /* intermOut.cpp */, + C4FE988EF9A293867E5C771B /* IntermTraverse.cpp */, + 153BF06BF12C6F50496C6156 /* localintermediate.h */, 57CF1F83E842901C42D44825 /* MapLongVariableNames.cpp */, 81CC4245A8E5AB5584D336F3 /* MapLongVariableNames.h */, + DEEAFC618A3B33F1FBFE3536 /* MMap.h */, + C8BD59BD7056FFC21373C50A /* osinclude.h */, + BE258486005F6696CC031622 /* ossource_posix.cpp */, DB2917C5B624712364DE4A75 /* OutputESSL.cpp */, 6BB66AB5873868E23675B6DB /* OutputESSL.h */, 48B7402CC07A059FEF5EC351 /* OutputGLSL.cpp */, @@ -271,20 +377,25 @@ B55B359CF7E486DBC49BBF0A /* OutputGLSLBase.h */, 9A5B5BB2526802479E19F993 /* OutputHLSL.cpp */, 5A21599C59BC1A75A7FABA34 /* OutputHLSL.h */, + D2C9C8EB4A7EFF5B67FF9DBF /* parseConst.cpp */, 976C831A75EBE009A9861796 /* ParseHelper.cpp */, CEE0C90DF6D504D1F3629711 /* ParseHelper.h */, B64EABE738FC666A5E4E2F42 /* PoolAlloc.cpp */, 12EAF028311EEA4753E82818 /* PoolAlloc.h */, + A201085B159C324F00E57BBE /* Pragma.h */, + 0E8D65F584FDB84DAABD3969 /* preprocessor */, 4857E18799D332C30EF460C7 /* QualifierAlive.cpp */, 9D47B1AC82E4EE859AC54243 /* QualifierAlive.h */, B436EFF06913FCB19C3522A7 /* RemoveTree.cpp */, D40F78CB9BA0C89921FA319D /* RemoveTree.h */, + A201085C159C324F00E57BBE /* RenameFunction.h */, 228A6DEDDF08DB370394A7AD /* SearchSymbol.cpp */, F3E09DC8E1BF5D2958AACEDE /* SearchSymbol.h */, - AE65E139AE10DE9EFAD8D5B1 /* ShHandle.h */, 56C7E99BA500A84C35216FE0 /* ShaderLang.cpp */, + AE65E139AE10DE9EFAD8D5B1 /* ShHandle.h */, B7E5B0F04635E6090F0DE8EF /* SymbolTable.cpp */, 7C6BB12AB099556CF379D78F /* SymbolTable.h */, + A201085D159C324F00E57BBE /* timing */, 0A3A260F5379A7E2655D40F3 /* TranslatorESSL.cpp */, D53DDD0CDF15EE1DD01F1A20 /* TranslatorESSL.h */, 6FB70DC74A21FBCD665ABDF9 /* TranslatorGLSL.cpp */, @@ -292,29 +403,17 @@ C3DAFF6BF12BB7F4784D6C7E /* TranslatorHLSL.cpp */, E3A29B6E9C21B67C25FF0D2B /* TranslatorHLSL.h */, AA53B6632C76F905DF08E564 /* Types.h */, - E3711A48A0BF16B1CBD77AC9 /* UnfoldSelect.cpp */, - 2A765B86CBAF0D4A3E69DCA7 /* UnfoldSelect.h */, + A201086F159C326200E57BBE /* UnfoldShortCircuit.cpp */, + A2010870159C326200E57BBE /* UnfoldShortCircuit.h */, + AE7674C52BDDDB28AF5FFD9F /* unistd.h */, + 3EE7215A7AB4EF71C97D2545 /* util.cpp */, + A51C728B615B41E1D59E9902 /* util.h */, B148D967B8D288A8267BFF3A /* ValidateLimitations.cpp */, 90254842D72975672C2E9A93 /* ValidateLimitations.h */, 27C11EE10FED2979931FFC11 /* VariableInfo.cpp */, 5D99354C4D8187D384C81207 /* VariableInfo.h */, F727AEC906712EC238041464 /* VersionGLSL.cpp */, 120AD0A3B7642FB5A9AE3A56 /* VersionGLSL.h */, - 4ABA230FEA3654B030E4C4FB /* debug.cpp */, - 95276AA6B36FC1B1D913FCE4 /* debug.h */, - 497C5C24EEF466FB4B50A259 /* glslang.h */, - 73A57C6D413773AEBA3C47A6 /* glslang_lex.cpp */, - 3F68A6AA811495718A6938C0 /* glslang_tab.cpp */, - 4FCF32CB2D8A42C930A66B00 /* glslang_tab.h */, - DEAF6F3126C2EC4397785C3F /* intermOut.cpp */, - 799DC9611EE2EA3BA7CF5477 /* intermediate.h */, - 153BF06BF12C6F50496C6156 /* localintermediate.h */, - C8BD59BD7056FFC21373C50A /* osinclude.h */, - BE258486005F6696CC031622 /* ossource_posix.cpp */, - D2C9C8EB4A7EFF5B67FF9DBF /* parseConst.cpp */, - AE7674C52BDDDB28AF5FFD9F /* unistd.h */, - 3EE7215A7AB4EF71C97D2545 /* util.cpp */, - A51C728B615B41E1D59E9902 /* util.h */, ); name = Source; path = compiler; @@ -329,6 +428,62 @@ ); sourceTree = "<group>"; }; + A201081E159C31A000E57BBE /* new */ = { + isa = PBXGroup; + children = ( + A201081F159C31A000E57BBE /* Diagnostics.cpp */, + A2010820159C31A000E57BBE /* Diagnostics.h */, + A2010821159C31A000E57BBE /* DirectiveHandler.cpp */, + A2010822159C31A000E57BBE /* DirectiveHandler.h */, + A2010823159C31A000E57BBE /* DirectiveParser.cpp */, + A2010824159C31A000E57BBE /* DirectiveParser.h */, + A2010825159C31A000E57BBE /* ExpressionParser.cpp */, + A2010826159C31A000E57BBE /* ExpressionParser.h */, + A2010829159C31A000E57BBE /* Input.cpp */, + A201082A159C31A000E57BBE /* Input.h */, + A201082B159C31A000E57BBE /* Lexer.cpp */, + A201082C159C31A000E57BBE /* Lexer.h */, + A201082D159C31A000E57BBE /* Macro.cpp */, + A201082E159C31A000E57BBE /* Macro.h */, + A201082F159C31A000E57BBE /* MacroExpander.cpp */, + A2010830159C31A000E57BBE /* MacroExpander.h */, + A2010831159C31A000E57BBE /* pp_utils.h */, + A2010832159C31A000E57BBE /* Preprocessor.cpp */, + A2010833159C31A000E57BBE /* Preprocessor.h */, + A2010835159C31A000E57BBE /* SourceLocation.h */, + A2010836159C31A000E57BBE /* Token.cpp */, + A2010837159C31A000E57BBE /* Token.h */, + A2010838159C31A000E57BBE /* Tokenizer.cpp */, + A2010839159C31A000E57BBE /* Tokenizer.h */, + ); + path = new; + sourceTree = "<group>"; + }; + A201084B159C324F00E57BBE /* depgraph */ = { + isa = PBXGroup; + children = ( + A201084C159C324F00E57BBE /* DependencyGraph.cpp */, + A201084D159C324F00E57BBE /* DependencyGraph.h */, + A201084E159C324F00E57BBE /* DependencyGraphBuilder.cpp */, + A201084F159C324F00E57BBE /* DependencyGraphBuilder.h */, + A2010850159C324F00E57BBE /* DependencyGraphOutput.cpp */, + A2010851159C324F00E57BBE /* DependencyGraphOutput.h */, + A2010852159C324F00E57BBE /* DependencyGraphTraverse.cpp */, + ); + path = depgraph; + sourceTree = "<group>"; + }; + A201085D159C324F00E57BBE /* timing */ = { + isa = PBXGroup; + children = ( + A201085E159C324F00E57BBE /* RestrictFragmentShaderTiming.cpp */, + A201085F159C324F00E57BBE /* RestrictFragmentShaderTiming.h */, + A2010860159C324F00E57BBE /* RestrictVertexShaderTiming.cpp */, + A2010861159C324F00E57BBE /* RestrictVertexShaderTiming.h */, + ); + path = timing; + sourceTree = "<group>"; + }; B2C184C3543198BA51592EA4 /* Build */ = { isa = PBXGroup; children = ( @@ -344,6 +499,7 @@ 3DDDC77216202A4DE1808BDB /* libtranslator_common.a */, A1644B00E9304C407FDC5F47 /* libtranslator_glsl.a */, A447F75F33DA4C4C123AC952 /* libtranslator_hlsl.a */, + A20107FF159C313C00E57BBE /* libtranslator_common copy.a */, ); name = Products; sourceTree = "<group>"; @@ -383,6 +539,22 @@ productReference = 3DDDC77216202A4DE1808BDB /* libtranslator_common.a */; productType = "com.apple.product-type.library.static"; }; + A20107DC159C313C00E57BBE /* preprocessor */ = { + isa = PBXNativeTarget; + buildConfigurationList = A20107FC159C313C00E57BBE /* Build configuration list for PBXNativeTarget "preprocessor" */; + buildPhases = ( + A20107DD159C313C00E57BBE /* Sources */, + A20107FB159C313C00E57BBE /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = preprocessor; + productName = translator_common; + productReference = A20107FF159C313C00E57BBE /* libtranslator_common copy.a */; + productType = "com.apple.product-type.library.static"; + }; A838E9574B3FF14791DBDAB1 /* translator_hlsl */ = { isa = PBXNativeTarget; buildConfigurationList = C71E79C7829FD796CF621B44 /* Build configuration list for PBXNativeTarget "translator_hlsl" */; @@ -409,7 +581,11 @@ }; buildConfigurationList = 0E59F8FE4A8099E8DDCA4CE7 /* Build configuration list for PBXProject "build_angle" */; compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + en, + ); mainGroup = 5BBEFF9B91738297B95C568D; projectDirPath = ""; projectRoot = ""; @@ -418,6 +594,7 @@ 6F4FD35CB3DFC89D70ECD432 /* translator_common */, 5892C7A3695330437AFE5714 /* translator_glsl */, A838E9574B3FF14791DBDAB1 /* translator_hlsl */, + A20107DC159C313C00E57BBE /* preprocessor */, ); }; /* End PBXProject section */ @@ -430,8 +607,27 @@ 4B4BDE7AD6266B39ED43C2D4 /* CodeGenHLSL.cpp in Sources */, 5F7B52A54DCE8155ED94ECF8 /* OutputHLSL.cpp in Sources */, E99D6D80DBF05ECE7108B26D /* TranslatorHLSL.cpp in Sources */, - 9886BCD5D0DD69B6FDE09DD8 /* UnfoldSelect.cpp in Sources */, 296466566D8C0F023A553760 /* SearchSymbol.cpp in Sources */, + A2010871159C326200E57BBE /* DetectDiscontinuity.cpp in Sources */, + A2010872159C326200E57BBE /* UnfoldShortCircuit.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A20107DD159C313C00E57BBE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A201083B159C31A000E57BBE /* Diagnostics.cpp in Sources */, + A201083C159C31A000E57BBE /* DirectiveHandler.cpp in Sources */, + A201083D159C31A000E57BBE /* DirectiveParser.cpp in Sources */, + A201083E159C31A000E57BBE /* ExpressionParser.cpp in Sources */, + A2010840159C31A000E57BBE /* Input.cpp in Sources */, + A2010841159C31A000E57BBE /* Lexer.cpp in Sources */, + A2010842159C31A000E57BBE /* Macro.cpp in Sources */, + A2010843159C31A000E57BBE /* MacroExpander.cpp in Sources */, + A2010844159C31A000E57BBE /* Preprocessor.cpp in Sources */, + A2010845159C31A000E57BBE /* Token.cpp in Sources */, + A2010846159C31A000E57BBE /* Tokenizer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -483,6 +679,17 @@ AD85517F086FDCEF3947C403 /* symbols.c in Sources */, E8C727AA8E9DC5E7B58857DF /* tokens.c in Sources */, B4858417E54365BE8CDE3919 /* ossource_posix.cpp in Sources */, + A2010862159C324F00E57BBE /* BuiltInFunctionEmulator.cpp in Sources */, + A2010863159C324F00E57BBE /* DependencyGraph.cpp in Sources */, + A2010864159C324F00E57BBE /* DependencyGraphBuilder.cpp in Sources */, + A2010865159C324F00E57BBE /* DependencyGraphOutput.cpp in Sources */, + A2010866159C324F00E57BBE /* DependencyGraphTraverse.cpp in Sources */, + A2010867159C324F00E57BBE /* DetectRecursion.cpp in Sources */, + A2010868159C324F00E57BBE /* Diagnostics.cpp in Sources */, + A2010869159C324F00E57BBE /* DirectiveHandler.cpp in Sources */, + A201086A159C324F00E57BBE /* InitializeParseContext.cpp in Sources */, + A201086B159C324F00E57BBE /* RestrictFragmentShaderTiming.cpp in Sources */, + A201086C159C324F00E57BBE /* RestrictVertexShaderTiming.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -561,6 +768,38 @@ }; name = Debug; }; + A20107FD159C313C00E57BBE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ( + "\"ANGLE_DISABLE_TRACE\"", + "\"ANGLE_COMPILE_OPTIMIZATION_LEVEL=D3DCOMPILE_OPTIMIZATION_LEVEL0\"", + ); + HEADER_SEARCH_PATHS = ( + ., + ../include, + ); + PRODUCT_NAME = "translator_common copy"; + }; + name = Debug; + }; + A20107FE159C313C00E57BBE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ( + "\"ANGLE_DISABLE_TRACE\"", + "\"ANGLE_COMPILE_OPTIMIZATION_LEVEL=D3DCOMPILE_OPTIMIZATION_LEVEL0\"", + ); + HEADER_SEARCH_PATHS = ( + ., + ../include, + ); + PRODUCT_NAME = "translator_common copy"; + }; + name = Release; + }; AF7C2CD10C6FEA076B141E6E /* Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -672,6 +911,15 @@ defaultConfigurationIsVisible = 1; defaultConfigurationName = Debug; }; + A20107FC159C313C00E57BBE /* Build configuration list for PBXNativeTarget "preprocessor" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A20107FD159C313C00E57BBE /* Debug */, + A20107FE159C313C00E57BBE /* Release */, + ); + defaultConfigurationIsVisible = 1; + defaultConfigurationName = Debug; + }; C71E79C7829FD796CF621B44 /* Build configuration list for PBXNativeTarget "translator_hlsl" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Source/ThirdParty/ANGLE/src/common/angleutils.h b/Source/ThirdParty/ANGLE/src/common/angleutils.h index 24c766bdf..7d9349a4d 100644 --- a/Source/ThirdParty/ANGLE/src/common/angleutils.h +++ b/Source/ThirdParty/ANGLE/src/common/angleutils.h @@ -15,4 +15,8 @@ TypeName(const TypeName&); \ void operator=(const TypeName&) +#if defined(_MSC_VER) +#define snprintf _snprintf +#endif + #endif // COMMON_ANGLEUTILS_H_ diff --git a/Source/ThirdParty/ANGLE/src/common/debug.cpp b/Source/ThirdParty/ANGLE/src/common/debug.cpp index 845d25896..b2238f970 100644 --- a/Source/ThirdParty/ANGLE/src/common/debug.cpp +++ b/Source/ThirdParty/ANGLE/src/common/debug.cpp @@ -1,103 +1,103 @@ -//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// debug.cpp: Debugging utilities.
-
-#include "common/debug.h"
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <d3d9.h>
-#include <windows.h>
-
-namespace gl
-{
-
-typedef void (WINAPI *PerfOutputFunction)(D3DCOLOR, LPCWSTR);
-
-static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg)
-{
-#if !defined(ANGLE_DISABLE_PERF)
- if (perfActive())
- {
- char message[32768];
- int len = vsprintf_s(message, format, vararg);
- if (len < 0)
- {
- return;
- }
-
- // There are no ASCII variants of these D3DPERF functions.
- wchar_t wideMessage[32768];
- for (int i = 0; i < len; ++i)
- {
- wideMessage[i] = message[i];
- }
- wideMessage[len] = 0;
-
- perfFunc(0, wideMessage);
- }
-#endif
-
-#if !defined(ANGLE_DISABLE_TRACE)
-#if defined(NDEBUG)
- if (traceFileDebugOnly)
- {
- return;
- }
-#endif
-
- FILE* file = fopen(TRACE_OUTPUT_FILE, "a");
- if (file)
- {
- vfprintf(file, format, vararg);
- fclose(file);
- }
-#endif
-}
-
-void trace(bool traceFileDebugOnly, const char *format, ...)
-{
- va_list vararg;
- va_start(vararg, format);
-#if defined(ANGLE_DISABLE_PERF)
- output(traceFileDebugOnly, NULL, format, vararg);
-#else
- output(traceFileDebugOnly, D3DPERF_SetMarker, format, vararg);
-#endif
- va_end(vararg);
-}
-
-bool perfActive()
-{
-#if defined(ANGLE_DISABLE_PERF)
- return false;
-#else
- static bool active = D3DPERF_GetStatus() != 0;
- return active;
-#endif
-}
-
-ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
-{
-#if !defined(ANGLE_DISABLE_PERF)
- va_list vararg;
- va_start(vararg, format);
- output(true, reinterpret_cast<PerfOutputFunction>(D3DPERF_BeginEvent), format, vararg);
- va_end(vararg);
-#endif
-}
-
-ScopedPerfEventHelper::~ScopedPerfEventHelper()
-{
-#if !defined(ANGLE_DISABLE_PERF)
- if (perfActive())
- {
- D3DPERF_EndEvent();
- }
-#endif
-}
-}
+// +// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// debug.cpp: Debugging utilities. + +#include "common/debug.h" + +#include <stdio.h> +#include <stdarg.h> +#include <d3d9.h> +#include <windows.h> + +namespace gl +{ + +typedef void (WINAPI *PerfOutputFunction)(D3DCOLOR, LPCWSTR); + +static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg) +{ +#if !defined(ANGLE_DISABLE_PERF) + if (perfActive()) + { + char message[32768]; + int len = vsprintf_s(message, format, vararg); + if (len < 0) + { + return; + } + + // There are no ASCII variants of these D3DPERF functions. + wchar_t wideMessage[32768]; + for (int i = 0; i < len; ++i) + { + wideMessage[i] = message[i]; + } + wideMessage[len] = 0; + + perfFunc(0, wideMessage); + } +#endif + +#if !defined(ANGLE_DISABLE_TRACE) +#if defined(NDEBUG) + if (traceFileDebugOnly) + { + return; + } +#endif + + FILE* file = fopen(TRACE_OUTPUT_FILE, "a"); + if (file) + { + vfprintf(file, format, vararg); + fclose(file); + } +#endif +} + +void trace(bool traceFileDebugOnly, const char *format, ...) +{ + va_list vararg; + va_start(vararg, format); +#if defined(ANGLE_DISABLE_PERF) + output(traceFileDebugOnly, NULL, format, vararg); +#else + output(traceFileDebugOnly, D3DPERF_SetMarker, format, vararg); +#endif + va_end(vararg); +} + +bool perfActive() +{ +#if defined(ANGLE_DISABLE_PERF) + return false; +#else + static bool active = D3DPERF_GetStatus() != 0; + return active; +#endif +} + +ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...) +{ +#if !defined(ANGLE_DISABLE_PERF) + va_list vararg; + va_start(vararg, format); + output(true, reinterpret_cast<PerfOutputFunction>(D3DPERF_BeginEvent), format, vararg); + va_end(vararg); +#endif +} + +ScopedPerfEventHelper::~ScopedPerfEventHelper() +{ +#if !defined(ANGLE_DISABLE_PERF) + if (perfActive()) + { + D3DPERF_EndEvent(); + } +#endif +} +} diff --git a/Source/ThirdParty/ANGLE/src/common/version.h b/Source/ThirdParty/ANGLE/src/common/version.h index 203c42177..bdd16245e 100644 --- a/Source/ThirdParty/ANGLE/src/common/version.h +++ b/Source/ThirdParty/ANGLE/src/common/version.h @@ -1,7 +1,7 @@ #define MAJOR_VERSION 1 #define MINOR_VERSION 0 #define BUILD_VERSION 0 -#define BUILD_REVISION 1009 +#define BUILD_REVISION 1166 #define STRINGIFY(x) #x #define MACRO_STRINGIFY(x) STRINGIFY(x) diff --git a/Source/ThirdParty/ANGLE/src/compiler/BuiltInFunctionEmulator.cpp b/Source/ThirdParty/ANGLE/src/compiler/BuiltInFunctionEmulator.cpp index a7950b990..1c4b25f13 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/BuiltInFunctionEmulator.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/BuiltInFunctionEmulator.cpp @@ -16,11 +16,6 @@ namespace { // evaluated. This is unlikely to show up in real shaders, but is something to // consider. const char* kFunctionEmulationVertexSource[] = { - "#error no emulation for atan(float, float)", - "vec2 webgl_atan_emu(vec2 y, vec2 x) { return vec2(atan(y[0], x[0]), atan(y[1], x[1])); }", - "vec3 webgl_atan_emu(vec3 y, vec3 x) { return vec3(atan(y[0], x[0]), atan(y[1], x[1]), atan(y[2], x[2])); }", - "vec4 webgl_atan_emu(vec4 y, vec4 x) { return vec4(atan(y[0], x[0]), atan(y[1], x[1]), atan(y[2], x[2]), atan(y[3], x[3])); }", - "#error no emulation for cos(float)", "#error no emulation for cos(vec2)", "#error no emulation for cos(vec3)", @@ -41,11 +36,6 @@ const char* kFunctionEmulationVertexSource[] = { "#error no emulation for length(vec3)", "#error no emulation for length(vec4)", - "#error no emulation for mod(float, float)", - "vec2 webgl_mod_emu(vec2 x, vec2 y) { return vec2(mod(x[0], y[0]), mod(x[1], y[1])); }", - "vec3 webgl_mod_emu(vec3 x, vec3 y) { return vec3(mod(x[0], y[0]), mod(x[1], y[1]), mod(x[2], y[2])); }", - "vec4 webgl_mod_emu(vec4 x, vec4 y) { return vec4(mod(x[0], y[0]), mod(x[1], y[1]), mod(x[2], y[2]), mod(x[3], y[3])); }", - "#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))", "#error no emulation for normalize(vec2)", "#error no emulation for normalize(vec3)", @@ -58,42 +48,32 @@ const char* kFunctionEmulationVertexSource[] = { }; const char* kFunctionEmulationFragmentSource[] = { - "#error no emulation for atan(float, float)", - "#error no emulation for atan(vec2, vec2)", - "#error no emulation for atan(vec3, vec3)", - "#error no emulation for atan(vec4, vec4)", - "webgl_emu_precision float webgl_cos_emu(webgl_emu_precision float a) { return cos(a); }", "webgl_emu_precision vec2 webgl_cos_emu(webgl_emu_precision vec2 a) { return cos(a); }", "webgl_emu_precision vec3 webgl_cos_emu(webgl_emu_precision vec3 a) { return cos(a); }", "webgl_emu_precision vec4 webgl_cos_emu(webgl_emu_precision vec4 a) { return cos(a); }", - "#error no emulation for distance(float, float)", + "#define webgl_distance_emu(x, y) ((x) >= (y) ? (x) - (y) : (y) - (x))", "#error no emulation for distance(vec2, vec2)", "#error no emulation for distance(vec3, vec3)", "#error no emulation for distance(vec4, vec4)", - "#error no emulation for dot(float, float)", + "#define webgl_dot_emu(x, y) ((x) * (y))", "#error no emulation for dot(vec2, vec2)", "#error no emulation for dot(vec3, vec3)", "#error no emulation for dot(vec4, vec4)", - "#error no emulation for length(float)", + "#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))", "#error no emulation for length(vec2)", "#error no emulation for length(vec3)", "#error no emulation for length(vec4)", - "#error no emulation for mod(float, float)", - "#error no emulation for mod(vec2, vec2)", - "#error no emulation for mod(vec3, vec3)", - "#error no emulation for mod(vec4, vec4)", - - "#error no emulation for normalize(float)", + "#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))", "#error no emulation for normalize(vec2)", "#error no emulation for normalize(vec3)", "#error no emulation for normalize(vec4)", - "#error no emulation for reflect(float, float)", + "#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))", "#error no emulation for reflect(vec2, vec2)", "#error no emulation for reflect(vec3, vec3)", "#error no emulation for reflect(vec4, vec4)" @@ -102,10 +82,6 @@ const char* kFunctionEmulationFragmentSource[] = { const bool kFunctionEmulationVertexMask[] = { #if defined(__APPLE__) // Work around ATI driver bugs in Mac. - false, // TFunctionAtan1_1 - false, // TFunctionAtan2_2 - false, // TFunctionAtan3_3 - false, // TFunctionAtan4_4 false, // TFunctionCos1 false, // TFunctionCos2 false, // TFunctionCos3 @@ -122,10 +98,6 @@ const bool kFunctionEmulationVertexMask[] = { false, // TFunctionLength2 false, // TFunctionLength3 false, // TFunctionLength4 - false, // TFunctionMod1_1 - false, // TFunctionMod2_2 - false, // TFunctionMod3_3 - false, // TFunctionMod4_4 true, // TFunctionNormalize1 false, // TFunctionNormalize2 false, // TFunctionNormalize3 @@ -136,10 +108,6 @@ const bool kFunctionEmulationVertexMask[] = { false, // TFunctionReflect4_4 #else // Work around D3D driver bug in Win. - false, // TFunctionAtan1_1 - true, // TFunctionAtan2_2 - true, // TFunctionAtan3_3 - true, // TFunctionAtan4_4 false, // TFunctionCos1 false, // TFunctionCos2 false, // TFunctionCos3 @@ -156,10 +124,6 @@ const bool kFunctionEmulationVertexMask[] = { false, // TFunctionLength2 false, // TFunctionLength3 false, // TFunctionLength4 - false, // TFunctionMod1_1 - true, // TFunctionMod2_2 - true, // TFunctionMod3_3 - true, // TFunctionMod4_4 false, // TFunctionNormalize1 false, // TFunctionNormalize2 false, // TFunctionNormalize3 @@ -173,22 +137,38 @@ const bool kFunctionEmulationVertexMask[] = { }; const bool kFunctionEmulationFragmentMask[] = { - false, // TFunctionAtan1_1 - false, // TFunctionAtan2_2 - false, // TFunctionAtan3_3 - false, // TFunctionAtan4_4 #if defined(__APPLE__) - // Work around a ATI driver bug in Mac that causes crashes. + // Work around ATI driver bugs in Mac. true, // TFunctionCos1 true, // TFunctionCos2 true, // TFunctionCos3 true, // TFunctionCos4 + true, // TFunctionDistance1_1 + false, // TFunctionDistance2_2 + false, // TFunctionDistance3_3 + false, // TFunctionDistance4_4 + true, // TFunctionDot1_1 + false, // TFunctionDot2_2 + false, // TFunctionDot3_3 + false, // TFunctionDot4_4 + true, // TFunctionLength1 + false, // TFunctionLength2 + false, // TFunctionLength3 + false, // TFunctionLength4 + true, // TFunctionNormalize1 + false, // TFunctionNormalize2 + false, // TFunctionNormalize3 + false, // TFunctionNormalize4 + true, // TFunctionReflect1_1 + false, // TFunctionReflect2_2 + false, // TFunctionReflect3_3 + false, // TFunctionReflect4_4 #else + // Work around D3D driver bug in Win. false, // TFunctionCos1 false, // TFunctionCos2 false, // TFunctionCos3 false, // TFunctionCos4 -#endif false, // TFunctionDistance1_1 false, // TFunctionDistance2_2 false, // TFunctionDistance3_3 @@ -201,10 +181,6 @@ const bool kFunctionEmulationFragmentMask[] = { false, // TFunctionLength2 false, // TFunctionLength3 false, // TFunctionLength4 - false, // TFunctionMod1_1 - false, // TFunctionMod2_2 - false, // TFunctionMod3_3 - false, // TFunctionMod4_4 false, // TFunctionNormalize1 false, // TFunctionNormalize2 false, // TFunctionNormalize3 @@ -213,6 +189,7 @@ const bool kFunctionEmulationFragmentMask[] = { false, // TFunctionReflect2_2 false, // TFunctionReflect3_3 false, // TFunctionReflect4_4 +#endif false // TFunctionUnknown }; @@ -386,18 +363,12 @@ BuiltInFunctionEmulator::IdentifyFunction( unsigned int function = TFunctionUnknown; switch (op) { - case EOpAtan: - function = TFunctionAtan1_1; - break; case EOpDistance: function = TFunctionDistance1_1; break; case EOpDot: function = TFunctionDot1_1; break; - case EOpMod: - function = TFunctionMod1_1; - break; case EOpReflect: function = TFunctionReflect1_1; break; diff --git a/Source/ThirdParty/ANGLE/src/compiler/BuiltInFunctionEmulator.h b/Source/ThirdParty/ANGLE/src/compiler/BuiltInFunctionEmulator.h index b37b66535..0d904f41d 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/BuiltInFunctionEmulator.h +++ b/Source/ThirdParty/ANGLE/src/compiler/BuiltInFunctionEmulator.h @@ -45,12 +45,7 @@ private: // Built-in functions. // enum TBuiltInFunction { - TFunctionAtan1_1 = 0, // float atan(float, float); - TFunctionAtan2_2, // vec2 atan(vec2, vec2); - TFunctionAtan3_3, // vec3 atan(vec3, vec2); - TFunctionAtan4_4, // vec4 atan(vec4, vec2); - - TFunctionCos1, // float cos(float); + TFunctionCos1 = 0, // float cos(float); TFunctionCos2, // vec2 cos(vec2); TFunctionCos3, // vec3 cos(vec3); TFunctionCos4, // vec4 cos(vec4); @@ -70,11 +65,6 @@ private: TFunctionLength3, // float length(vec3); TFunctionLength4, // float length(vec4); - TFunctionMod1_1, // float mod(float, float); - TFunctionMod2_2, // vec2 mod(vec2, vec2); - TFunctionMod3_3, // vec3 mod(vec3, vec3); - TFunctionMod4_4, // vec4 mod(vec4, vec4); - TFunctionNormalize1, // float normalize(float); TFunctionNormalize2, // vec2 normalize(vec2); TFunctionNormalize3, // vec3 normalize(vec3); diff --git a/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp b/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp index f27cb75d5..cab8056bc 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp @@ -8,10 +8,21 @@ #include "compiler/DetectRecursion.h" #include "compiler/ForLoopUnroll.h" #include "compiler/Initialize.h" +#include "compiler/InitializeParseContext.h" #include "compiler/MapLongVariableNames.h" #include "compiler/ParseHelper.h" +#include "compiler/RenameFunction.h" #include "compiler/ShHandle.h" #include "compiler/ValidateLimitations.h" +#include "compiler/depgraph/DependencyGraph.h" +#include "compiler/depgraph/DependencyGraphOutput.h" +#include "compiler/timing/RestrictFragmentShaderTiming.h" +#include "compiler/timing/RestrictVertexShaderTiming.h" + +bool isWebGLBasedSpec(ShShaderSpec spec) +{ + return spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC; +} namespace { bool InitializeSymbolTable( @@ -123,7 +134,7 @@ bool TCompiler::compile(const char* const shaderStrings[], return true; // If compiling for WebGL, validate loop and indexing as well. - if (shaderSpec == SH_WEBGL_SPEC) + if (isWebGLBasedSpec(shaderSpec)) compileOptions |= SH_VALIDATE_LOOP_INDEXING; // First string is path of source file if flag is set. The actual source follows. @@ -161,6 +172,12 @@ bool TCompiler::compile(const char* const shaderStrings[], if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING)) success = validateLimitations(root); + if (success && (compileOptions & SH_TIMING_RESTRICTIONS)) + success = enforceTimingRestrictions(root, (compileOptions & SH_DEPENDENCY_GRAPH) != 0); + + if (success && shaderSpec == SH_CSS_SHADERS_SPEC) + rewriteCSSShader(root); + // Unroll for-loop markup needs to happen after validateLimitations pass. if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX)) ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(root); @@ -235,12 +252,58 @@ bool TCompiler::detectRecursion(TIntermNode* root) } } +void TCompiler::rewriteCSSShader(TIntermNode* root) +{ + RenameFunction renamer("main(", "css_main("); + root->traverse(&renamer); +} + bool TCompiler::validateLimitations(TIntermNode* root) { ValidateLimitations validate(shaderType, infoSink.info); root->traverse(&validate); return validate.numErrors() == 0; } +bool TCompiler::enforceTimingRestrictions(TIntermNode* root, bool outputGraph) +{ + if (shaderSpec != SH_WEBGL_SPEC) { + infoSink.info << "Timing restrictions must be enforced under the WebGL spec."; + return false; + } + + if (shaderType == SH_FRAGMENT_SHADER) { + TDependencyGraph graph(root); + + // Output any errors first. + bool success = enforceFragmentShaderTimingRestrictions(graph); + + // Then, output the dependency graph. + if (outputGraph) { + TDependencyGraphOutput output(infoSink.info); + output.outputAllSpanningTrees(graph); + } + + return success; + } + else { + return enforceVertexShaderTimingRestrictions(root); + } +} + +bool TCompiler::enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph) +{ + RestrictFragmentShaderTiming restrictor(infoSink.info); + restrictor.enforceRestrictions(graph); + return restrictor.numErrors() == 0; +} + +bool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root) +{ + RestrictVertexShaderTiming restrictor(infoSink.info); + restrictor.enforceRestrictions(root); + return restrictor.numErrors() == 0; +} + void TCompiler::collectAttribsUniforms(TIntermNode* root) { CollectAttribsUniforms collect(attribs, uniforms); diff --git a/Source/ThirdParty/ANGLE/src/compiler/DetectDiscontinuity.cpp b/Source/ThirdParty/ANGLE/src/compiler/DetectDiscontinuity.cpp new file mode 100644 index 000000000..472232a75 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/DetectDiscontinuity.cpp @@ -0,0 +1,119 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Contains analysis utilities for dealing with HLSL's lack of support for +// the use of intrinsic functions which (implicitly or explicitly) compute +// gradients of functions with discontinuities. +// + +#include "compiler/DetectDiscontinuity.h" + +#include "compiler/ParseHelper.h" + +namespace sh +{ +bool DetectLoopDiscontinuity::traverse(TIntermNode *node) +{ + mLoopDiscontinuity = false; + node->traverse(this); + return mLoopDiscontinuity; +} + +bool DetectLoopDiscontinuity::visitBranch(Visit visit, TIntermBranch *node) +{ + if (mLoopDiscontinuity) + { + return false; + } + + switch (node->getFlowOp()) + { + case EOpKill: + break; + case EOpBreak: + case EOpContinue: + mLoopDiscontinuity = true; + case EOpReturn: + break; + default: UNREACHABLE(); + } + + return !mLoopDiscontinuity; +} + +bool DetectLoopDiscontinuity::visitAggregate(Visit visit, TIntermAggregate *node) +{ + return !mLoopDiscontinuity; +} + +bool containsLoopDiscontinuity(TIntermNode *node) +{ + DetectLoopDiscontinuity detectLoopDiscontinuity; + return detectLoopDiscontinuity.traverse(node); +} + +bool DetectGradientOperation::traverse(TIntermNode *node) +{ + mGradientOperation = false; + node->traverse(this); + return mGradientOperation; +} + +bool DetectGradientOperation::visitUnary(Visit visit, TIntermUnary *node) +{ + if (mGradientOperation) + { + return false; + } + + switch (node->getOp()) + { + case EOpDFdx: + case EOpDFdy: + mGradientOperation = true; + default: + break; + } + + return !mGradientOperation; +} + +bool DetectGradientOperation::visitAggregate(Visit visit, TIntermAggregate *node) +{ + if (mGradientOperation) + { + return false; + } + + if (node->getOp() == EOpFunctionCall) + { + if (!node->isUserDefined()) + { + TString name = TFunction::unmangleName(node->getName()); + + if (name == "texture2D" || + name == "texture2DProj" || + name == "textureCube") + { + mGradientOperation = true; + } + } + else + { + // When a user defined function is called, we have to + // conservatively assume it to contain gradient operations + mGradientOperation = true; + } + } + + return !mGradientOperation; +} + +bool containsGradientOperation(TIntermNode *node) +{ + DetectGradientOperation detectGradientOperation; + return detectGradientOperation.traverse(node); +} +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/DetectDiscontinuity.h b/Source/ThirdParty/ANGLE/src/compiler/DetectDiscontinuity.h new file mode 100644 index 000000000..8bda4c3de --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/DetectDiscontinuity.h @@ -0,0 +1,50 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Contains analysis utilities for dealing with HLSL's lack of support for +// the use of intrinsic functions which (implicitly or explicitly) compute +// gradients of functions with discontinuities. +// + +#ifndef COMPILER_DETECTDISCONTINUITY_H_ +#define COMPILER_DETECTDISCONTINUITY_H_ + +#include "compiler/intermediate.h" + +namespace sh +{ +// Checks whether a loop can run for a variable number of iterations +class DetectLoopDiscontinuity : public TIntermTraverser +{ + public: + bool traverse(TIntermNode *node); + + protected: + bool visitBranch(Visit visit, TIntermBranch *node); + bool visitAggregate(Visit visit, TIntermAggregate *node); + + bool mLoopDiscontinuity; +}; + +bool containsLoopDiscontinuity(TIntermNode *node); + +// Checks for intrinsic functions which compute gradients +class DetectGradientOperation : public TIntermTraverser +{ + public: + bool traverse(TIntermNode *node); + + protected: + bool visitUnary(Visit visit, TIntermUnary *node); + bool visitAggregate(Visit visit, TIntermAggregate *node); + + bool mGradientOperation; +}; + +bool containsGradientOperation(TIntermNode *node); + +} + +#endif // COMPILER_DETECTDISCONTINUITY_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/Diagnostics.cpp b/Source/ThirdParty/ANGLE/src/compiler/Diagnostics.cpp new file mode 100644 index 000000000..5f93a0343 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/Diagnostics.cpp @@ -0,0 +1,44 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/Diagnostics.h" + +#include "compiler/InfoSink.h" +#include "compiler/preprocessor/new/SourceLocation.h" + +TDiagnostics::TDiagnostics(TInfoSink& infoSink) : mInfoSink(infoSink) +{ +} + +TDiagnostics::~TDiagnostics() +{ +} + +void TDiagnostics::writeInfo(Severity severity, + const pp::SourceLocation& loc, + const std::string& reason, + const std::string& token, + const std::string& extra) +{ + TInfoSinkBase& sink = mInfoSink.info; + TPrefixType prefix = severity == ERROR ? EPrefixError : EPrefixWarning; + + /* VC++ format: file(linenum) : error #: 'token' : extrainfo */ + sink.prefix(prefix); + sink.location(EncodeSourceLoc(loc.file, loc.line)); + sink << "'" << token << "' : " << reason << " " << extra << "\n"; +} + +void TDiagnostics::writeDebug(const std::string& str) +{ + mInfoSink.debug << str; +} + +void TDiagnostics::print(ID id, + const pp::SourceLocation& loc, + const std::string& text) +{ +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/Diagnostics.h b/Source/ThirdParty/ANGLE/src/compiler/Diagnostics.h new file mode 100644 index 000000000..43a13067e --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/Diagnostics.h @@ -0,0 +1,39 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_DIAGNOSTICS_H_ +#define COMPILER_DIAGNOSTICS_H_ + +#include "compiler/preprocessor/new/Diagnostics.h" + +class TInfoSink; + +class TDiagnostics : public pp::Diagnostics +{ + public: + TDiagnostics(TInfoSink& infoSink); + virtual ~TDiagnostics(); + + TInfoSink& infoSink() { return mInfoSink; } + + void writeInfo(Severity severity, + const pp::SourceLocation& loc, + const std::string& reason, + const std::string& token, + const std::string& extra); + + void writeDebug(const std::string& str); + + protected: + virtual void print(ID id, + const pp::SourceLocation& loc, + const std::string& text); + + private: + TInfoSink& mInfoSink; +}; + +#endif // COMPILER_DIAGNOSTICS_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/DirectiveHandler.cpp b/Source/ThirdParty/ANGLE/src/compiler/DirectiveHandler.cpp new file mode 100644 index 000000000..d1f6ab3af --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/DirectiveHandler.cpp @@ -0,0 +1,161 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/DirectiveHandler.h" + +#include <sstream> + +#include "compiler/debug.h" +#include "compiler/Diagnostics.h" + +static TBehavior getBehavior(const std::string& str) +{ + static const std::string kRequire("require"); + static const std::string kEnable("enable"); + static const std::string kDisable("disable"); + static const std::string kWarn("warn"); + + if (str == kRequire) return EBhRequire; + else if (str == kEnable) return EBhEnable; + else if (str == kDisable) return EBhDisable; + else if (str == kWarn) return EBhWarn; + return EBhUndefined; +} + +TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior, + TDiagnostics& diagnostics) + : mExtensionBehavior(extBehavior), + mDiagnostics(diagnostics) +{ +} + +TDirectiveHandler::~TDirectiveHandler() +{ +} + +void TDirectiveHandler::handleError(const pp::SourceLocation& loc, + const std::string& msg) +{ + mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc, msg, "", ""); +} + +void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc, + const std::string& name, + const std::string& value) +{ + static const std::string kSTDGL("STDGL"); + static const std::string kOptimize("optimize"); + static const std::string kDebug("debug"); + static const std::string kOn("on"); + static const std::string kOff("off"); + + bool invalidValue = false; + if (name == kSTDGL) + { + // The STDGL pragma is used to reserve pragmas for use by future + // revisions of GLSL. Ignore it. + return; + } + else if (name == kOptimize) + { + if (value == kOn) mPragma.optimize = true; + else if (value == kOff) mPragma.optimize = false; + else invalidValue = true; + } + else if (name == kDebug) + { + if (value == kOn) mPragma.debug = true; + else if (value == kOff) mPragma.debug = false; + else invalidValue = true; + } + else + { + mDiagnostics.report(pp::Diagnostics::UNRECOGNIZED_PRAGMA, loc, name); + return; + } + + if (invalidValue) + mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc, + "invalid pragma value", value, + "'on' or 'off' expected"); +} + +void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc, + const std::string& name, + const std::string& behavior) +{ + static const std::string kExtAll("all"); + + TBehavior behaviorVal = getBehavior(behavior); + if (behaviorVal == EBhUndefined) + { + mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc, + "behavior", name, "invalid"); + return; + } + + if (name == kExtAll) + { + if (behaviorVal == EBhRequire) + { + mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc, + "extension", name, + "cannot have 'require' behavior"); + } + else if (behaviorVal == EBhEnable) + { + mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc, + "extension", name, + "cannot have 'enable' behavior"); + } + else + { + for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin(); + iter != mExtensionBehavior.end(); ++iter) + iter->second = behaviorVal; + } + return; + } + + TExtensionBehavior::iterator iter = mExtensionBehavior.find(name); + if (iter != mExtensionBehavior.end()) + { + iter->second = behaviorVal; + return; + } + + pp::Diagnostics::Severity severity = pp::Diagnostics::ERROR; + switch (behaviorVal) { + case EBhRequire: + severity = pp::Diagnostics::ERROR; + break; + case EBhEnable: + case EBhWarn: + case EBhDisable: + severity = pp::Diagnostics::WARNING; + break; + default: + UNREACHABLE(); + break; + } + mDiagnostics.writeInfo(severity, loc, + "extension", name, "is not supported"); +} + +void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc, + int version) +{ + static const int kVersion = 100; + + if (version != kVersion) + { + std::stringstream stream; + stream << version; + std::string str = stream.str(); + mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc, + "version number", str, "not supported"); + } +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/DirectiveHandler.h b/Source/ThirdParty/ANGLE/src/compiler/DirectiveHandler.h new file mode 100644 index 000000000..21d3dfc31 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/DirectiveHandler.h @@ -0,0 +1,46 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_DIRECTIVE_HANDLER_H_ +#define COMPILER_DIRECTIVE_HANDLER_H_ + +#include "compiler/ExtensionBehavior.h" +#include "compiler/Pragma.h" +#include "compiler/preprocessor/new/DirectiveHandler.h" + +class TDiagnostics; + +class TDirectiveHandler : public pp::DirectiveHandler +{ + public: + TDirectiveHandler(TExtensionBehavior& extBehavior, + TDiagnostics& diagnostics); + virtual ~TDirectiveHandler(); + + const TPragma& pragma() const { return mPragma; } + const TExtensionBehavior& extensionBehavior() const { return mExtensionBehavior; } + + virtual void handleError(const pp::SourceLocation& loc, + const std::string& msg); + + virtual void handlePragma(const pp::SourceLocation& loc, + const std::string& name, + const std::string& value); + + virtual void handleExtension(const pp::SourceLocation& loc, + const std::string& name, + const std::string& behavior); + + virtual void handleVersion(const pp::SourceLocation& loc, + int version); + + private: + TPragma mPragma; + TExtensionBehavior& mExtensionBehavior; + TDiagnostics& mDiagnostics; +}; + +#endif // COMPILER_DIRECTIVE_HANDLER_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/ExtensionBehavior.h b/Source/ThirdParty/ANGLE/src/compiler/ExtensionBehavior.h index e9bba4b23..604098083 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/ExtensionBehavior.h +++ b/Source/ThirdParty/ANGLE/src/compiler/ExtensionBehavior.h @@ -7,9 +7,11 @@ #ifndef _EXTENSION_BEHAVIOR_INCLUDED_ #define _EXTENSION_BEHAVIOR_INCLUDED_ -#include "compiler/Common.h" +#include <map> +#include <string> -typedef enum { +typedef enum +{ EBhRequire, EBhEnable, EBhWarn, @@ -19,20 +21,17 @@ typedef enum { inline const char* getBehaviorString(TBehavior b) { - switch(b) { - case EBhRequire: - return "require"; - case EBhEnable: - return "enable"; - case EBhWarn: - return "warn"; - case EBhDisable: - return "disable"; - default: - return NULL; + switch(b) + { + case EBhRequire: return "require"; + case EBhEnable: return "enable"; + case EBhWarn: return "warn"; + case EBhDisable: return "disable"; + default: return NULL; } } -typedef TMap<TString, TBehavior> TExtensionBehavior; +// Mapping between extension name and behavior. +typedef std::map<std::string, TBehavior> TExtensionBehavior; #endif // _EXTENSION_TABLE_INCLUDED_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/Initialize.cpp b/Source/ThirdParty/ANGLE/src/compiler/Initialize.cpp index f3a19dc13..3e94ce7ba 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/Initialize.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/Initialize.cpp @@ -475,7 +475,7 @@ static TString DefaultPrecisionFragment() // Implementation dependent built-in constants. // //============================================================================ -static TString BuiltInConstants(const ShBuiltInResources &resources) +static TString BuiltInConstants(ShShaderSpec spec, const ShBuiltInResources &resources) { TStringStream s; @@ -487,7 +487,9 @@ static TString BuiltInConstants(const ShBuiltInResources &resources) s << "const int gl_MaxCombinedTextureImageUnits = " << resources.MaxCombinedTextureImageUnits << ";"; s << "const int gl_MaxTextureImageUnits = " << resources.MaxTextureImageUnits << ";"; s << "const int gl_MaxFragmentUniformVectors = " << resources.MaxFragmentUniformVectors << ";"; - s << "const int gl_MaxDrawBuffers = " << resources.MaxDrawBuffers << ";"; + + if (spec != SH_CSS_SHADERS_SPEC) + s << "const int gl_MaxDrawBuffers = " << resources.MaxDrawBuffers << ";"; return s.str(); } @@ -513,7 +515,7 @@ void TBuiltIns::initialize(ShShaderType type, ShShaderSpec spec, default: assert(false && "Language not supported"); } - builtInStrings.push_back(BuiltInConstants(resources)); + builtInStrings.push_back(BuiltInConstants(spec, resources)); } void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec, @@ -526,11 +528,22 @@ void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec, // switch(type) { case SH_FRAGMENT_SHADER: - symbolTable.insert(*new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord, 4))); - symbolTable.insert(*new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool, EbpUndefined, EvqFrontFacing, 1))); - symbolTable.insert(*new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4))); - symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4))); - symbolTable.insert(*new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord, 2))); + symbolTable.insert(*new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord, 4))); + symbolTable.insert(*new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool, EbpUndefined, EvqFrontFacing, 1))); + symbolTable.insert(*new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord, 2))); + + // + // In CSS Shaders, gl_FragColor, gl_FragData, and gl_MaxDrawBuffers are not available. + // Instead, css_MixColor and css_ColorMatrix are available. + // + if (spec != SH_CSS_SHADERS_SPEC) { + symbolTable.insert(*new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4))); + symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4))); + } else { + symbolTable.insert(*new TVariable(NewPoolTString("css_MixColor"), TType(EbtFloat, EbpMedium, EvqGlobal, 4))); + symbolTable.insert(*new TVariable(NewPoolTString("css_ColorMatrix"), TType(EbtFloat, EbpMedium, EvqGlobal, 4, true))); + } + break; case SH_VERTEX_SHADER: @@ -620,7 +633,8 @@ void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec, // Finally add resource-specific variables. switch(type) { - case SH_FRAGMENT_SHADER: { + case SH_FRAGMENT_SHADER: + if (spec != SH_CSS_SHADERS_SPEC) { // Set up gl_FragData. The array size. TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, false, true); fragData.setArraySize(resources.MaxDrawBuffers); diff --git a/Source/ThirdParty/ANGLE/src/compiler/InitializeParseContext.cpp b/Source/ThirdParty/ANGLE/src/compiler/InitializeParseContext.cpp new file mode 100644 index 000000000..1f40cf580 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/InitializeParseContext.cpp @@ -0,0 +1,96 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/InitializeParseContext.h" + +#include "compiler/osinclude.h" + +OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX; + +bool InitializeParseContextIndex() +{ + if (GlobalParseContextIndex != OS_INVALID_TLS_INDEX) { + assert(0 && "InitializeParseContextIndex(): Parse Context already initalized"); + return false; + } + + // + // Allocate a TLS index. + // + GlobalParseContextIndex = OS_AllocTLSIndex(); + + if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) { + assert(0 && "InitializeParseContextIndex(): Parse Context already initalized"); + return false; + } + + return true; +} + +bool FreeParseContextIndex() +{ + OS_TLSIndex tlsiIndex = GlobalParseContextIndex; + + if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) { + assert(0 && "FreeParseContextIndex(): Parse Context index not initalized"); + return false; + } + + GlobalParseContextIndex = OS_INVALID_TLS_INDEX; + + return OS_FreeTLSIndex(tlsiIndex); +} + +bool InitializeGlobalParseContext() +{ + if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) { + assert(0 && "InitializeGlobalParseContext(): Parse Context index not initalized"); + return false; + } + + TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex)); + if (lpParseContext != 0) { + assert(0 && "InitializeParseContextIndex(): Parse Context already initalized"); + return false; + } + + TThreadParseContext *lpThreadData = new TThreadParseContext(); + if (lpThreadData == 0) { + assert(0 && "InitializeGlobalParseContext(): Unable to create thread parse context"); + return false; + } + + lpThreadData->lpGlobalParseContext = 0; + OS_SetTLSValue(GlobalParseContextIndex, lpThreadData); + + return true; +} + +bool FreeParseContext() +{ + if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) { + assert(0 && "FreeParseContext(): Parse Context index not initalized"); + return false; + } + + TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex)); + if (lpParseContext) + delete lpParseContext; + + return true; +} + +TParseContextPointer& GetGlobalParseContext() +{ + // + // Minimal error checking for speed + // + + TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex)); + + return lpParseContext->lpGlobalParseContext; +} + diff --git a/Source/ThirdParty/ANGLE/src/compiler/InitializeParseContext.h b/Source/ThirdParty/ANGLE/src/compiler/InitializeParseContext.h index 760fd09d5..aa53b735d 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/InitializeParseContext.h +++ b/Source/ThirdParty/ANGLE/src/compiler/InitializeParseContext.h @@ -13,4 +13,14 @@ bool FreeParseContextIndex(); bool InitializeGlobalParseContext(); bool FreeParseContext(); +struct TParseContext; +typedef TParseContext* TParseContextPointer; +extern TParseContextPointer& GetGlobalParseContext(); +#define GlobalParseContext GetGlobalParseContext() + +typedef struct TThreadParseContextRec +{ + TParseContext *lpGlobalParseContext; +} TThreadParseContext; + #endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp b/Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp index ca6d8f746..92c450530 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -373,7 +373,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, // their operator to EOpSequence. // // Returns an aggregate node, which could be the one passed in if -// it was already an aggregate. +// it was already an aggregate but no operator was set. // TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, TSourceLoc line) { @@ -592,10 +592,10 @@ TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nod // if (cond->getAsTyped() && cond->getAsTyped()->getAsConstantUnion()) { - if (cond->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getBConst()) - return nodePair.node1; + if (cond->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getBConst() == true) + return nodePair.node1 ? setAggregateOperator(nodePair.node1, EOpSequence, nodePair.node1->getLine()) : NULL; else - return nodePair.node2; + return nodePair.node2 ? setAggregateOperator(nodePair.node2, EOpSequence, nodePair.node2->getLine()) : NULL; } TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2); @@ -656,6 +656,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true // Make a selection node. // TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType()); + node->getTypePointer()->setQualifier(EvqTemporary); node->setLine(line); return node; @@ -1444,9 +1445,3 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC return addConstantUnion(leftUnionArray, TType(promoteTo, t.getPrecision(), t.getQualifier(), t.getNominalSize(), t.isMatrix(), t.isArray()), node->getLine()); } -void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable) -{ - assert(!pragmaTable); - pragmaTable = new TPragmaTable(); - *pragmaTable = pTable; -} diff --git a/Source/ThirdParty/ANGLE/src/compiler/MapLongVariableNames.cpp b/Source/ThirdParty/ANGLE/src/compiler/MapLongVariableNames.cpp index 0c7e1a9cb..a50310154 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/MapLongVariableNames.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/MapLongVariableNames.cpp @@ -15,7 +15,9 @@ TString mapLongName(int id, const TString& name, bool isGlobal) stream << "webgl_"; if (isGlobal) stream << "g"; - stream << id << "_"; + stream << id; + if (name[0] != '_') + stream << "_"; stream << name.substr(0, MAX_SHORTENED_IDENTIFIER_SIZE - stream.str().size()); return stream.str(); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.cpp index 69b8c26b8..d7e69d357 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.cpp @@ -6,10 +6,12 @@ #include "compiler/OutputHLSL.h" +#include "common/angleutils.h" #include "compiler/debug.h" #include "compiler/InfoSink.h" -#include "compiler/UnfoldSelect.h" +#include "compiler/UnfoldShortCircuit.h" #include "compiler/SearchSymbol.h" +#include "compiler/DetectDiscontinuity.h" #include <stdio.h> #include <algorithm> @@ -20,13 +22,13 @@ namespace sh TString str(int i) { char buffer[20]; - sprintf(buffer, "%d", i); + snprintf(buffer, sizeof(buffer), "%d", i); return buffer; } OutputHLSL::OutputHLSL(TParseContext &context) : TIntermTraverser(true, true, true), mContext(context) { - mUnfoldSelect = new UnfoldSelect(context, this); + mUnfoldShortCircuit = new UnfoldShortCircuit(context, this); mInsideFunction = false; mUsesTexture2D = false; @@ -38,6 +40,12 @@ OutputHLSL::OutputHLSL(TParseContext &context) : TIntermTraverser(true, true, tr mUsesTextureCube = false; mUsesTextureCube_bias = false; mUsesTextureCubeLod = false; + mUsesTexture2DLod0 = false; + mUsesTexture2DLod0_bias = false; + mUsesTexture2DProjLod0 = false; + mUsesTexture2DProjLod0_bias = false; + mUsesTextureCubeLod0 = false; + mUsesTextureCubeLod0_bias = false; mUsesDepthRange = false; mUsesFragCoord = false; mUsesPointCoord = false; @@ -75,20 +83,26 @@ OutputHLSL::OutputHLSL(TParseContext &context) : TIntermTraverser(true, true, tr mScopeDepth = 0; mUniqueIndex = 0; + + mContainsLoopDiscontinuity = false; + mOutputLod0Function = false; + mInsideDiscontinuousLoop = false; } OutputHLSL::~OutputHLSL() { - delete mUnfoldSelect; + delete mUnfoldShortCircuit; } void OutputHLSL::output() { + mContainsLoopDiscontinuity = containsLoopDiscontinuity(mContext.treeRoot); + mContext.treeRoot->traverse(this); // Output the body first to determine what has to go in the header header(); - mContext.infoSink.obj << mHeader.c_str(); - mContext.infoSink.obj << mBody.c_str(); + mContext.infoSink().obj << mHeader.c_str(); + mContext.infoSink().obj << mBody.c_str(); } TInfoSinkBase &OutputHLSL::getBodyStream() @@ -205,25 +219,11 @@ void OutputHLSL::header() out << uniforms; out << "\n"; - // The texture fetch functions "flip" the Y coordinate in one way or another. This is because textures are stored - // according to the OpenGL convention, i.e. (0, 0) is "bottom left", rather than the D3D convention where (0, 0) - // is "top left". Since the HLSL texture fetch functions expect textures to be stored according to the D3D - // convention, the Y coordinate passed to these functions is adjusted to compensate. - // - // The simplest case is texture2D where the mapping is Y -> 1-Y, which maps [0, 1] -> [1, 0]. - // - // The texture2DProj functions are more complicated because the projection divides by either Z or W. For the vec3 - // case, the mapping is Y -> Z-Y or Y/Z -> 1-Y/Z, which again maps [0, 1] -> [1, 0]. - // - // For cube textures the mapping is Y -> -Y, which maps [-1, 1] -> [1, -1]. This is not sufficient on its own for the - // +Y and -Y faces, which are now on the "wrong sides" of the cube. This is compensated for by exchanging the - // +Y and -Y faces everywhere else throughout the code. - if (mUsesTexture2D) { out << "float4 gl_texture2D(sampler2D s, float2 t)\n" "{\n" - " return tex2D(s, float2(t.x, 1 - t.y));\n" + " return tex2D(s, t);\n" "}\n" "\n"; } @@ -232,7 +232,7 @@ void OutputHLSL::header() { out << "float4 gl_texture2D(sampler2D s, float2 t, float bias)\n" "{\n" - " return tex2Dbias(s, float4(t.x, 1 - t.y, 0, bias));\n" + " return tex2Dbias(s, float4(t.x, t.y, 0, bias));\n" "}\n" "\n"; } @@ -241,12 +241,12 @@ void OutputHLSL::header() { out << "float4 gl_texture2DProj(sampler2D s, float3 t)\n" "{\n" - " return tex2Dproj(s, float4(t.x, t.z - t.y, 0, t.z));\n" + " return tex2Dproj(s, float4(t.x, t.y, 0, t.z));\n" "}\n" "\n" "float4 gl_texture2DProj(sampler2D s, float4 t)\n" "{\n" - " return tex2Dproj(s, float4(t.x, t.w - t.y, t.z, t.w));\n" + " return tex2Dproj(s, t);\n" "}\n" "\n"; } @@ -255,12 +255,12 @@ void OutputHLSL::header() { out << "float4 gl_texture2DProj(sampler2D s, float3 t, float bias)\n" "{\n" - " return tex2Dbias(s, float4(t.x / t.z, 1 - (t.y / t.z), 0, bias));\n" + " return tex2Dbias(s, float4(t.x / t.z, t.y / t.z, 0, bias));\n" "}\n" "\n" "float4 gl_texture2DProj(sampler2D s, float4 t, float bias)\n" "{\n" - " return tex2Dbias(s, float4(t.x / t.w, 1 - (t.y / t.w), 0, bias));\n" + " return tex2Dbias(s, float4(t.x / t.w, t.y / t.w, 0, bias));\n" "}\n" "\n"; } @@ -269,7 +269,7 @@ void OutputHLSL::header() { out << "float4 gl_textureCube(samplerCUBE s, float3 t)\n" "{\n" - " return texCUBE(s, float3(t.x, -t.y, t.z));\n" + " return texCUBE(s, t);\n" "}\n" "\n"; } @@ -278,7 +278,73 @@ void OutputHLSL::header() { out << "float4 gl_textureCube(samplerCUBE s, float3 t, float bias)\n" "{\n" - " return texCUBEbias(s, float4(t.x, -t.y, t.z, bias));\n" + " return texCUBEbias(s, float4(t.x, t.y, t.z, bias));\n" + "}\n" + "\n"; + } + + // These *Lod0 intrinsics are not available in GL fragment shaders. + // They are used to sample using discontinuous texture coordinates. + if (mUsesTexture2DLod0) + { + out << "float4 gl_texture2DLod0(sampler2D s, float2 t)\n" + "{\n" + " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n" + "}\n" + "\n"; + } + + if (mUsesTexture2DLod0_bias) + { + out << "float4 gl_texture2DLod0(sampler2D s, float2 t, float bias)\n" + "{\n" + " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n" + "}\n" + "\n"; + } + + if (mUsesTexture2DProjLod0) + { + out << "float4 gl_texture2DProjLod0(sampler2D s, float3 t)\n" + "{\n" + " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n" + "}\n" + "\n" + "float4 gl_texture2DProjLod(sampler2D s, float4 t)\n" + "{\n" + " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n" + "}\n" + "\n"; + } + + if (mUsesTexture2DProjLod0_bias) + { + out << "float4 gl_texture2DProjLod0_bias(sampler2D s, float3 t, float bias)\n" + "{\n" + " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n" + "}\n" + "\n" + "float4 gl_texture2DProjLod_bias(sampler2D s, float4 t, float bias)\n" + "{\n" + " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n" + "}\n" + "\n"; + } + + if (mUsesTextureCubeLod0) + { + out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t)\n" + "{\n" + " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n" + "}\n" + "\n"; + } + + if (mUsesTextureCubeLod0_bias) + { + out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t, float bias)\n" + "{\n" + " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n" "}\n" "\n"; } @@ -897,7 +963,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) case EOpIndexDirectStruct: if (visit == InVisit) { - out << "." + node->getType().getFieldName(); + out << "." + decorateField(node->getType().getFieldName(), node->getLeft()->getType()); return false; } @@ -973,9 +1039,9 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) const TType *fieldType = (*fields)[i].type; node->getLeft()->traverse(this); - out << "." + fieldType->getFieldName() + " == "; + out << "." + decorateField(fieldType->getFieldName(), node->getLeft()->getType()) + " == "; node->getRight()->traverse(this); - out << "." + fieldType->getFieldName(); + out << "." + decorateField(fieldType->getFieldName(), node->getLeft()->getType()); if (i < fields->size() - 1) { @@ -1054,12 +1120,16 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) case EOpVectorTimesMatrix: outputTriplet(visit, "mul(", ", transpose(", "))"); break; case EOpMatrixTimesVector: outputTriplet(visit, "mul(transpose(", "), ", ")"); break; case EOpMatrixTimesMatrix: outputTriplet(visit, "transpose(mul(transpose(", "), transpose(", ")))"); break; - case EOpLogicalOr: outputTriplet(visit, "(", " || ", ")"); break; + case EOpLogicalOr: + out << "s" << mUnfoldShortCircuit->getNextTemporaryIndex(); + return false; case EOpLogicalXor: mUsesXor = true; outputTriplet(visit, "xor(", ", ", ")"); break; - case EOpLogicalAnd: outputTriplet(visit, "(", " && ", ")"); break; + case EOpLogicalAnd: + out << "s" << mUnfoldShortCircuit->getNextTemporaryIndex(); + return false; default: UNREACHABLE(); } @@ -1131,9 +1201,36 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node) case EOpFract: outputTriplet(visit, "frac(", "", ")"); break; case EOpLength: outputTriplet(visit, "length(", "", ")"); break; case EOpNormalize: outputTriplet(visit, "normalize(", "", ")"); break; - case EOpDFdx: outputTriplet(visit, "ddx(", "", ")"); break; - case EOpDFdy: outputTriplet(visit, "(-ddy(", "", "))"); break; - case EOpFwidth: outputTriplet(visit, "fwidth(", "", ")"); break; + case EOpDFdx: + if(mInsideDiscontinuousLoop || mOutputLod0Function) + { + outputTriplet(visit, "(", "", ", 0.0)"); + } + else + { + outputTriplet(visit, "ddx(", "", ")"); + } + break; + case EOpDFdy: + if(mInsideDiscontinuousLoop || mOutputLod0Function) + { + outputTriplet(visit, "(", "", ", 0.0)"); + } + else + { + outputTriplet(visit, "ddy(", "", ")"); + } + break; + case EOpFwidth: + if(mInsideDiscontinuousLoop || mOutputLod0Function) + { + outputTriplet(visit, "(", "", ", 0.0)"); + } + else + { + outputTriplet(visit, "fwidth(", "", ")"); + } + break; case EOpAny: outputTriplet(visit, "any(", "", ")"); break; case EOpAll: outputTriplet(visit, "all(", "", ")"); break; default: UNREACHABLE(); @@ -1171,12 +1268,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) { outputLineDirective((*sit)->getLine()); - if (isSingleStatement(*sit)) - { - mUnfoldSelect->traverse(*sit); - } - - (*sit)->traverse(this); + traverseStatements(*sit); out << ";\n"; } @@ -1290,59 +1382,64 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) { TString name = TFunction::unmangleName(node->getName()); - if (visit == PreVisit) + out << typeString(node->getType()) << " "; + + if (name == "main") + { + out << "gl_main("; + } + else { - out << typeString(node->getType()) << " "; + out << decorate(name) << (mOutputLod0Function ? "Lod0(" : "("); + } - if (name == "main") - { - out << "gl_main("; - } - else - { - out << decorate(name) << "("; - } + TIntermSequence &sequence = node->getSequence(); + TIntermSequence &arguments = sequence[0]->getAsAggregate()->getSequence(); - TIntermSequence &sequence = node->getSequence(); - TIntermSequence &arguments = sequence[0]->getAsAggregate()->getSequence(); + for (unsigned int i = 0; i < arguments.size(); i++) + { + TIntermSymbol *symbol = arguments[i]->getAsSymbolNode(); - for (unsigned int i = 0; i < arguments.size(); i++) + if (symbol) { - TIntermSymbol *symbol = arguments[i]->getAsSymbolNode(); - - if (symbol) + if (symbol->getType().getStruct()) { - if (symbol->getType().getStruct()) - { - addConstructor(symbol->getType(), scopedStruct(symbol->getType().getTypeName()), NULL); - } + addConstructor(symbol->getType(), scopedStruct(symbol->getType().getTypeName()), NULL); + } - out << argumentString(symbol); + out << argumentString(symbol); - if (i < arguments.size() - 1) - { - out << ", "; - } + if (i < arguments.size() - 1) + { + out << ", "; } - else UNREACHABLE(); } + else UNREACHABLE(); + } - sequence.erase(sequence.begin()); - - out << ")\n"; - - outputLineDirective(node->getLine()); - out << "{\n"; - + out << ")\n" + "{\n"; + + if (sequence.size() > 1) + { mInsideFunction = true; + sequence[1]->traverse(this); + mInsideFunction = false; } - else if (visit == PostVisit) - { - outputLineDirective(node->getEndLine()); - out << "}\n"; + + out << "}\n"; - mInsideFunction = false; + if (mContainsLoopDiscontinuity && !mOutputLod0Function) + { + if (name != "main") + { + mOutputLod0Function = true; + node->traverse(this); + mOutputLod0Function = false; + } } + + return false; } break; case EOpFunctionCall: @@ -1350,54 +1447,106 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) if (visit == PreVisit) { TString name = TFunction::unmangleName(node->getName()); + bool lod0 = mInsideDiscontinuousLoop || mOutputLod0Function; if (node->isUserDefined()) { - out << decorate(name) << "("; + out << decorate(name) << (lod0 ? "Lod0(" : "("); } else { if (name == "texture2D") { - if (node->getSequence().size() == 2) + if (!lod0) { - mUsesTexture2D = true; + if (node->getSequence().size() == 2) + { + mUsesTexture2D = true; + } + else if (node->getSequence().size() == 3) + { + mUsesTexture2D_bias = true; + } + else UNREACHABLE(); + + out << "gl_texture2D("; } - else if (node->getSequence().size() == 3) + else { - mUsesTexture2D_bias = true; - } - else UNREACHABLE(); + if (node->getSequence().size() == 2) + { + mUsesTexture2DLod0 = true; + } + else if (node->getSequence().size() == 3) + { + mUsesTexture2DLod0_bias = true; + } + else UNREACHABLE(); - out << "gl_texture2D("; + out << "gl_texture2DLod0("; + } } else if (name == "texture2DProj") { - if (node->getSequence().size() == 2) + if (!lod0) { - mUsesTexture2DProj = true; + if (node->getSequence().size() == 2) + { + mUsesTexture2DProj = true; + } + else if (node->getSequence().size() == 3) + { + mUsesTexture2DProj_bias = true; + } + else UNREACHABLE(); + + out << "gl_texture2DProj("; } - else if (node->getSequence().size() == 3) + else { - mUsesTexture2DProj_bias = true; - } - else UNREACHABLE(); + if (node->getSequence().size() == 2) + { + mUsesTexture2DProjLod0 = true; + } + else if (node->getSequence().size() == 3) + { + mUsesTexture2DProjLod0_bias = true; + } + else UNREACHABLE(); - out << "gl_texture2DProj("; + out << "gl_texture2DProjLod0("; + } } else if (name == "textureCube") { - if (node->getSequence().size() == 2) + if (!lod0) { - mUsesTextureCube = true; + if (node->getSequence().size() == 2) + { + mUsesTextureCube = true; + } + else if (node->getSequence().size() == 3) + { + mUsesTextureCube_bias = true; + } + else UNREACHABLE(); + + out << "gl_textureCube("; } - else if (node->getSequence().size() == 3) + else { - mUsesTextureCube_bias = true; - } - else UNREACHABLE(); + if (node->getSequence().size() == 2) + { + mUsesTextureCubeLod0 = true; + } + else if (node->getSequence().size() == 3) + { + mUsesTextureCubeLod0_bias = true; + } + else UNREACHABLE(); - out << "gl_textureCube("; + out << "gl_textureCubeLod0("; + } } else if (name == "texture2DLod") { @@ -1583,11 +1732,11 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) if (node->usesTernaryOperator()) { - out << "s" << mUnfoldSelect->getNextTemporaryIndex(); + out << "s" << mUnfoldShortCircuit->getNextTemporaryIndex(); } else // if/else statement { - mUnfoldSelect->traverse(node->getCondition()); + mUnfoldShortCircuit->traverse(node->getCondition()); out << "if("; @@ -1600,11 +1749,11 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) if (node->getTrueBlock()) { - node->getTrueBlock()->traverse(this); + traverseStatements(node->getTrueBlock()); } outputLineDirective(node->getLine()); - out << ";}\n"; + out << ";\n}\n"; if (node->getFalseBlock()) { @@ -1614,10 +1763,10 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) out << "{\n"; outputLineDirective(node->getFalseBlock()->getLine()); - node->getFalseBlock()->traverse(this); + traverseStatements(node->getFalseBlock()); outputLineDirective(node->getFalseBlock()->getLine()); - out << ";}\n"; + out << ";\n}\n"; } } @@ -1631,6 +1780,13 @@ void OutputHLSL::visitConstantUnion(TIntermConstantUnion *node) bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) { + bool wasDiscontinuous = mInsideDiscontinuousLoop; + + if (!mInsideDiscontinuousLoop) + { + mInsideDiscontinuousLoop = containsLoopDiscontinuity(node); + } + if (handleExcessiveLoop(node)) { return false; @@ -1676,7 +1832,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) if (node->getBody()) { - node->getBody()->traverse(this); + traverseStatements(node->getBody()); } outputLineDirective(node->getLine()); @@ -1694,6 +1850,8 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) out << "}\n"; + mInsideDiscontinuousLoop = wasDiscontinuous; + return false; } @@ -1732,6 +1890,16 @@ bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node) return true; } +void OutputHLSL::traverseStatements(TIntermNode *node) +{ + if (isSingleStatement(node)) + { + mUnfoldShortCircuit->traverse(node); + } + + node->traverse(this); +} + bool OutputHLSL::isSingleStatement(TIntermNode *node) { TIntermAggregate *aggregate = node->getAsAggregate(); @@ -1759,9 +1927,11 @@ bool OutputHLSL::isSingleStatement(TIntermNode *node) return true; } -// Handle loops with more than 255 iterations (unsupported by D3D9) by splitting them +// Handle loops with more than 254 iterations (unsupported by D3D9) by splitting them +// (The D3D documentation says 255 iterations, but the compiler complains at anything more than 254). bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) { + const int MAX_LOOP_ITERATIONS = 254; TInfoSinkBase &out = mBody; // Parse loops of the form: @@ -1877,14 +2047,14 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) { int iterations = (limit - initial) / increment; - if (iterations <= 255) + if (iterations <= MAX_LOOP_ITERATIONS) { return false; // Not an excessive loop } while (iterations > 0) { - int clampedLimit = initial + increment * std::min(255, iterations); + int clampedLimit = initial + increment * std::min(MAX_LOOP_ITERATIONS, iterations); // for(int index = initial; index < clampedLimit; index += increment) @@ -1915,8 +2085,8 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) outputLineDirective(node->getLine()); out << ";}\n"; - initial += 255 * increment; - iterations -= 255; + initial += MAX_LOOP_ITERATIONS * increment; + iterations -= MAX_LOOP_ITERATIONS; } return true; @@ -2012,7 +2182,7 @@ TString OutputHLSL::typeString(const TType &type) { const TType &field = *fields[i].type; - string += " " + typeString(field) + " " + field.getFieldName() + arrayString(field) + ";\n"; + string += " " + typeString(field) + " " + decorate(field.getFieldName()) + arrayString(field) + ";\n"; } string += "} "; @@ -2065,6 +2235,8 @@ TString OutputHLSL::typeString(const TType &type) return "samplerCUBE"; case EbtSamplerExternalOES: return "sampler2D"; + default: + break; } } @@ -2135,7 +2307,7 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI { const TType &field = *fields[i].type; - structure += " " + typeString(field) + " " + field.getFieldName() + arrayString(field) + ";\n"; + structure += " " + typeString(field) + " " + decorateField(field.getFieldName(), type) + arrayString(field) + ";\n"; } structure += "};\n"; @@ -2434,4 +2606,14 @@ TString OutputHLSL::decorateUniform(const TString &string, const TType &type) return decorate(string); } + +TString OutputHLSL::decorateField(const TString &string, const TType &structure) +{ + if (structure.getTypeName().compare(0, 3, "gl_") != 0) + { + return decorate(string); + } + + return string; +} } diff --git a/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.h b/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.h index 824bc071b..ea28a3c9d 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.h +++ b/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.h @@ -15,7 +15,7 @@ namespace sh { -class UnfoldSelect; +class UnfoldShortCircuit; class OutputHLSL : public TIntermTraverser { @@ -33,6 +33,7 @@ class OutputHLSL : public TIntermTraverser static TString initializer(const TType &type); static TString decorate(const TString &string); // Prepends an underscore to avoid naming clashes static TString decorateUniform(const TString &string, const TType &type); + static TString decorateField(const TString &string, const TType &structure); protected: void header(); @@ -47,6 +48,7 @@ class OutputHLSL : public TIntermTraverser bool visitLoop(Visit visit, TIntermLoop*); bool visitBranch(Visit visit, TIntermBranch*); + void traverseStatements(TIntermNode *node); bool isSingleStatement(TIntermNode *node); bool handleExcessiveLoop(TIntermLoop *node); void outputTriplet(Visit visit, const TString &preString, const TString &inString, const TString &postString); @@ -62,7 +64,7 @@ class OutputHLSL : public TIntermTraverser TString structLookup(const TString &typeName); TParseContext &mContext; - UnfoldSelect *mUnfoldSelect; + UnfoldShortCircuit *mUnfoldShortCircuit; bool mInsideFunction; // Output streams @@ -84,6 +86,12 @@ class OutputHLSL : public TIntermTraverser bool mUsesTextureCube; bool mUsesTextureCube_bias; bool mUsesTextureCubeLod; + bool mUsesTexture2DLod0; + bool mUsesTexture2DLod0_bias; + bool mUsesTexture2DProjLod0; + bool mUsesTexture2DProjLod0_bias; + bool mUsesTextureCubeLod0; + bool mUsesTextureCubeLod0_bias; bool mUsesDepthRange; bool mUsesFragCoord; bool mUsesPointCoord; @@ -132,6 +140,10 @@ class OutputHLSL : public TIntermTraverser unsigned int mScopeDepth; int mUniqueIndex; // For creating unique names + + bool mContainsLoopDiscontinuity; + bool mOutputLod0Function; + bool mInsideDiscontinuousLoop; }; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.cpp b/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.cpp index 431f8d1ce..79bddeabf 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -10,33 +10,7 @@ #include <stdio.h> #include "compiler/glslang.h" -#include "compiler/osinclude.h" -#include "compiler/InitializeParseContext.h" - -extern "C" { -extern int InitPreprocessor(); -extern int FinalizePreprocessor(); -extern void PredefineIntMacro(const char *name, int value); -} - -static void ReportInfo(TInfoSinkBase& sink, - TPrefixType type, TSourceLoc loc, - const char* reason, const char* token, - const char* extraInfo) -{ - /* VC++ format: file(linenum) : error #: 'token' : extrainfo */ - sink.prefix(type); - sink.location(loc); - sink << "'" << token << "' : " << reason << " " << extraInfo << "\n"; -} - -static void DefineExtensionMacros(const TExtensionBehavior& extBehavior) -{ - for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); - iter != extBehavior.end(); ++iter) { - PredefineIntMacro(iter->first.c_str(), 1); - } -} +#include "compiler/preprocessor/new/SourceLocation.h" /////////////////////////////////////////////////////////////////////// // @@ -52,7 +26,7 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV { fields.num = (int) compString.size(); if (fields.num > 4) { - error(line, "illegal vector field selection", compString.c_str(), ""); + error(line, "illegal vector field selection", compString.c_str()); return false; } @@ -114,20 +88,20 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV fieldSet[i] = estpq; break; default: - error(line, "illegal vector field selection", compString.c_str(), ""); + error(line, "illegal vector field selection", compString.c_str()); return false; } } for (int i = 0; i < fields.num; ++i) { if (fields.offsets[i] >= vecSize) { - error(line, "vector field selection out of range", compString.c_str(), ""); + error(line, "vector field selection out of range", compString.c_str()); return false; } if (i > 0) { if (fieldSet[i] != fieldSet[i-1]) { - error(line, "illegal - vector component fields not from the same set", compString.c_str(), ""); + error(line, "illegal - vector component fields not from the same set", compString.c_str()); return false; } } @@ -149,20 +123,20 @@ bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TM fields.col = -1; if (compString.size() != 2) { - error(line, "illegal length of matrix field selection", compString.c_str(), ""); + error(line, "illegal length of matrix field selection", compString.c_str()); return false; } if (compString[0] == '_') { if (compString[1] < '0' || compString[1] > '3') { - error(line, "illegal matrix field selection", compString.c_str(), ""); + error(line, "illegal matrix field selection", compString.c_str()); return false; } fields.wholeCol = true; fields.col = compString[1] - '0'; } else if (compString[1] == '_') { if (compString[0] < '0' || compString[0] > '3') { - error(line, "illegal matrix field selection", compString.c_str(), ""); + error(line, "illegal matrix field selection", compString.c_str()); return false; } fields.wholeRow = true; @@ -170,7 +144,7 @@ bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TM } else { if (compString[0] < '0' || compString[0] > '3' || compString[1] < '0' || compString[1] > '3') { - error(line, "illegal matrix field selection", compString.c_str(), ""); + error(line, "illegal matrix field selection", compString.c_str()); return false; } fields.row = compString[0] - '0'; @@ -178,7 +152,7 @@ bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TM } if (fields.row >= matSize || fields.col >= matSize) { - error(line, "matrix field selection out of range", compString.c_str(), ""); + error(line, "matrix field selection out of range", compString.c_str()); return false; } @@ -203,30 +177,28 @@ void TParseContext::recover() // void TParseContext::error(TSourceLoc loc, const char* reason, const char* token, - const char* extraInfoFormat, ...) + const char* extraInfo) { - char extraInfo[512]; - va_list marker; - va_start(marker, extraInfoFormat); - vsnprintf(extraInfo, sizeof(extraInfo), extraInfoFormat, marker); + pp::SourceLocation srcLoc; + DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line); + diagnostics.writeInfo(pp::Diagnostics::ERROR, + srcLoc, reason, token, extraInfo); - ReportInfo(infoSink.info, EPrefixError, loc, reason, token, extraInfo); - - va_end(marker); ++numErrors; } void TParseContext::warning(TSourceLoc loc, const char* reason, const char* token, - const char* extraInfoFormat, ...) { - char extraInfo[512]; - va_list marker; - va_start(marker, extraInfoFormat); - vsnprintf(extraInfo, sizeof(extraInfo), extraInfoFormat, marker); - - ReportInfo(infoSink.info, EPrefixWarning, loc, reason, token, extraInfo); + const char* extraInfo) { + pp::SourceLocation srcLoc; + DecodeSourceLoc(loc, &srcLoc.file, &srcLoc.line); + diagnostics.writeInfo(pp::Diagnostics::WARNING, + srcLoc, reason, token, extraInfo); +} - va_end(marker); +void TParseContext::trace(const char* str) +{ + diagnostics.writeDebug(str); } // @@ -234,8 +206,10 @@ void TParseContext::warning(TSourceLoc loc, // void TParseContext::assignError(int line, const char* op, TString left, TString right) { - error(line, "", op, "cannot convert from '%s' to '%s'", - right.c_str(), left.c_str()); + std::stringstream extraInfoStream; + extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'"; + std::string extraInfo = extraInfoStream.str(); + error(line, "", op, extraInfo.c_str()); } // @@ -243,9 +217,11 @@ void TParseContext::assignError(int line, const char* op, TString left, TString // void TParseContext::unaryOpError(int line, const char* op, TString operand) { - error(line, " wrong operand type", op, - "no operation '%s' exists that takes an operand of type %s (or there is no acceptable conversion)", - op, operand.c_str()); + std::stringstream extraInfoStream; + extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " << operand + << " (or there is no acceptable conversion)"; + std::string extraInfo = extraInfoStream.str(); + error(line, " wrong operand type", op, extraInfo.c_str()); } // @@ -253,10 +229,11 @@ void TParseContext::unaryOpError(int line, const char* op, TString operand) // void TParseContext::binaryOpError(int line, const char* op, TString left, TString right) { - error(line, " wrong operand types ", op, - "no operation '%s' exists that takes a left-hand operand of type '%s' and " - "a right operand of type '%s' (or there is no acceptable conversion)", - op, left.c_str(), right.c_str()); + std::stringstream extraInfoStream; + extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left + << "' and a right operand of type '" << right << "' (or there is no acceptable conversion)"; + std::string extraInfo = extraInfoStream.str(); + error(line, " wrong operand types ", op, extraInfo.c_str()); } bool TParseContext::precisionErrorCheck(int line, TPrecision precision, TBasicType type){ @@ -265,13 +242,13 @@ bool TParseContext::precisionErrorCheck(int line, TPrecision precision, TBasicTy switch( type ){ case EbtFloat: if( precision == EbpUndefined ){ - error( line, "No precision specified for (float)", "", "" ); + error( line, "No precision specified for (float)", "" ); return true; } break; case EbtInt: if( precision == EbpUndefined ){ - error( line, "No precision specified (int)", "", "" ); + error( line, "No precision specified (int)", "" ); return true; } break; @@ -313,7 +290,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod int value = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getIConst(); offset[value]++; if (offset[value] > 1) { - error(line, " l-value of swizzle cannot have duplicate components", op, "", ""); + error(line, " l-value of swizzle cannot have duplicate components", op); return true; } @@ -324,7 +301,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod default: break; } - error(line, " l-value required", op, "", ""); + error(line, " l-value required", op); return true; } @@ -364,7 +341,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod } if (message == 0 && binaryNode == 0 && symNode == 0) { - error(line, " l-value required", op, "", ""); + error(line, " l-value required", op); return true; } @@ -379,10 +356,18 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod // // If we get here, we have an error and a message. // - if (symNode) - error(line, " l-value required", op, "\"%s\" (%s)", symbol, message); - else - error(line, " l-value required", op, "(%s)", message); + if (symNode) { + std::stringstream extraInfoStream; + extraInfoStream << "\"" << symbol << "\" (" << message << ")"; + std::string extraInfo = extraInfoStream.str(); + error(line, " l-value required", op, extraInfo.c_str()); + } + else { + std::stringstream extraInfoStream; + extraInfoStream << "(" << message << ")"; + std::string extraInfo = extraInfoStream.str(); + error(line, " l-value required", op, extraInfo.c_str()); + } return true; } @@ -398,7 +383,7 @@ bool TParseContext::constErrorCheck(TIntermTyped* node) if (node->getQualifier() == EvqConst) return false; - error(node->getLine(), "constant expression required", "", ""); + error(node->getLine(), "constant expression required", ""); return true; } @@ -414,7 +399,7 @@ bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token) if (node->getBasicType() == EbtInt && node->getNominalSize() == 1) return false; - error(node->getLine(), "integer expression required", token, ""); + error(node->getLine(), "integer expression required", token); return true; } @@ -430,7 +415,7 @@ bool TParseContext::globalErrorCheck(int line, bool global, const char* token) if (global) return false; - error(line, "only allowed at global scope", token, ""); + error(line, "only allowed at global scope", token); return true; } @@ -449,24 +434,26 @@ bool TParseContext::reservedErrorCheck(int line, const TString& identifier) static const char* reservedErrMsg = "reserved built-in name"; if (!symbolTable.atBuiltInLevel()) { if (identifier.compare(0, 3, "gl_") == 0) { - error(line, reservedErrMsg, "gl_", ""); + error(line, reservedErrMsg, "gl_"); return true; } - if (shaderSpec == SH_WEBGL_SPEC) { + if (isWebGLBasedSpec(shaderSpec)) { if (identifier.compare(0, 6, "webgl_") == 0) { - error(line, reservedErrMsg, "webgl_", ""); + error(line, reservedErrMsg, "webgl_"); return true; } if (identifier.compare(0, 7, "_webgl_") == 0) { - error(line, reservedErrMsg, "_webgl_", ""); + error(line, reservedErrMsg, "_webgl_"); + return true; + } + if (shaderSpec == SH_CSS_SHADERS_SPEC && identifier.compare(0, 4, "css_") == 0) { + error(line, reservedErrMsg, "css_"); return true; } } if (identifier.find("__") != TString::npos) { - //error(line, "Two consecutive underscores are reserved for future use.", identifier.c_str(), "", ""); - //return true; - infoSink.info.message(EPrefixWarning, "Two consecutive underscores are reserved for future use.", line); - return false; + error(line, "identifiers containing two consecutive underscores (__) are reserved as possible future keywords", identifier.c_str()); + return true; } } @@ -527,51 +514,51 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction type->setQualifier(EvqConst); if (type->isArray() && type->getArraySize() != function.getParamCount()) { - error(line, "array constructor needs one argument per array element", "constructor", ""); + error(line, "array constructor needs one argument per array element", "constructor"); return true; } if (arrayArg && op != EOpConstructStruct) { - error(line, "constructing from a non-dereferenced array", "constructor", ""); + error(line, "constructing from a non-dereferenced array", "constructor"); return true; } if (matrixInMatrix && !type->isArray()) { if (function.getParamCount() != 1) { - error(line, "constructing matrix from matrix can only take one argument", "constructor", ""); + error(line, "constructing matrix from matrix can only take one argument", "constructor"); return true; } } if (overFull) { - error(line, "too many arguments", "constructor", ""); + error(line, "too many arguments", "constructor"); return true; } if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->size()) != function.getParamCount()) { - error(line, "Number of constructor parameters does not match the number of structure fields", "constructor", ""); + error(line, "Number of constructor parameters does not match the number of structure fields", "constructor"); return true; } if (!type->isMatrix() || !matrixInMatrix) { if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) || (op == EOpConstructStruct && size < type->getObjectSize())) { - error(line, "not enough data provided for construction", "constructor", ""); + error(line, "not enough data provided for construction", "constructor"); return true; } } TIntermTyped *typed = node ? node->getAsTyped() : 0; if (typed == 0) { - error(line, "constructor argument does not have a type", "constructor", ""); + error(line, "constructor argument does not have a type", "constructor"); return true; } if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) { - error(line, "cannot convert a sampler", "constructor", ""); + error(line, "cannot convert a sampler", "constructor"); return true; } if (typed->getBasicType() == EbtVoid) { - error(line, "cannot convert a void", "constructor", ""); + error(line, "cannot convert a void", "constructor"); return true; } @@ -585,7 +572,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TPublicType& pubType) { if (pubType.type == EbtVoid) { - error(line, "illegal use of type 'void'", identifier.c_str(), ""); + error(line, "illegal use of type 'void'", identifier.c_str()); return true; } @@ -599,7 +586,7 @@ bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TP bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type) { if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) { - error(line, "boolean expression expected", "", ""); + error(line, "boolean expression expected", ""); return true; } @@ -613,7 +600,7 @@ bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type) bool TParseContext::boolErrorCheck(int line, const TPublicType& pType) { if (pType.type != EbtBool || pType.array || pType.matrix || (pType.size > 1)) { - error(line, "boolean expression expected", "", ""); + error(line, "boolean expression expected", ""); return true; } @@ -631,7 +618,7 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const return false; } else if (IsSampler(pType.type)) { - error(line, reason, getBasicString(pType.type), ""); + error(line, reason, getBasicString(pType.type)); return true; } @@ -643,7 +630,7 @@ bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType { if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) && pType.type == EbtStruct) { - error(line, "cannot be used with a structure", getQualifierString(pType.qualifier), ""); + error(line, "cannot be used with a structure", getQualifierString(pType.qualifier)); return true; } @@ -658,7 +645,7 @@ bool TParseContext::parameterSamplerErrorCheck(int line, TQualifier qualifier, c { if ((qualifier == EvqOut || qualifier == EvqInOut) && type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) { - error(line, "samplers cannot be output parameters", type.getBasicString(), ""); + error(line, "samplers cannot be output parameters", type.getBasicString()); return true; } @@ -690,14 +677,14 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size) { TIntermConstantUnion* constant = expr->getAsConstantUnion(); if (constant == 0 || constant->getBasicType() != EbtInt) { - error(line, "array size must be a constant integer expression", "", ""); + error(line, "array size must be a constant integer expression", ""); return true; } size = constant->getUnionArrayPointer()->getIConst(); if (size <= 0) { - error(line, "array size must be a positive integer", "", ""); + error(line, "array size must be a positive integer", ""); size = 1; return true; } @@ -713,7 +700,7 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size) bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type) { if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqConst)) { - error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str(), ""); + error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str()); return true; } @@ -731,7 +718,7 @@ bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type) // Can the type be an array? // if (type.array) { - error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str(), ""); + error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str()); return true; } @@ -767,34 +754,34 @@ bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType t if (! symbolTable.insert(*variable)) { delete variable; - error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str(), ""); + error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str()); return true; } } else { if (! symbol->isVariable()) { - error(line, "variable expected", identifier.c_str(), ""); + error(line, "variable expected", identifier.c_str()); return true; } variable = static_cast<TVariable*>(symbol); if (! variable->getType().isArray()) { - error(line, "redeclaring non-array as array", identifier.c_str(), ""); + error(line, "redeclaring non-array as array", identifier.c_str()); return true; } if (variable->getType().getArraySize() > 0) { - error(line, "redeclaration of array with size", identifier.c_str(), ""); + error(line, "redeclaration of array with size", identifier.c_str()); return true; } if (! variable->getType().sameElementType(TType(type))) { - error(line, "redeclaration of array with a different type", identifier.c_str(), ""); + error(line, "redeclaration of array with a different type", identifier.c_str()); return true; } TType* t = variable->getArrayInformationType(); while (t != 0) { if (t->getMaxArraySize() > type.arraySize) { - error(line, "higher index value already used for the array", identifier.c_str(), ""); + error(line, "higher index value already used for the array", identifier.c_str()); return true; } t->setArraySize(type.arraySize); @@ -816,7 +803,7 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool builtIn = false; TSymbol* symbol = symbolTable.find(node->getSymbol(), &builtIn); if (symbol == 0) { - error(line, " undeclared identifier", node->getSymbol().c_str(), ""); + error(line, " undeclared identifier", node->getSymbol().c_str()); return true; } TVariable* variable = static_cast<TVariable*>(symbol); @@ -828,14 +815,11 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, // its an error if (node->getSymbol() == "gl_FragData") { TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", &builtIn); - if (fragData == 0) { - infoSink.info.message(EPrefixInternalError, "gl_MaxDrawBuffers not defined", line); - return true; - } + ASSERT(fragData); int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst(); if (fragDataValue <= size) { - error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers", ""); + error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers"); return true; } } @@ -870,7 +854,7 @@ bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPubli // if (type.qualifier == EvqConst) { type.qualifier = EvqTemporary; - error(line, "variables with qualifier 'const' must be initialized", identifier.c_str(), ""); + error(line, "variables with qualifier 'const' must be initialized", identifier.c_str()); return true; } @@ -891,7 +875,7 @@ bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType variable = new TVariable(&identifier, TType(type)); if (! symbolTable.insert(*variable)) { - error(line, "redefinition", variable->getName().c_str(), ""); + error(line, "redefinition", variable->getName().c_str()); delete variable; variable = 0; return true; @@ -906,7 +890,7 @@ bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type) { if (qualifier != EvqConst && qualifier != EvqTemporary) { - error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier), ""); + error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier)); return true; } if (qualifier == EvqConst && paramQualifier != EvqIn) { @@ -924,8 +908,9 @@ bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier p bool TParseContext::extensionErrorCheck(int line, const TString& extension) { - TExtensionBehavior::const_iterator iter = extensionBehavior.find(extension); - if (iter == extensionBehavior.end()) { + const TExtensionBehavior& extBehavior = extensionBehavior(); + TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str()); + if (iter == extBehavior.end()) { error(line, "extension", extension.c_str(), "is not supported"); return true; } @@ -935,8 +920,7 @@ bool TParseContext::extensionErrorCheck(int line, const TString& extension) return true; } if (iter->second == EBhWarn) { - TString msg = "extension " + extension + " is being used"; - infoSink.info.message(EPrefixWarning, msg.c_str(), line); + warning(line, "extension", extension.c_str(), "is being used"); return false; } @@ -945,8 +929,23 @@ bool TParseContext::extensionErrorCheck(int line, const TString& extension) bool TParseContext::supportsExtension(const char* extension) { - TExtensionBehavior::const_iterator iter = extensionBehavior.find(extension); - return (iter != extensionBehavior.end()); + const TExtensionBehavior& extbehavior = extensionBehavior(); + TExtensionBehavior::const_iterator iter = extbehavior.find(extension); + return (iter != extbehavior.end()); +} + +void TParseContext::handleExtensionDirective(int line, const char* extName, const char* behavior) +{ + pp::SourceLocation loc; + DecodeSourceLoc(line, &loc.file, &loc.line); + directiveHandler.handleExtension(loc, extName, behavior); +} + +void TParseContext::handlePragmaDirective(int line, const char* name, const char* value) +{ + pp::SourceLocation loc; + DecodeSourceLoc(line, &loc.file, &loc.line); + directiveHandler.handlePragma(loc, name, value); } ///////////////////////////////////////////////////////////////////////////////// @@ -970,12 +969,12 @@ const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *bu } if (symbol == 0) { - error(line, "no matching overloaded function found", call->getName().c_str(), ""); + error(line, "no matching overloaded function found", call->getName().c_str()); return 0; } if (!symbol->isFunction()) { - error(line, "function name expected", call->getName().c_str(), ""); + error(line, "function name expected", call->getName().c_str()); return 0; } @@ -1003,7 +1002,7 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu // variable = new TVariable(&identifier, type); if (! symbolTable.insert(*variable)) { - error(line, "redefinition", variable->getName().c_str(), ""); + error(line, "redefinition", variable->getName().c_str()); return true; // don't delete variable, it's used by error recovery, and the pool // pop will take care of the memory @@ -1015,7 +1014,7 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu // TQualifier qualifier = variable->getType().getQualifier(); if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) { - error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString(), ""); + error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString()); return true; } // @@ -1024,13 +1023,16 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu if (qualifier == EvqConst) { if (qualifier != initializer->getType().getQualifier()) { - error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str()); + std::stringstream extraInfoStream; + extraInfoStream << "'" << variable->getType().getCompleteString() << "'"; + std::string extraInfo = extraInfoStream.str(); + error(line, " assigning non-constant to", "=", extraInfo.c_str()); variable->getType().setQualifier(EvqTemporary); return true; } if (type != initializer->getType()) { error(line, " non-matching types for const initializer ", - variable->getType().getQualifierString(), ""); + variable->getType().getQualifierString()); variable->getType().setQualifier(EvqTemporary); return true; } @@ -1049,7 +1051,10 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu ConstantUnion* constArray = tVar->getConstPointer(); variable->shareConstPointer(constArray); } else { - error(line, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str()); + std::stringstream extraInfoStream; + extraInfoStream << "'" << variable->getType().getCompleteString() << "'"; + std::string extraInfo = extraInfoStream.str(); + error(line, " cannot assign to", "=", extraInfo.c_str()); variable->getType().setQualifier(EvqTemporary); return true; } @@ -1234,14 +1239,14 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, T break; default: - error(line, "unsupported construction", "", ""); + error(line, "unsupported construction", ""); recover(); return 0; } newNode = intermediate.addUnaryMath(basicOp, node, node->getLine(), symbolTable); if (newNode == 0) { - error(line, "can't convert", "constructor", ""); + error(line, "can't convert", "constructor"); return 0; } @@ -1270,8 +1275,12 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int else return intermediate.setAggregateOperator(node->getAsTyped(), EOpConstructStruct, line); } else { - error(line, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount, - node->getAsTyped()->getType().getBasicString(), type->getBasicString()); + std::stringstream extraInfoStream; + extraInfoStream << "cannot convert parameter " << paramCount + << " from '" << node->getAsTyped()->getType().getBasicString() + << "' to '" << type->getBasicString() << "'"; + std::string extraInfo = extraInfoStream.str(); + error(line, "", "constructor", extraInfo.c_str()); recover(); } @@ -1293,15 +1302,13 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy ConstantUnion *unionArray; if (tempConstantNode) { unionArray = tempConstantNode->getUnionArrayPointer(); + ASSERT(unionArray); - if (!unionArray) { // this error message should never be raised - infoSink.info.message(EPrefixInternalError, "ConstantUnion not initialized in addConstVectorNode function", line); - recover(); - + if (!unionArray) { return node; } } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error - error(line, "Cannot offset into the vector", "Error", ""); + error(line, "Cannot offset into the vector", "Error"); recover(); return 0; @@ -1311,7 +1318,10 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy for (int i = 0; i < fields.num; i++) { if (fields.offsets[i] >= node->getType().getObjectSize()) { - error(line, "", "[", "vector field selection out of range '%d'", fields.offsets[i]); + std::stringstream extraInfoStream; + extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'"; + std::string extraInfo = extraInfoStream.str(); + error(line, "", "[", extraInfo.c_str()); recover(); fields.offsets[i] = 0; } @@ -1335,7 +1345,10 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); if (index >= node->getType().getNominalSize()) { - error(line, "", "[", "matrix field selection out of range '%d'", index); + std::stringstream extraInfoStream; + extraInfoStream << "matrix field selection out of range '" << index << "'"; + std::string extraInfo = extraInfoStream.str(); + error(line, "", "[", extraInfo.c_str()); recover(); index = 0; } @@ -1345,7 +1358,7 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T int size = tempConstantNode->getType().getNominalSize(); typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line); } else { - error(line, "Cannot offset into the matrix", "Error", ""); + error(line, "Cannot offset into the matrix", "Error"); recover(); return 0; @@ -1369,7 +1382,10 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS arrayElementType.clearArrayness(); if (index >= node->getType().getArraySize()) { - error(line, "", "[", "array field selection out of range '%d'", index); + std::stringstream extraInfoStream; + extraInfoStream << "array field selection out of range '" << index << "'"; + std::string extraInfo = extraInfoStream.str(); + error(line, "", "[", extraInfo.c_str()); recover(); index = 0; } @@ -1380,7 +1396,7 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer(); typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line); } else { - error(line, "Cannot offset into the array", "Error", ""); + error(line, "Cannot offset into the array", "Error"); recover(); return 0; @@ -1416,7 +1432,7 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function } else { - error(line, "Cannot offset into the structure", "Error", ""); + error(line, "Cannot offset into the structure", "Error"); recover(); return 0; @@ -1433,7 +1449,7 @@ bool TParseContext::enterStructDeclaration(int line, const TString& identifier) // They aren't allowed in GLSL either, but we need to detect this here // so we don't rely on the GLSL compiler to catch it. if (structNestingLevel > 1) { - error(line, "", "Embedded struct definitions are not allowed", ""); + error(line, "", "Embedded struct definitions are not allowed"); return true; } @@ -1453,7 +1469,7 @@ const int kWebGLMaxStructNesting = 4; bool TParseContext::structNestingErrorCheck(TSourceLoc line, const TType& fieldType) { - if (shaderSpec != SH_WEBGL_SPEC) { + if (!isWebGLBasedSpec(shaderSpec)) { return false; } @@ -1464,8 +1480,11 @@ bool TParseContext::structNestingErrorCheck(TSourceLoc line, const TType& fieldT // We're already inside a structure definition at this point, so add // one to the field's struct nesting. if (1 + fieldType.getDeepestStructNesting() > kWebGLMaxStructNesting) { - error(line, "", "", "Reference of struct type %s exceeds maximum struct nesting of %d", - fieldType.getTypeName().c_str(), kWebGLMaxStructNesting); + std::stringstream extraInfoStream; + extraInfoStream << "Reference of struct type " << fieldType.getTypeName() + << " exceeds maximum struct nesting of " << kWebGLMaxStructNesting; + std::string extraInfo = extraInfoStream.str(); + error(line, "", "", extraInfo.c_str()); return true; } @@ -1482,105 +1501,17 @@ int PaParseStrings(int count, const char* const string[], const int length[], if ((count == 0) || (string == NULL)) return 1; - // setup preprocessor. - if (InitPreprocessor()) - return 1; - DefineExtensionMacros(context->extensionBehavior); - if (glslang_initialize(context)) return 1; - glslang_scan(count, string, length, context); - int error = glslang_parse(context); + int error = glslang_scan(count, string, length, context); + if (!error) + error = glslang_parse(context); glslang_finalize(context); - FinalizePreprocessor(); - return (error == 0) && (context->numErrors == 0) ? 0 : 1; -} - -OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX; - -bool InitializeParseContextIndex() -{ - if (GlobalParseContextIndex != OS_INVALID_TLS_INDEX) { - assert(0 && "InitializeParseContextIndex(): Parse Context already initalised"); - return false; - } - - // - // Allocate a TLS index. - // - GlobalParseContextIndex = OS_AllocTLSIndex(); - - if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) { - assert(0 && "InitializeParseContextIndex(): Parse Context already initalised"); - return false; - } - return true; -} - -bool FreeParseContextIndex() -{ - OS_TLSIndex tlsiIndex = GlobalParseContextIndex; - - if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) { - assert(0 && "FreeParseContextIndex(): Parse Context index not initalised"); - return false; - } - - GlobalParseContextIndex = OS_INVALID_TLS_INDEX; - - return OS_FreeTLSIndex(tlsiIndex); -} - -bool InitializeGlobalParseContext() -{ - if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) { - assert(0 && "InitializeGlobalParseContext(): Parse Context index not initalised"); - return false; - } - - TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex)); - if (lpParseContext != 0) { - assert(0 && "InitializeParseContextIndex(): Parse Context already initalised"); - return false; - } - - TThreadParseContext *lpThreadData = new TThreadParseContext(); - if (lpThreadData == 0) { - assert(0 && "InitializeGlobalParseContext(): Unable to create thread parse context"); - return false; - } - - lpThreadData->lpGlobalParseContext = 0; - OS_SetTLSValue(GlobalParseContextIndex, lpThreadData); - - return true; -} - -bool FreeParseContext() -{ - if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) { - assert(0 && "FreeParseContext(): Parse Context index not initalised"); - return false; - } - - TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex)); - if (lpParseContext) - delete lpParseContext; - - return true; + return (error == 0) && (context->numErrors == 0) ? 0 : 1; } -TParseContextPointer& GetGlobalParseContext() -{ - // - // Minimal error checking for speed - // - TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex)); - - return lpParseContext->lpGlobalParseContext; -} diff --git a/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h b/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h index 3e05763b1..8dee8fdf5 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h +++ b/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h @@ -6,8 +6,10 @@ #ifndef _PARSER_HELPER_INCLUDED_ #define _PARSER_HELPER_INCLUDED_ -#include "compiler/ExtensionBehavior.h" +#include "compiler/Diagnostics.h" +#include "compiler/DirectiveHandler.h" #include "compiler/localintermediate.h" +#include "compiler/preprocessor/new/Preprocessor.h" #include "compiler/ShHandle.h" #include "compiler/SymbolTable.h" @@ -18,13 +20,6 @@ struct TMatrixFields { int col; }; -struct TPragma { - TPragma(bool o, bool d) : optimize(o), debug(d) { } - bool optimize; - bool debug; - TPragmaTable pragmaTable; -}; - // // The following are extra variables needed during parsing, grouped together so // they can be passed to the parser without needing a global. @@ -33,8 +28,6 @@ struct TParseContext { TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, ShShaderType type, ShShaderSpec spec, int options, bool checksPrecErrors, const char* sourcePath, TInfoSink& is) : intermediate(interm), symbolTable(symt), - extensionBehavior(ext), - infoSink(is), shaderType(type), shaderSpec(spec), compileOptions(options), @@ -48,12 +41,12 @@ struct TParseContext { currentFunctionType(NULL), functionReturnsValue(false), checksPrecisionErrors(checksPrecErrors), - contextPragma(true, false), + diagnostics(is), + directiveHandler(ext, diagnostics), + preprocessor(&diagnostics, &directiveHandler), scanner(NULL) { } TIntermediate& intermediate; // to hold and build a parse tree TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed - TExtensionBehavior& extensionBehavior; // mapping between supported extensions and current behavior. - TInfoSink& infoSink; ShShaderType shaderType; // vertex or fragment language (future: pack or unpack) ShShaderSpec shaderSpec; // The language specification compiler conforms to - GLES2 or WebGL. int compileOptions; @@ -67,15 +60,19 @@ struct TParseContext { const TType* currentFunctionType; // the return type of the function that's currently being parsed bool functionReturnsValue; // true if a non-void function has a return bool checksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit. - struct TPragma contextPragma; TString HashErrMsg; bool AfterEOF; + TDiagnostics diagnostics; + TDirectiveHandler directiveHandler; + pp::Preprocessor preprocessor; void* scanner; + TInfoSink& infoSink() { return diagnostics.infoSink(); } void error(TSourceLoc loc, const char *reason, const char* token, - const char* extraInfoFormat, ...); + const char* extraInfo=""); void warning(TSourceLoc loc, const char* reason, const char* token, - const char* extraInfoFormat, ...); + const char* extraInfo=""); + void trace(const char* str); void recover(); bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line); @@ -105,7 +102,13 @@ struct TParseContext { bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable); bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type); bool extensionErrorCheck(int line, const TString&); + + const TExtensionBehavior& extensionBehavior() const { return directiveHandler.extensionBehavior(); } bool supportsExtension(const char* extension); + void handleExtensionDirective(int line, const char* extName, const char* behavior); + + const TPragma& pragma() const { return directiveHandler.pragma(); } + void handlePragmaDirective(int line, const char* name, const char* value); bool containsSampler(TType& type); bool areAllChildConst(TIntermAggregate* aggrNode); @@ -135,13 +138,4 @@ struct TParseContext { int PaParseStrings(int count, const char* const string[], const int length[], TParseContext* context); -typedef TParseContext* TParseContextPointer; -extern TParseContextPointer& GetGlobalParseContext(); -#define GlobalParseContext GetGlobalParseContext() - -typedef struct TThreadParseContextRec -{ - TParseContext *lpGlobalParseContext; -} TThreadParseContext; - #endif // _PARSER_HELPER_INCLUDED_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp b/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp index a600c02cb..9ef4f59f5 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp @@ -11,6 +11,7 @@ #endif #include <stdio.h> +#include "common/angleutils.h" #include "compiler/InitializeGlobals.h" #include "compiler/osinclude.h" @@ -158,10 +159,10 @@ void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, co // We don't print the assert message. It's here just to be helpful. #if defined(_MSC_VER) - sprintf(assertMsg, "PoolAlloc: Damage %s %Iu byte allocation at 0x%p\n", + snprintf(assertMsg, sizeof(assertMsg), "PoolAlloc: Damage %s %Iu byte allocation at 0x%p\n", locText, size, data()); #else - sprintf(assertMsg, "PoolAlloc: Damage %s %zu byte allocation at 0x%p\n", + snprintf(assertMsg, sizeof(assertMsg), "PoolAlloc: Damage %s %zu byte allocation at 0x%p\n", locText, size, data()); #endif assert(0 && "PoolAlloc: Damage in guard block"); diff --git a/Source/ThirdParty/ANGLE/src/compiler/Pragma.h b/Source/ThirdParty/ANGLE/src/compiler/Pragma.h new file mode 100644 index 000000000..2f744123b --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/Pragma.h @@ -0,0 +1,19 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_PRAGMA_H_ +#define COMPILER_PRAGMA_H_ + +struct TPragma { + // By default optimization is turned on and debug is turned off. + TPragma() : optimize(true), debug(false) { } + TPragma(bool o, bool d) : optimize(o), debug(d) { } + + bool optimize; + bool debug; +}; + +#endif // COMPILER_PRAGMA_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/RenameFunction.h b/Source/ThirdParty/ANGLE/src/compiler/RenameFunction.h new file mode 100644 index 000000000..cfdb40da9 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/RenameFunction.h @@ -0,0 +1,36 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_RENAME_FUNCTION +#define COMPILER_RENAME_FUNCTION + +#include "compiler/intermediate.h" + +// +// Renames a function, including its declaration and any calls to it. +// +class RenameFunction : public TIntermTraverser +{ +public: + RenameFunction(const TString& oldFunctionName, const TString& newFunctionName) + : TIntermTraverser(true, false, false) + , mOldFunctionName(oldFunctionName) + , mNewFunctionName(newFunctionName) {} + + virtual bool visitAggregate(Visit visit, TIntermAggregate* node) + { + TOperator op = node->getOp(); + if ((op == EOpFunction || op == EOpFunctionCall) && node->getName() == mOldFunctionName) + node->setName(mNewFunctionName); + return true; + } + +private: + const TString& mOldFunctionName; + const TString& mNewFunctionName; +}; + +#endif // COMPILER_RENAME_FUNCTION diff --git a/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h b/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h index 91c47e777..26528b8db 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h +++ b/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h @@ -24,6 +24,13 @@ class LongNameMap; class TCompiler; +class TDependencyGraph; + +// +// Helper function to identify specs that are based on the WebGL spec, +// like the CSS Shaders spec. +// +bool isWebGLBasedSpec(ShShaderSpec spec); // // The base class used to back handles returned to the driver. @@ -70,6 +77,8 @@ protected: void clearResults(); // Return true if function recursion is detected. bool detectRecursion(TIntermNode* root); + // Rewrites a shader's intermediate tree according to the CSS Shaders spec. + void rewriteCSSShader(TIntermNode* root); // Returns true if the given shader does not exceed the minimum // functionality mandated in GLSL 1.0 spec Appendix A. bool validateLimitations(TIntermNode* root); @@ -79,6 +88,13 @@ protected: void mapLongVariableNames(TIntermNode* root); // Translate to object code. virtual void translate(TIntermNode* root) = 0; + // Returns true if the shader passes the restrictions that aim to prevent timing attacks. + bool enforceTimingRestrictions(TIntermNode* root, bool outputGraph); + // Returns true if the shader does not use samplers. + bool enforceVertexShaderTimingRestrictions(TIntermNode* root); + // Returns true if the shader does not use sampler dependent values to affect control + // flow or in operations whose time can depend on the input values. + bool enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph); // Get built-in extensions with default behavior. const TExtensionBehavior& getExtensionBehavior() const; diff --git a/Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp b/Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp index 13f11b5ca..56f5c7f2e 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp @@ -72,12 +72,14 @@ static void getVariableInfo(ShShaderInfo varType, int activeUniformAndAttribLength = 1 + MAX_SYMBOL_NAME_LEN; ASSERT(checkActiveUniformAndAttribMaxLengths(handle, activeUniformAndAttribLength)); strncpy(name, varInfo.name.c_str(), activeUniformAndAttribLength); + name[activeUniformAndAttribLength - 1] = 0; if (mappedName) { // This size must match that queried by // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below. int maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN; ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength)); strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength); + mappedName[maxMappedNameLength - 1] = 0; } } diff --git a/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.cpp b/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.cpp index edbea99b9..68f029d0e 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.cpp @@ -16,9 +16,10 @@ #include "compiler/SymbolTable.h" #include <stdio.h> - #include <algorithm> +#include "common/angleutils.h" + // // TType helper function needs a place to live. // @@ -56,7 +57,7 @@ void TType::buildMangledName(TString& mangledName) mangledName += static_cast<char>('0' + getNominalSize()); if (isArray()) { char buf[20]; - sprintf(buf, "%d", arraySize); + snprintf(buf, sizeof(buf), "%d", arraySize); mangledName += '['; mangledName += buf; mangledName += ']'; diff --git a/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.cpp index 96d7f1077..f41decd48 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.cpp @@ -6,6 +6,7 @@ #include "compiler/TranslatorHLSL.h" +#include "compiler/InitializeParseContext.h" #include "compiler/OutputHLSL.h" TranslatorHLSL::TranslatorHLSL(ShShaderType type, ShShaderSpec spec) diff --git a/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.cpp b/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.cpp deleted file mode 100644 index d3985e68b..000000000 --- a/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.cpp +++ /dev/null @@ -1,96 +0,0 @@ -// -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// UnfoldSelect is an AST traverser to output the select operator ?: as if-else statements -// - -#include "compiler/UnfoldSelect.h" - -#include "compiler/InfoSink.h" -#include "compiler/OutputHLSL.h" - -namespace sh -{ -UnfoldSelect::UnfoldSelect(TParseContext &context, OutputHLSL *outputHLSL) : mContext(context), mOutputHLSL(outputHLSL) -{ - mTemporaryIndex = 0; -} - -void UnfoldSelect::traverse(TIntermNode *node) -{ - int rewindIndex = mTemporaryIndex; - node->traverse(this); - mTemporaryIndex = rewindIndex; -} - -bool UnfoldSelect::visitSelection(Visit visit, TIntermSelection *node) -{ - TInfoSinkBase &out = mOutputHLSL->getBodyStream(); - - if (node->usesTernaryOperator()) - { - int i = mTemporaryIndex; - - out << mOutputHLSL->typeString(node->getType()) << " s" << i << ";\n"; - - mTemporaryIndex = i + 1; - node->getCondition()->traverse(this); - out << "if("; - mTemporaryIndex = i + 1; - node->getCondition()->traverse(mOutputHLSL); - out << ")\n" - "{\n"; - mTemporaryIndex = i + 1; - node->getTrueBlock()->traverse(this); - out << " s" << i << " = "; - mTemporaryIndex = i + 1; - node->getTrueBlock()->traverse(mOutputHLSL); - out << ";\n" - "}\n" - "else\n" - "{\n"; - mTemporaryIndex = i + 1; - node->getFalseBlock()->traverse(this); - out << " s" << i << " = "; - mTemporaryIndex = i + 1; - node->getFalseBlock()->traverse(mOutputHLSL); - out << ";\n" - "}\n"; - - mTemporaryIndex = i + 1; - } - - return false; -} - -bool UnfoldSelect::visitLoop(Visit visit, TIntermLoop *node) -{ - int rewindIndex = mTemporaryIndex; - - if (node->getInit()) - { - node->getInit()->traverse(this); - } - - if (node->getCondition()) - { - node->getCondition()->traverse(this); - } - - if (node->getExpression()) - { - node->getExpression()->traverse(this); - } - - mTemporaryIndex = rewindIndex; - - return false; -} - -int UnfoldSelect::getNextTemporaryIndex() -{ - return mTemporaryIndex++; -} -} diff --git a/Source/ThirdParty/ANGLE/src/compiler/UnfoldShortCircuit.cpp b/Source/ThirdParty/ANGLE/src/compiler/UnfoldShortCircuit.cpp new file mode 100644 index 000000000..1782ebc90 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/UnfoldShortCircuit.cpp @@ -0,0 +1,172 @@ +// +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// UnfoldShortCircuit is an AST traverser to output short-circuiting operators as if-else statements. +// The results are assigned to s# temporaries, which are used by the main translator instead of +// the original expression. +// + +#include "compiler/UnfoldShortCircuit.h" + +#include "compiler/InfoSink.h" +#include "compiler/OutputHLSL.h" + +namespace sh +{ +UnfoldShortCircuit::UnfoldShortCircuit(TParseContext &context, OutputHLSL *outputHLSL) : mContext(context), mOutputHLSL(outputHLSL) +{ + mTemporaryIndex = 0; +} + +void UnfoldShortCircuit::traverse(TIntermNode *node) +{ + int rewindIndex = mTemporaryIndex; + node->traverse(this); + mTemporaryIndex = rewindIndex; +} + +bool UnfoldShortCircuit::visitBinary(Visit visit, TIntermBinary *node) +{ + TInfoSinkBase &out = mOutputHLSL->getBodyStream(); + + switch (node->getOp()) + { + case EOpLogicalOr: + // "x || y" is equivalent to "x ? true : y", which unfolds to "bool s; if(x) s = true; else s = y;", + // and then further simplifies down to "bool s = x; if(!s) s = y;". + { + int i = mTemporaryIndex; + + out << "bool s" << i << ";\n"; + + out << "{\n"; + + mTemporaryIndex = i + 1; + node->getLeft()->traverse(this); + out << "s" << i << " = "; + mTemporaryIndex = i + 1; + node->getLeft()->traverse(mOutputHLSL); + out << ";\n"; + out << "if(!s" << i << ")\n" + "{\n"; + mTemporaryIndex = i + 1; + node->getRight()->traverse(this); + out << " s" << i << " = "; + mTemporaryIndex = i + 1; + node->getRight()->traverse(mOutputHLSL); + out << ";\n" + "}\n"; + + out << "}\n"; + + mTemporaryIndex = i + 1; + } + return false; + case EOpLogicalAnd: + // "x && y" is equivalent to "x ? y : false", which unfolds to "bool s; if(x) s = y; else s = false;", + // and then further simplifies down to "bool s = x; if(s) s = y;". + { + int i = mTemporaryIndex; + + out << "bool s" << i << ";\n"; + + out << "{\n"; + + mTemporaryIndex = i + 1; + node->getLeft()->traverse(this); + out << "s" << i << " = "; + mTemporaryIndex = i + 1; + node->getLeft()->traverse(mOutputHLSL); + out << ";\n"; + out << "if(s" << i << ")\n" + "{\n"; + mTemporaryIndex = i + 1; + node->getRight()->traverse(this); + out << " s" << i << " = "; + mTemporaryIndex = i + 1; + node->getRight()->traverse(mOutputHLSL); + out << ";\n" + "}\n"; + + out << "}\n"; + + mTemporaryIndex = i + 1; + } + return false; + } + + return true; +} + +bool UnfoldShortCircuit::visitSelection(Visit visit, TIntermSelection *node) +{ + TInfoSinkBase &out = mOutputHLSL->getBodyStream(); + + // Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;" + if (node->usesTernaryOperator()) + { + int i = mTemporaryIndex; + + out << mOutputHLSL->typeString(node->getType()) << " s" << i << ";\n"; + + mTemporaryIndex = i + 1; + node->getCondition()->traverse(this); + out << "if("; + mTemporaryIndex = i + 1; + node->getCondition()->traverse(mOutputHLSL); + out << ")\n" + "{\n"; + mTemporaryIndex = i + 1; + node->getTrueBlock()->traverse(this); + out << " s" << i << " = "; + mTemporaryIndex = i + 1; + node->getTrueBlock()->traverse(mOutputHLSL); + out << ";\n" + "}\n" + "else\n" + "{\n"; + mTemporaryIndex = i + 1; + node->getFalseBlock()->traverse(this); + out << " s" << i << " = "; + mTemporaryIndex = i + 1; + node->getFalseBlock()->traverse(mOutputHLSL); + out << ";\n" + "}\n"; + + mTemporaryIndex = i + 1; + } + + return false; +} + +bool UnfoldShortCircuit::visitLoop(Visit visit, TIntermLoop *node) +{ + int rewindIndex = mTemporaryIndex; + + if (node->getInit()) + { + node->getInit()->traverse(this); + } + + if (node->getCondition()) + { + node->getCondition()->traverse(this); + } + + if (node->getExpression()) + { + node->getExpression()->traverse(this); + } + + mTemporaryIndex = rewindIndex; + + return false; +} + +int UnfoldShortCircuit::getNextTemporaryIndex() +{ + return mTemporaryIndex++; +} +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.h b/Source/ThirdParty/ANGLE/src/compiler/UnfoldShortCircuit.h index 4a3ba5f86..cb176a5f1 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.h +++ b/Source/ThirdParty/ANGLE/src/compiler/UnfoldShortCircuit.h @@ -1,13 +1,13 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// UnfoldSelect is an AST traverser to output the select operator ?: as if-else statements +// UnfoldShortCircuit is an AST traverser to output short-circuiting operators as if-else statements // -#ifndef COMPILER_UNFOLDSELECT_H_ -#define COMPILER_UNFOLDSELECT_H_ +#ifndef COMPILER_UNFOLDSHORTCIRCUIT_H_ +#define COMPILER_UNFOLDSHORTCIRCUIT_H_ #include "compiler/intermediate.h" #include "compiler/ParseHelper.h" @@ -16,12 +16,13 @@ namespace sh { class OutputHLSL; -class UnfoldSelect : public TIntermTraverser +class UnfoldShortCircuit : public TIntermTraverser { public: - UnfoldSelect(TParseContext &context, OutputHLSL *outputHLSL); + UnfoldShortCircuit(TParseContext &context, OutputHLSL *outputHLSL); void traverse(TIntermNode *node); + bool visitBinary(Visit visit, TIntermBinary*); bool visitSelection(Visit visit, TIntermSelection *node); bool visitLoop(Visit visit, TIntermLoop *node); @@ -35,4 +36,4 @@ class UnfoldSelect : public TIntermTraverser }; } -#endif // COMPILER_UNFOLDSELECT_H_ +#endif // COMPILER_UNFOLDSHORTCIRCUIT_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp index 767d0bf38..d69ec6bba 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp @@ -6,6 +6,7 @@ #include "compiler/ValidateLimitations.h" #include "compiler/InfoSink.h" +#include "compiler/InitializeParseContext.h" #include "compiler/ParseHelper.h" namespace { diff --git a/Source/ThirdParty/ANGLE/src/compiler/debug.cpp b/Source/ThirdParty/ANGLE/src/compiler/debug.cpp index 9642e1e37..53778bd3e 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/debug.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/debug.cpp @@ -11,6 +11,7 @@ #include <stdarg.h> #include <stdio.h> +#include "compiler/InitializeParseContext.h" #include "compiler/ParseHelper.h" static const int kTraceBufferLen = 1024; @@ -28,7 +29,7 @@ void Trace(const char *format, ...) { vsnprintf(buf, kTraceBufferLen, format, args); va_end(args); - parseContext->infoSink.debug << buf; + parseContext->trace(buf); } } } // extern "C" diff --git a/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraph.cpp b/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraph.cpp new file mode 100644 index 000000000..ca661d676 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraph.cpp @@ -0,0 +1,97 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#pragma warning(disable: 4718) + +#include "compiler/depgraph/DependencyGraph.h" +#include "compiler/depgraph/DependencyGraphBuilder.h" + +TDependencyGraph::TDependencyGraph(TIntermNode* intermNode) +{ + TDependencyGraphBuilder::build(intermNode, this); +} + +TDependencyGraph::~TDependencyGraph() +{ + for (TGraphNodeVector::const_iterator iter = mAllNodes.begin(); iter != mAllNodes.end(); ++iter) + { + TGraphNode* node = *iter; + delete node; + } +} + +TGraphArgument* TDependencyGraph::createArgument(TIntermAggregate* intermFunctionCall, + int argumentNumber) +{ + TGraphArgument* argument = new TGraphArgument(intermFunctionCall, argumentNumber); + mAllNodes.push_back(argument); + return argument; +} + +TGraphFunctionCall* TDependencyGraph::createFunctionCall(TIntermAggregate* intermFunctionCall) +{ + TGraphFunctionCall* functionCall = new TGraphFunctionCall(intermFunctionCall); + mAllNodes.push_back(functionCall); + if (functionCall->getIntermFunctionCall()->isUserDefined()) + mUserDefinedFunctionCalls.push_back(functionCall); + return functionCall; +} + +TGraphSymbol* TDependencyGraph::getOrCreateSymbol(TIntermSymbol* intermSymbol) +{ + TSymbolIdMap::const_iterator iter = mSymbolIdMap.find(intermSymbol->getId()); + + TGraphSymbol* symbol = NULL; + + if (iter != mSymbolIdMap.end()) { + TSymbolIdPair pair = *iter; + symbol = pair.second; + } else { + symbol = new TGraphSymbol(intermSymbol); + mAllNodes.push_back(symbol); + + TSymbolIdPair pair(intermSymbol->getId(), symbol); + mSymbolIdMap.insert(pair); + + // We save all sampler symbols in a collection, so we can start graph traversals from them quickly. + if (IsSampler(intermSymbol->getBasicType())) + mSamplerSymbols.push_back(symbol); + } + + return symbol; +} + +TGraphSelection* TDependencyGraph::createSelection(TIntermSelection* intermSelection) +{ + TGraphSelection* selection = new TGraphSelection(intermSelection); + mAllNodes.push_back(selection); + return selection; +} + +TGraphLoop* TDependencyGraph::createLoop(TIntermLoop* intermLoop) +{ + TGraphLoop* loop = new TGraphLoop(intermLoop); + mAllNodes.push_back(loop); + return loop; +} + +TGraphLogicalOp* TDependencyGraph::createLogicalOp(TIntermBinary* intermLogicalOp) +{ + TGraphLogicalOp* logicalOp = new TGraphLogicalOp(intermLogicalOp); + mAllNodes.push_back(logicalOp); + return logicalOp; +} + +const char* TGraphLogicalOp::getOpString() const +{ + const char* opString = NULL; + switch (getIntermLogicalOp()->getOp()) { + case EOpLogicalAnd: opString = "and"; break; + case EOpLogicalOr: opString = "or"; break; + default: opString = "unknown"; break; + } + return opString; +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraph.h b/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraph.h new file mode 100644 index 000000000..5a9c35d00 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraph.h @@ -0,0 +1,212 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_H +#define COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_H + +#include "compiler/intermediate.h" + +#include <set> +#include <stack> + +class TGraphNode; +class TGraphParentNode; +class TGraphArgument; +class TGraphFunctionCall; +class TGraphSymbol; +class TGraphSelection; +class TGraphLoop; +class TGraphLogicalOp; +class TDependencyGraphTraverser; +class TDependencyGraphOutput; + +typedef std::set<TGraphNode*> TGraphNodeSet; +typedef std::vector<TGraphNode*> TGraphNodeVector; +typedef std::vector<TGraphSymbol*> TGraphSymbolVector; +typedef std::vector<TGraphFunctionCall*> TFunctionCallVector; + +// +// Base class for all dependency graph nodes. +// +class TGraphNode { +public: + TGraphNode(TIntermNode* node) : intermNode(node) {} + virtual ~TGraphNode() {} + virtual void traverse(TDependencyGraphTraverser* graphTraverser); +protected: + TIntermNode* intermNode; +}; + +// +// Base class for dependency graph nodes that may have children. +// +class TGraphParentNode : public TGraphNode { +public: + TGraphParentNode(TIntermNode* node) : TGraphNode(node) {} + virtual ~TGraphParentNode() {} + void addDependentNode(TGraphNode* node) { if (node != this) mDependentNodes.insert(node); } + virtual void traverse(TDependencyGraphTraverser* graphTraverser); +private: + TGraphNodeSet mDependentNodes; +}; + +// +// Handle function call arguments. +// +class TGraphArgument : public TGraphParentNode { +public: + TGraphArgument(TIntermAggregate* intermFunctionCall, int argumentNumber) + : TGraphParentNode(intermFunctionCall) + , mArgumentNumber(argumentNumber) {} + virtual ~TGraphArgument() {} + const TIntermAggregate* getIntermFunctionCall() const { return intermNode->getAsAggregate(); } + int getArgumentNumber() const { return mArgumentNumber; } + virtual void traverse(TDependencyGraphTraverser* graphTraverser); +private: + int mArgumentNumber; +}; + +// +// Handle function calls. +// +class TGraphFunctionCall : public TGraphParentNode { +public: + TGraphFunctionCall(TIntermAggregate* intermFunctionCall) + : TGraphParentNode(intermFunctionCall) {} + virtual ~TGraphFunctionCall() {} + const TIntermAggregate* getIntermFunctionCall() const { return intermNode->getAsAggregate(); } + virtual void traverse(TDependencyGraphTraverser* graphTraverser); +}; + +// +// Handle symbols. +// +class TGraphSymbol : public TGraphParentNode { +public: + TGraphSymbol(TIntermSymbol* intermSymbol) : TGraphParentNode(intermSymbol) {} + virtual ~TGraphSymbol() {} + const TIntermSymbol* getIntermSymbol() const { return intermNode->getAsSymbolNode(); } + virtual void traverse(TDependencyGraphTraverser* graphTraverser); +}; + +// +// Handle if statements and ternary operators. +// +class TGraphSelection : public TGraphNode { +public: + TGraphSelection(TIntermSelection* intermSelection) : TGraphNode(intermSelection) {} + virtual ~TGraphSelection() {} + const TIntermSelection* getIntermSelection() const { return intermNode->getAsSelectionNode(); } + virtual void traverse(TDependencyGraphTraverser* graphTraverser); +}; + +// +// Handle for, do-while, and while loops. +// +class TGraphLoop : public TGraphNode { +public: + TGraphLoop(TIntermLoop* intermLoop) : TGraphNode(intermLoop) {} + virtual ~TGraphLoop() {} + const TIntermLoop* getIntermLoop() const { return intermNode->getAsLoopNode(); } + virtual void traverse(TDependencyGraphTraverser* graphTraverser); +}; + +// +// Handle logical and, or. +// +class TGraphLogicalOp : public TGraphNode { +public: + TGraphLogicalOp(TIntermBinary* intermLogicalOp) : TGraphNode(intermLogicalOp) {} + virtual ~TGraphLogicalOp() {} + const TIntermBinary* getIntermLogicalOp() const { return intermNode->getAsBinaryNode(); } + const char* getOpString() const; + virtual void traverse(TDependencyGraphTraverser* graphTraverser); +}; + +// +// A dependency graph of symbols, function calls, conditions etc. +// +// This class provides an interface to the entry points of the dependency graph. +// +// Dependency graph nodes should be created by using one of the provided "create..." methods. +// This class (and nobody else) manages the memory of the created nodes. +// Nodes may not be removed after being added, so all created nodes will exist while the +// TDependencyGraph instance exists. +// +class TDependencyGraph { +public: + TDependencyGraph(TIntermNode* intermNode); + ~TDependencyGraph(); + TGraphNodeVector::const_iterator begin() const { return mAllNodes.begin(); } + TGraphNodeVector::const_iterator end() const { return mAllNodes.end(); } + + TGraphSymbolVector::const_iterator beginSamplerSymbols() const + { + return mSamplerSymbols.begin(); + } + + TGraphSymbolVector::const_iterator endSamplerSymbols() const + { + return mSamplerSymbols.end(); + } + + TFunctionCallVector::const_iterator beginUserDefinedFunctionCalls() const + { + return mUserDefinedFunctionCalls.begin(); + } + + TFunctionCallVector::const_iterator endUserDefinedFunctionCalls() const + { + return mUserDefinedFunctionCalls.end(); + } + + TGraphArgument* createArgument(TIntermAggregate* intermFunctionCall, int argumentNumber); + TGraphFunctionCall* createFunctionCall(TIntermAggregate* intermFunctionCall); + TGraphSymbol* getOrCreateSymbol(TIntermSymbol* intermSymbol); + TGraphSelection* createSelection(TIntermSelection* intermSelection); + TGraphLoop* createLoop(TIntermLoop* intermLoop); + TGraphLogicalOp* createLogicalOp(TIntermBinary* intermLogicalOp); +private: + typedef TMap<int, TGraphSymbol*> TSymbolIdMap; + typedef std::pair<int, TGraphSymbol*> TSymbolIdPair; + + TGraphNodeVector mAllNodes; + TGraphSymbolVector mSamplerSymbols; + TFunctionCallVector mUserDefinedFunctionCalls; + TSymbolIdMap mSymbolIdMap; +}; + +// +// For traversing the dependency graph. Users should derive from this, +// put their traversal specific data in it, and then pass it to a +// traverse method. +// +// When using this, just fill in the methods for nodes you want visited. +// +class TDependencyGraphTraverser { +public: + TDependencyGraphTraverser() : mDepth(0) {} + + virtual void visitSymbol(TGraphSymbol* symbol) {}; + virtual void visitArgument(TGraphArgument* selection) {}; + virtual void visitFunctionCall(TGraphFunctionCall* functionCall) {}; + virtual void visitSelection(TGraphSelection* selection) {}; + virtual void visitLoop(TGraphLoop* loop) {}; + virtual void visitLogicalOp(TGraphLogicalOp* logicalOp) {}; + + int getDepth() const { return mDepth; } + void incrementDepth() { ++mDepth; } + void decrementDepth() { --mDepth; } + + void clearVisited() { mVisited.clear(); } + void markVisited(TGraphNode* node) { mVisited.insert(node); } + bool isVisited(TGraphNode* node) const { return mVisited.find(node) != mVisited.end(); } +private: + int mDepth; + TGraphNodeSet mVisited; +}; + +#endif diff --git a/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphBuilder.cpp b/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphBuilder.cpp new file mode 100644 index 000000000..d586cfd03 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphBuilder.cpp @@ -0,0 +1,227 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/depgraph/DependencyGraphBuilder.h" + +void TDependencyGraphBuilder::build(TIntermNode* node, TDependencyGraph* graph) +{ + TDependencyGraphBuilder builder(graph); + builder.build(node); +} + +bool TDependencyGraphBuilder::visitAggregate(Visit visit, TIntermAggregate* intermAggregate) +{ + switch (intermAggregate->getOp()) { + case EOpFunction: visitFunctionDefinition(intermAggregate); break; + case EOpFunctionCall: visitFunctionCall(intermAggregate); break; + default: visitAggregateChildren(intermAggregate); break; + } + + return false; +} + +void TDependencyGraphBuilder::visitFunctionDefinition(TIntermAggregate* intermAggregate) +{ + // Currently, we do not support user defined functions. + if (intermAggregate->getName() != "main(") + return; + + visitAggregateChildren(intermAggregate); +} + +// Takes an expression like "f(x)" and creates a dependency graph like +// "x -> argument 0 -> function call". +void TDependencyGraphBuilder::visitFunctionCall(TIntermAggregate* intermFunctionCall) +{ + TGraphFunctionCall* functionCall = mGraph->createFunctionCall(intermFunctionCall); + + // Run through the function call arguments. + int argumentNumber = 0; + TIntermSequence& intermArguments = intermFunctionCall->getSequence(); + for (TIntermSequence::const_iterator iter = intermArguments.begin(); + iter != intermArguments.end(); + ++iter, ++argumentNumber) + { + TNodeSetMaintainer nodeSetMaintainer(this); + + TIntermNode* intermArgument = *iter; + intermArgument->traverse(this); + + if (TParentNodeSet* argumentNodes = mNodeSets.getTopSet()) { + TGraphArgument* argument = mGraph->createArgument(intermFunctionCall, argumentNumber); + connectMultipleNodesToSingleNode(argumentNodes, argument); + argument->addDependentNode(functionCall); + } + } + + // Push the leftmost symbol of this function call into the current set of dependent symbols to + // represent the result of this function call. + // Thus, an expression like "y = f(x)" will yield a dependency graph like + // "x -> argument 0 -> function call -> y". + // This line essentially passes the function call node back up to an earlier visitAssignment + // call, which will create the connection "function call -> y". + mNodeSets.insertIntoTopSet(functionCall); +} + +void TDependencyGraphBuilder::visitAggregateChildren(TIntermAggregate* intermAggregate) +{ + TIntermSequence& sequence = intermAggregate->getSequence(); + for(TIntermSequence::const_iterator iter = sequence.begin(); iter != sequence.end(); ++iter) + { + TIntermNode* intermChild = *iter; + intermChild->traverse(this); + } +} + +void TDependencyGraphBuilder::visitSymbol(TIntermSymbol* intermSymbol) +{ + // Push this symbol into the set of dependent symbols for the current assignment or condition + // that we are traversing. + TGraphSymbol* symbol = mGraph->getOrCreateSymbol(intermSymbol); + mNodeSets.insertIntoTopSet(symbol); + + // If this symbol is the current leftmost symbol under an assignment, replace the previous + // leftmost symbol with this symbol. + if (!mLeftmostSymbols.empty() && mLeftmostSymbols.top() != &mRightSubtree) { + mLeftmostSymbols.pop(); + mLeftmostSymbols.push(symbol); + } +} + +bool TDependencyGraphBuilder::visitBinary(Visit visit, TIntermBinary* intermBinary) +{ + TOperator op = intermBinary->getOp(); + if (op == EOpInitialize || intermBinary->modifiesState()) + visitAssignment(intermBinary); + else if (op == EOpLogicalAnd || op == EOpLogicalOr) + visitLogicalOp(intermBinary); + else + visitBinaryChildren(intermBinary); + + return false; +} + +void TDependencyGraphBuilder::visitAssignment(TIntermBinary* intermAssignment) +{ + TIntermTyped* intermLeft = intermAssignment->getLeft(); + if (!intermLeft) + return; + + TGraphSymbol* leftmostSymbol = NULL; + + { + TNodeSetMaintainer nodeSetMaintainer(this); + + { + TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mLeftSubtree); + intermLeft->traverse(this); + leftmostSymbol = mLeftmostSymbols.top(); + + // After traversing the left subtree of this assignment, we should have found a real + // leftmost symbol, and the leftmost symbol should not be a placeholder. + ASSERT(leftmostSymbol != &mLeftSubtree); + ASSERT(leftmostSymbol != &mRightSubtree); + } + + if (TIntermTyped* intermRight = intermAssignment->getRight()) { + TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree); + intermRight->traverse(this); + } + + if (TParentNodeSet* assignmentNodes = mNodeSets.getTopSet()) + connectMultipleNodesToSingleNode(assignmentNodes, leftmostSymbol); + } + + // Push the leftmost symbol of this assignment into the current set of dependent symbols to + // represent the result of this assignment. + // An expression like "a = (b = c)" will yield a dependency graph like "c -> b -> a". + // This line essentially passes the leftmost symbol of the nested assignment ("b" in this + // example) back up to the earlier visitAssignment call for the outer assignment, which will + // create the connection "b -> a". + mNodeSets.insertIntoTopSet(leftmostSymbol); +} + +void TDependencyGraphBuilder::visitLogicalOp(TIntermBinary* intermLogicalOp) +{ + if (TIntermTyped* intermLeft = intermLogicalOp->getLeft()) { + TNodeSetPropagatingMaintainer nodeSetMaintainer(this); + + intermLeft->traverse(this); + if (TParentNodeSet* leftNodes = mNodeSets.getTopSet()) { + TGraphLogicalOp* logicalOp = mGraph->createLogicalOp(intermLogicalOp); + connectMultipleNodesToSingleNode(leftNodes, logicalOp); + } + } + + if (TIntermTyped* intermRight = intermLogicalOp->getRight()) { + TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree); + intermRight->traverse(this); + } +} + +void TDependencyGraphBuilder::visitBinaryChildren(TIntermBinary* intermBinary) +{ + if (TIntermTyped* intermLeft = intermBinary->getLeft()) + intermLeft->traverse(this); + + if (TIntermTyped* intermRight = intermBinary->getRight()) { + TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree); + intermRight->traverse(this); + } +} + +bool TDependencyGraphBuilder::visitSelection(Visit visit, TIntermSelection* intermSelection) +{ + if (TIntermNode* intermCondition = intermSelection->getCondition()) { + TNodeSetMaintainer nodeSetMaintainer(this); + + intermCondition->traverse(this); + if (TParentNodeSet* conditionNodes = mNodeSets.getTopSet()) { + TGraphSelection* selection = mGraph->createSelection(intermSelection); + connectMultipleNodesToSingleNode(conditionNodes, selection); + } + } + + if (TIntermNode* intermTrueBlock = intermSelection->getTrueBlock()) + intermTrueBlock->traverse(this); + + if (TIntermNode* intermFalseBlock = intermSelection->getFalseBlock()) + intermFalseBlock->traverse(this); + + return false; +} + +bool TDependencyGraphBuilder::visitLoop(Visit visit, TIntermLoop* intermLoop) +{ + if (TIntermTyped* intermCondition = intermLoop->getCondition()) { + TNodeSetMaintainer nodeSetMaintainer(this); + + intermCondition->traverse(this); + if (TParentNodeSet* conditionNodes = mNodeSets.getTopSet()) { + TGraphLoop* loop = mGraph->createLoop(intermLoop); + connectMultipleNodesToSingleNode(conditionNodes, loop); + } + } + + if (TIntermNode* intermBody = intermLoop->getBody()) + intermBody->traverse(this); + + if (TIntermTyped* intermExpression = intermLoop->getExpression()) + intermExpression->traverse(this); + + return false; +} + + +void TDependencyGraphBuilder::connectMultipleNodesToSingleNode(TParentNodeSet* nodes, + TGraphNode* node) const +{ + for (TParentNodeSet::const_iterator iter = nodes->begin(); iter != nodes->end(); ++iter) + { + TGraphParentNode* currentNode = *iter; + currentNode->addDependentNode(node); + } +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphBuilder.h b/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphBuilder.h new file mode 100644 index 000000000..c5f232cb2 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphBuilder.h @@ -0,0 +1,181 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H +#define COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H + +#include "compiler/depgraph/DependencyGraph.h" + +// +// Creates a dependency graph of symbols, function calls, conditions etc. by traversing a +// intermediate tree. +// +class TDependencyGraphBuilder : public TIntermTraverser { +public: + static void build(TIntermNode* node, TDependencyGraph* graph); + + virtual void visitSymbol(TIntermSymbol*); + virtual bool visitBinary(Visit visit, TIntermBinary*); + virtual bool visitSelection(Visit visit, TIntermSelection*); + virtual bool visitAggregate(Visit visit, TIntermAggregate*); + virtual bool visitLoop(Visit visit, TIntermLoop*); + +private: + typedef std::stack<TGraphSymbol*> TSymbolStack; + typedef std::set<TGraphParentNode*> TParentNodeSet; + + // + // For collecting the dependent nodes of assignments, conditions, etc. + // while traversing the intermediate tree. + // + // This data structure is stack of sets. Each set contains dependency graph parent nodes. + // + class TNodeSetStack { + public: + TNodeSetStack() {}; + ~TNodeSetStack() { clear(); } + + // This should only be called after a pushSet. + // Returns NULL if the top set is empty. + TParentNodeSet* getTopSet() const + { + ASSERT(!nodeSets.empty()); + TParentNodeSet* topSet = nodeSets.top(); + return !topSet->empty() ? topSet : NULL; + } + + void pushSet() { nodeSets.push(new TParentNodeSet()); } + void popSet() + { + ASSERT(!nodeSets.empty()); + delete nodeSets.top(); + nodeSets.pop(); + } + + // Pops the top set and adds its contents to the new top set. + // This should only be called after a pushSet. + // If there is no set below the top set, the top set is just deleted. + void popSetIntoNext() + { + ASSERT(!nodeSets.empty()); + TParentNodeSet* oldTopSet = nodeSets.top(); + nodeSets.pop(); + + if (!nodeSets.empty()) { + TParentNodeSet* newTopSet = nodeSets.top(); + newTopSet->insert(oldTopSet->begin(), oldTopSet->end()); + } + + delete oldTopSet; + } + + // Does nothing if there is no top set. + // This can be called when there is no top set if we are visiting + // symbols that are not under an assignment or condition. + // We don't need to track those symbols. + void insertIntoTopSet(TGraphParentNode* node) + { + if (nodeSets.empty()) + return; + + nodeSets.top()->insert(node); + } + + void clear() + { + while (!nodeSets.empty()) + popSet(); + } + + private: + typedef std::stack<TParentNodeSet*> TParentNodeSetStack; + + TParentNodeSetStack nodeSets; + }; + + // + // An instance of this class pushes a new node set when instantiated. + // When the instance goes out of scope, it and pops the node set. + // + class TNodeSetMaintainer { + public: + TNodeSetMaintainer(TDependencyGraphBuilder* factory) + : sets(factory->mNodeSets) { sets.pushSet(); } + ~TNodeSetMaintainer() { sets.popSet(); } + protected: + TNodeSetStack& sets; + }; + + // + // An instance of this class pushes a new node set when instantiated. + // When the instance goes out of scope, it and pops the top node set and adds its contents to + // the new top node set. + // + class TNodeSetPropagatingMaintainer { + public: + TNodeSetPropagatingMaintainer(TDependencyGraphBuilder* factory) + : sets(factory->mNodeSets) { sets.pushSet(); } + ~TNodeSetPropagatingMaintainer() { sets.popSetIntoNext(); } + protected: + TNodeSetStack& sets; + }; + + // + // An instance of this class keeps track of the leftmost symbol while we're exploring an + // assignment. + // It will push the placeholder symbol kLeftSubtree when instantiated under a left subtree, + // and kRightSubtree under a right subtree. + // When it goes out of scope, it will pop the leftmost symbol at the top of the scope. + // During traversal, the TDependencyGraphBuilder will replace kLeftSubtree with a real symbol. + // kRightSubtree will never be replaced by a real symbol because we are tracking the leftmost + // symbol. + // + class TLeftmostSymbolMaintainer { + public: + TLeftmostSymbolMaintainer(TDependencyGraphBuilder* factory, TGraphSymbol& subtree) + : leftmostSymbols(factory->mLeftmostSymbols) + { + needsPlaceholderSymbol = leftmostSymbols.empty() || leftmostSymbols.top() != &subtree; + if (needsPlaceholderSymbol) + leftmostSymbols.push(&subtree); + } + + ~TLeftmostSymbolMaintainer() + { + if (needsPlaceholderSymbol) + leftmostSymbols.pop(); + } + + protected: + TSymbolStack& leftmostSymbols; + bool needsPlaceholderSymbol; + }; + + TDependencyGraphBuilder(TDependencyGraph* graph) + : TIntermTraverser(true, false, false) + , mLeftSubtree(NULL) + , mRightSubtree(NULL) + , mGraph(graph) {} + void build(TIntermNode* intermNode) { intermNode->traverse(this); } + + void connectMultipleNodesToSingleNode(TParentNodeSet* nodes, TGraphNode* node) const; + + void visitAssignment(TIntermBinary*); + void visitLogicalOp(TIntermBinary*); + void visitBinaryChildren(TIntermBinary*); + void visitFunctionDefinition(TIntermAggregate*); + void visitFunctionCall(TIntermAggregate* intermFunctionCall); + void visitAggregateChildren(TIntermAggregate*); + + TGraphSymbol mLeftSubtree; + TGraphSymbol mRightSubtree; + + TDependencyGraph* mGraph; + TNodeSetStack mNodeSets; + TSymbolStack mLeftmostSymbols; +}; + +#endif // COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H diff --git a/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphOutput.cpp b/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphOutput.cpp new file mode 100644 index 000000000..6fc489e7b --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphOutput.cpp @@ -0,0 +1,65 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/depgraph/DependencyGraphOutput.h" + +void TDependencyGraphOutput::outputIndentation() +{ + for (int i = 0; i < getDepth(); ++i) + mSink << " "; +} + +void TDependencyGraphOutput::visitArgument(TGraphArgument* parameter) +{ + outputIndentation(); + mSink << "argument " << parameter->getArgumentNumber() << " of call to " + << parameter->getIntermFunctionCall()->getName() << "\n"; +} + +void TDependencyGraphOutput::visitFunctionCall(TGraphFunctionCall* functionCall) +{ + outputIndentation(); + mSink << "function call " << functionCall->getIntermFunctionCall()->getName() << "\n"; +} + +void TDependencyGraphOutput::visitSymbol(TGraphSymbol* symbol) +{ + outputIndentation(); + mSink << symbol->getIntermSymbol()->getSymbol() << " (symbol id: " + << symbol->getIntermSymbol()->getId() << ")\n"; +} + +void TDependencyGraphOutput::visitSelection(TGraphSelection* selection) +{ + outputIndentation(); + mSink << "selection\n"; +} + +void TDependencyGraphOutput::visitLoop(TGraphLoop* loop) +{ + outputIndentation(); + mSink << "loop condition\n"; +} + +void TDependencyGraphOutput::visitLogicalOp(TGraphLogicalOp* logicalOp) +{ + outputIndentation(); + mSink << "logical " << logicalOp->getOpString() << "\n"; +} + +void TDependencyGraphOutput::outputAllSpanningTrees(TDependencyGraph& graph) +{ + mSink << "\n"; + + for (TGraphNodeVector::const_iterator iter = graph.begin(); iter != graph.end(); ++iter) + { + TGraphNode* symbol = *iter; + mSink << "--- Dependency graph spanning tree ---\n"; + clearVisited(); + symbol->traverse(this); + mSink << "\n"; + } +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphOutput.h b/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphOutput.h new file mode 100644 index 000000000..01447da98 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphOutput.h @@ -0,0 +1,30 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_OUTPUT_H +#define COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_OUTPUT_H + +#include "compiler/depgraph/DependencyGraph.h" +#include "compiler/InfoSink.h" + +class TDependencyGraphOutput : public TDependencyGraphTraverser { +public: + TDependencyGraphOutput(TInfoSinkBase& sink) : mSink(sink) {} + virtual void visitSymbol(TGraphSymbol* symbol); + virtual void visitArgument(TGraphArgument* parameter); + virtual void visitFunctionCall(TGraphFunctionCall* functionCall); + virtual void visitSelection(TGraphSelection* selection); + virtual void visitLoop(TGraphLoop* loop); + virtual void visitLogicalOp(TGraphLogicalOp* logicalOp); + + void outputAllSpanningTrees(TDependencyGraph& graph); +private: + void outputIndentation(); + + TInfoSinkBase& mSink; +}; + +#endif // COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_OUTPUT_H diff --git a/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphTraverse.cpp b/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphTraverse.cpp new file mode 100644 index 000000000..b158575ce --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphTraverse.cpp @@ -0,0 +1,69 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/depgraph/DependencyGraph.h" + +// These methods do a breadth-first traversal through the graph and mark visited nodes. + +void TGraphNode::traverse(TDependencyGraphTraverser* graphTraverser) +{ + graphTraverser->markVisited(this); +} + +void TGraphParentNode::traverse(TDependencyGraphTraverser* graphTraverser) +{ + TGraphNode::traverse(graphTraverser); + + graphTraverser->incrementDepth(); + + // Visit the parent node's children. + for (TGraphNodeSet::const_iterator iter = mDependentNodes.begin(); + iter != mDependentNodes.end(); + ++iter) + { + TGraphNode* node = *iter; + if (!graphTraverser->isVisited(node)) + node->traverse(graphTraverser); + } + + graphTraverser->decrementDepth(); +} + +void TGraphArgument::traverse(TDependencyGraphTraverser* graphTraverser) +{ + graphTraverser->visitArgument(this); + TGraphParentNode::traverse(graphTraverser); +} + +void TGraphFunctionCall::traverse(TDependencyGraphTraverser* graphTraverser) +{ + graphTraverser->visitFunctionCall(this); + TGraphParentNode::traverse(graphTraverser); +} + +void TGraphSymbol::traverse(TDependencyGraphTraverser* graphTraverser) +{ + graphTraverser->visitSymbol(this); + TGraphParentNode::traverse(graphTraverser); +} + +void TGraphSelection::traverse(TDependencyGraphTraverser* graphTraverser) +{ + graphTraverser->visitSelection(this); + TGraphNode::traverse(graphTraverser); +} + +void TGraphLoop::traverse(TDependencyGraphTraverser* graphTraverser) +{ + graphTraverser->visitLoop(this); + TGraphNode::traverse(graphTraverser); +} + +void TGraphLogicalOp::traverse(TDependencyGraphTraverser* graphTraverser) +{ + graphTraverser->visitLogicalOp(this); + TGraphNode::traverse(graphTraverser); +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang.h b/Source/ThirdParty/ANGLE/src/compiler/glslang.h index 26f1457e8..3a45daf3a 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/glslang.h +++ b/Source/ThirdParty/ANGLE/src/compiler/glslang.h @@ -8,9 +8,9 @@ struct TParseContext; extern int glslang_initialize(TParseContext* context); extern int glslang_finalize(TParseContext* context); -extern void glslang_scan(int count, - const char* const string[], - const int length[], - TParseContext* context); +extern int glslang_scan(int count, + const char* const string[], + const int length[], + TParseContext* context); extern int glslang_parse(TParseContext* context); diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang.l b/Source/ThirdParty/ANGLE/src/compiler/glslang.l index 9a0394bc5..b9a302d69 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/glslang.l +++ b/Source/ThirdParty/ANGLE/src/compiler/glslang.l @@ -1,6 +1,6 @@ /* // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -15,7 +15,7 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp). %top{ // -// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -38,6 +38,7 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp). %{ #include "compiler/glslang.h" #include "compiler/ParseHelper.h" +#include "compiler/preprocessor/new/Token.h" #include "compiler/util.h" #include "glslang_tab.h" @@ -159,6 +160,7 @@ O [0-7] "extern" { return reserved_word(yyscanner); } "external" { return reserved_word(yyscanner); } "interface" { return reserved_word(yyscanner); } +"flat" { return reserved_word(yyscanner); } "long" { return reserved_word(yyscanner); } "short" { return reserved_word(yyscanner); } @@ -166,6 +168,7 @@ O [0-7] "half" { return reserved_word(yyscanner); } "fixed" { return reserved_word(yyscanner); } "unsigned" { return reserved_word(yyscanner); } +"superp" { return reserved_word(yyscanner); } "input" { return reserved_word(yyscanner); } "output" { return reserved_word(yyscanner); } @@ -173,12 +176,21 @@ O [0-7] "hvec2" { return reserved_word(yyscanner); } "hvec3" { return reserved_word(yyscanner); } "hvec4" { return reserved_word(yyscanner); } -"fvec2" { return reserved_word(yyscanner); } -"fvec3" { return reserved_word(yyscanner); } -"fvec4" { return reserved_word(yyscanner); } "dvec2" { return reserved_word(yyscanner); } "dvec3" { return reserved_word(yyscanner); } "dvec4" { return reserved_word(yyscanner); } +"fvec2" { return reserved_word(yyscanner); } +"fvec3" { return reserved_word(yyscanner); } +"fvec4" { return reserved_word(yyscanner); } + +"sampler1D" { return reserved_word(yyscanner); } +"sampler3D" { return reserved_word(yyscanner); } + +"sampler1DShadow" { return reserved_word(yyscanner); } +"sampler2DShadow" { return reserved_word(yyscanner); } + +"sampler3DRect" { return reserved_word(yyscanner); } +"sampler2DRectShadow" { return reserved_word(yyscanner); } "sizeof" { return reserved_word(yyscanner); } "cast" { return reserved_word(yyscanner); } @@ -193,7 +205,7 @@ O [0-7] 0[xX]{H}+ { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } 0{O}+ { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } -0{D}+ { context->error(yylineno, "Invalid Octal number.", yytext, "", ""); context->recover(); return 0;} +0{D}+ { context->error(yylineno, "Invalid Octal number.", yytext); context->recover(); return 0;} {D}+ { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } {D}+{E} { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); } @@ -260,10 +272,15 @@ O [0-7] %% +#if !ANGLE_USE_NEW_PREPROCESSOR extern "C" { // Preprocessor interface. #include "compiler/preprocessor/preprocess.h" +extern int InitPreprocessor(); +extern int FinalizePreprocessor(); +extern void PredefineIntMacro(const char *name, int value); + #define SETUP_CONTEXT(pp) \ TParseContext* context = (TParseContext*) pp->pC; \ struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; @@ -272,26 +289,26 @@ extern "C" { void CPPDebugLogMsg(const char *msg) { SETUP_CONTEXT(cpp); - context->infoSink.debug.message(EPrefixNone, msg); + context->trace(msg); } void CPPWarningToInfoLog(const char *msg) { SETUP_CONTEXT(cpp); - context->warning(yylineno, msg, "", ""); + context->warning(yylineno, msg, ""); } void CPPShInfoLogMsg(const char *msg) { SETUP_CONTEXT(cpp); - context->error(yylineno, msg, "", ""); + context->error(yylineno, msg, ""); context->recover(); } -void CPPErrorToInfoLog(char *msg) +void CPPErrorToInfoLog(const char *msg) { SETUP_CONTEXT(cpp); - context->error(yylineno, msg, "", ""); + context->error(yylineno, msg, ""); context->recover(); } @@ -346,88 +363,15 @@ void DecLineNumber() void HandlePragma(const char **tokens, int numTokens) { SETUP_CONTEXT(cpp); - if (!strcmp(tokens[0], "optimize")) { - if (numTokens != 4) { - CPPShInfoLogMsg("optimize pragma syntax is incorrect"); - return; - } - - if (strcmp(tokens[1], "(")) { - CPPShInfoLogMsg("\"(\" expected after 'optimize' keyword"); - return; - } - - if (!strcmp(tokens[2], "on")) - context->contextPragma.optimize = true; - else if (!strcmp(tokens[2], "off")) - context->contextPragma.optimize = false; - else { - CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma"); - return; - } - - if (strcmp(tokens[3], ")")) { - CPPShInfoLogMsg("\")\" expected to end 'optimize' pragma"); - return; - } - } else if (!strcmp(tokens[0], "debug")) { - if (numTokens != 4) { - CPPShInfoLogMsg("debug pragma syntax is incorrect"); - return; - } - - if (strcmp(tokens[1], "(")) { - CPPShInfoLogMsg("\"(\" expected after 'debug' keyword"); - return; - } - - if (!strcmp(tokens[2], "on")) - context->contextPragma.debug = true; - else if (!strcmp(tokens[2], "off")) - context->contextPragma.debug = false; - else { - CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma"); - return; - } - - if (strcmp(tokens[3], ")")) { - CPPShInfoLogMsg("\")\" expected to end 'debug' pragma"); - return; - } - } else { -#ifdef PRAGMA_TABLE - // - // implementation specific pragma - // use ((TParseContext *)cpp->pC)->contextPragma.pragmaTable to store the information about pragma - // For now, just ignore the pragma that the implementation cannot recognize - // An Example of one such implementation for a pragma that has a syntax like - // #pragma pragmaname(pragmavalue) - // This implementation stores the current pragmavalue against the pragma name in pragmaTable. - // - if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) { - TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable; - TPragmaTable::iterator iter; - iter = pragmaTable.find(TString(tokens[0])); - if (iter != pragmaTable.end()) { - iter->second = tokens[2]; - } else { - pragmaTable[ tokens[0] ] = tokens[2]; - } - } else if (numTokens >= 2) { - TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable; - TPragmaTable::iterator iter; - iter = pragmaTable.find(TString(tokens[0])); - if (iter != pragmaTable.end()) { - iter->second = tokens[1]; - } else { - pragmaTable[ tokens[0] ] = tokens[1]; - } - } -#endif // PRAGMA_TABLE - } + + if (numTokens != 4) return; + if (strcmp(tokens[1], "(") != 0) return; + if (strcmp(tokens[3], ")") != 0) return; + + context->handlePragmaDirective(yylineno, tokens[0], tokens[2]); } -void StoreStr(char *string) +void StoreStr(const char *string) { SETUP_CONTEXT(cpp); TString strSrc; @@ -449,71 +393,33 @@ void ResetTString(void) context->HashErrMsg = ""; } -TBehavior GetBehavior(const char* behavior) -{ - if (!strcmp("require", behavior)) - return EBhRequire; - else if (!strcmp("enable", behavior)) - return EBhEnable; - else if (!strcmp("disable", behavior)) - return EBhDisable; - else if (!strcmp("warn", behavior)) - return EBhWarn; - else { - CPPShInfoLogMsg((TString("behavior '") + behavior + "' is not supported").c_str()); - return EBhDisable; - } -} - void updateExtensionBehavior(const char* extName, const char* behavior) { SETUP_CONTEXT(cpp); - TBehavior behaviorVal = GetBehavior(behavior); - TMap<TString, TBehavior>:: iterator iter; - TString msg; - - // special cased for all extension - if (!strcmp(extName, "all")) { - if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) { - CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior"); - return; - } else { - for (iter = context->extensionBehavior.begin(); iter != context->extensionBehavior.end(); ++iter) - iter->second = behaviorVal; - } - } else { - iter = context->extensionBehavior.find(TString(extName)); - if (iter == context->extensionBehavior.end()) { - switch (behaviorVal) { - case EBhRequire: - CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str()); - break; - case EBhEnable: - case EBhWarn: - case EBhDisable: - msg = TString("extension '") + extName + "' is not supported"; - context->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno); - break; - default: - break; - } - return; - } else - iter->second = behaviorVal; - } + context->handleExtensionDirective(yylineno, extName, behavior); } } // extern "C" +#endif // !ANGLE_USE_NEW_PREPROCESSOR int string_input(char* buf, int max_size, yyscan_t yyscanner) { - int len; - - if ((len = yylex_CPP(buf, max_size)) == 0) - return 0; - if (len >= max_size) - YY_FATAL_ERROR("input buffer overflow, can't enlarge buffer because scanner uses REJECT"); - - buf[len] = ' '; - return len+1; + int len = 0; + +#if ANGLE_USE_NEW_PREPROCESSOR + pp::Token token; + yyget_extra(yyscanner)->preprocessor.lex(&token); + len = token.type == pp::Token::LAST ? 0 : token.value.size(); + if ((len > 0) && (len < max_size)) + memcpy(buf, token.value.c_str(), len); + yyset_lineno(EncodeSourceLoc(token.location.file, token.location.line), yyscanner); +#else + len = yylex_CPP(buf, max_size); +#endif // ANGLE_USE_NEW_PREPROCESSOR + + if (len >= max_size) + YY_FATAL_ERROR("Input buffer overflow"); + else if (len > 0) + buf[len++] = ' '; + return len; } int check_type(yyscan_t yyscanner) { @@ -544,9 +450,9 @@ void yyerror(TParseContext* context, const char* reason) { struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; if (context->AfterEOF) { - context->error(yylineno, reason, "unexpected EOF", ""); + context->error(yylineno, reason, "unexpected EOF"); } else { - context->error(yylineno, reason, yytext, ""); + context->error(yylineno, reason, yytext); } context->recover(); } @@ -565,22 +471,43 @@ int glslang_finalize(TParseContext* context) { if (scanner == NULL) return 0; context->scanner = NULL; - return yylex_destroy(scanner); + yylex_destroy(scanner); + +#if !ANGLE_USE_NEW_PREPROCESSOR + FinalizePreprocessor(); +#endif + return 0; } -void glslang_scan(int count, const char* const string[], const int length[], - TParseContext* context) { +int glslang_scan(int count, const char* const string[], const int length[], + TParseContext* context) { yyrestart(NULL, context->scanner); yyset_lineno(EncodeSourceLoc(0, 1), context->scanner); context->AfterEOF = false; - - // Init preprocessor. + + // Initialize preprocessor. +#if ANGLE_USE_NEW_PREPROCESSOR + if (!context->preprocessor.init(count, string, length)) + return 1; +#else + if (InitPreprocessor()) + return 1; cpp->pC = context; - cpp->PaWhichStr = 0; - cpp->PaArgv = string; - cpp->PaArgc = count; - cpp->PaStrLen = length; cpp->pastFirstStatement = 0; - ScanFromString(string[0]); + if (InitScannerInput(cpp, count, string, length)) + return 1; +#endif // ANGLE_USE_NEW_PREPROCESSOR + + // Define extension macros. + const TExtensionBehavior& extBehavior = context->extensionBehavior(); + for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); + iter != extBehavior.end(); ++iter) { +#if ANGLE_USE_NEW_PREPROCESSOR + context->preprocessor.predefineMacro(iter->first.c_str(), 1); +#else + PredefineIntMacro(iter->first.c_str(), 1); +#endif + } + return 0; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang.y b/Source/ThirdParty/ANGLE/src/compiler/glslang.y index d6c8869f3..3cad33500 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/glslang.y +++ b/Source/ThirdParty/ANGLE/src/compiler/glslang.y @@ -38,6 +38,9 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). #include "compiler/ParseHelper.h" #include "GLSLANG/ShaderLang.h" +#define YYENABLE_NLS 0 +#define YYLTYPE_IS_TRIVIAL 1 + #define YYLEX_PARAM context->scanner %} @@ -84,21 +87,21 @@ extern void yyerror(TParseContext* context, const char* reason); #define FRAG_VERT_ONLY(S, L) { \ if (context->shaderType != SH_FRAGMENT_SHADER && \ context->shaderType != SH_VERTEX_SHADER) { \ - context->error(L, " supported in vertex/fragment shaders only ", S, "", ""); \ + context->error(L, " supported in vertex/fragment shaders only ", S); \ context->recover(); \ } \ } #define VERTEX_ONLY(S, L) { \ if (context->shaderType != SH_VERTEX_SHADER) { \ - context->error(L, " supported in vertex shaders only ", S, "", ""); \ + context->error(L, " supported in vertex shaders only ", S); \ context->recover(); \ } \ } #define FRAG_ONLY(S, L) { \ if (context->shaderType != SH_FRAGMENT_SHADER) { \ - context->error(L, " supported in fragment shaders only ", S, "", ""); \ + context->error(L, " supported in fragment shaders only ", S); \ context->recover(); \ } \ } @@ -167,7 +170,7 @@ variable_identifier const TSymbol* symbol = $1.symbol; const TVariable* variable; if (symbol == 0) { - context->error($1.line, "undeclared identifier", $1.string->c_str(), ""); + context->error($1.line, "undeclared identifier", $1.string->c_str()); context->recover(); TType type(EbtFloat, EbpUndefined); TVariable* fakeVariable = new TVariable($1.string, type); @@ -176,7 +179,7 @@ variable_identifier } else { // This identifier can only be a variable type symbol if (! symbol->isVariable()) { - context->error($1.line, "variable expected", $1.string->c_str(), ""); + context->error($1.line, "variable expected", $1.string->c_str()); context->recover(); } variable = static_cast<const TVariable*>(symbol); @@ -206,7 +209,7 @@ primary_expression // check for overflow for constants // if (abs($1.i) >= (1 << 16)) { - context->error($1.line, " integer constant overflow", "", ""); + context->error($1.line, " integer constant overflow", ""); context->recover(); } ConstantUnion *unionArray = new ConstantUnion[1]; @@ -235,9 +238,9 @@ postfix_expression | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET { if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) { if ($1->getAsSymbolNode()) - context->error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getSymbol().c_str(), ""); + context->error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getSymbol().c_str()); else - context->error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression", ""); + context->error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression"); context->recover(); } if ($1->getType().getQualifier() == EvqConst && $3->getQualifier() == EvqConst) { @@ -254,7 +257,10 @@ postfix_expression } else { if ($3->getQualifier() == EvqConst) { if (($1->isVector() || $1->isMatrix()) && $1->getType().getNominalSize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() && !$1->isArray() ) { - context->error($2.line, "", "[", "field selection out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()); + std::stringstream extraInfoStream; + extraInfoStream << "field selection out of range '" << $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() << "'"; + std::string extraInfo = extraInfoStream.str(); + context->error($2.line, "", "[", extraInfo.c_str()); context->recover(); } else { if ($1->isArray()) { @@ -267,7 +273,10 @@ postfix_expression context->recover(); } } else if ( $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= $1->getType().getArraySize()) { - context->error($2.line, "", "[", "array index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()); + std::stringstream extraInfoStream; + extraInfoStream << "array index out of range '" << $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() << "'"; + std::string extraInfo = extraInfoStream.str(); + context->error($2.line, "", "[", extraInfo.c_str()); context->recover(); } } @@ -310,7 +319,7 @@ postfix_expression } | postfix_expression DOT FIELD_SELECTION { if ($1->isArray()) { - context->error($3.line, "cannot apply dot operator to an array", ".", ""); + context->error($3.line, "cannot apply dot operator to an array", "."); context->recover(); } @@ -355,7 +364,7 @@ postfix_expression } if (fields.wholeRow || fields.wholeCol) { - context->error($2.line, " non-scalar fields not implemented yet", ".", ""); + context->error($2.line, " non-scalar fields not implemented yet", "."); context->recover(); ConstantUnion *unionArray = new ConstantUnion[1]; unionArray->setIConst(0); @@ -373,7 +382,7 @@ postfix_expression bool fieldFound = false; const TTypeList* fields = $1->getType().getStruct(); if (fields == 0) { - context->error($2.line, "structure has no fields", "Internal Error", ""); + context->error($2.line, "structure has no fields", "Internal Error"); context->recover(); $$ = $1; } else { @@ -405,13 +414,13 @@ postfix_expression $$->setType(*(*fields)[i].type); } } else { - context->error($2.line, " no such field in structure", $3.string->c_str(), ""); + context->error($2.line, " no such field in structure", $3.string->c_str()); context->recover(); $$ = $1; } } } else { - context->error($2.line, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str(), ""); + context->error($2.line, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str()); context->recover(); $$ = $1; } @@ -500,9 +509,10 @@ function_call // $$ = context->intermediate.addUnaryMath(op, $1.intermNode, 0, context->symbolTable); if ($$ == 0) { - context->error($1.intermNode->getLine(), " wrong operand type", "Internal Error", - "built in unary operator function. Type: %s", - static_cast<TIntermTyped*>($1.intermNode)->getCompleteString().c_str()); + std::stringstream extraInfoStream; + extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString(); + std::string extraInfo = extraInfoStream.str(); + context->error($1.intermNode->getLine(), " wrong operand type", "Internal Error", extraInfo.c_str()); YYERROR; } } else { @@ -526,7 +536,7 @@ function_call qual = fnCandidate->getParam(i).type->getQualifier(); if (qual == EvqOut || qual == EvqInOut) { if (context->lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) { - context->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", ""); + context->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error"); context->recover(); } } @@ -551,7 +561,7 @@ function_call_or_method $$ = $1; } | postfix_expression DOT function_call_generic { - context->error($3.line, "methods are not supported", "", ""); + context->error($3.line, "methods are not supported", ""); context->recover(); $$ = $3; } @@ -647,7 +657,7 @@ function_identifier default: break; } if (op == EOpNull) { - context->error($1.line, "cannot construct this type", getBasicString($1.type), ""); + context->error($1.line, "cannot construct this type", getBasicString($1.type)); context->recover(); $1.type = EbtFloat; op = EOpConstructFloat; @@ -1007,12 +1017,12 @@ function_prototype TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find($1->getMangledName())); if (prevDec) { if (prevDec->getReturnType() != $1->getReturnType()) { - context->error($2.line, "overloaded functions must have the same return type", $1->getReturnType().getBasicString(), ""); + context->error($2.line, "overloaded functions must have the same return type", $1->getReturnType().getBasicString()); context->recover(); } for (int i = 0; i < prevDec->getParamCount(); ++i) { if (prevDec->getParam(i).type->getQualifier() != $1->getParam(i).type->getQualifier()) { - context->error($2.line, "overloaded functions must have the same parameter qualifiers", $1->getParam(i).type->getQualifierString(), ""); + context->error($2.line, "overloaded functions must have the same parameter qualifiers", $1->getParam(i).type->getQualifierString()); context->recover(); } } @@ -1060,7 +1070,7 @@ function_header_with_parameters // // This parameter > first is void // - context->error($2.line, "cannot be an argument type except for '(void)'", "void", ""); + context->error($2.line, "cannot be an argument type except for '(void)'", "void"); context->recover(); delete $3.param.type; } else { @@ -1074,7 +1084,7 @@ function_header_with_parameters function_header : fully_specified_type IDENTIFIER LEFT_PAREN { if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) { - context->error($2.line, "no qualifiers allowed for function return", getQualifierString($1.qualifier), ""); + context->error($2.line, "no qualifiers allowed for function return", getQualifierString($1.qualifier)); context->recover(); } // make sure a sampler is not involved as well... @@ -1095,7 +1105,7 @@ parameter_declarator // Type + name : type_specifier IDENTIFIER { if ($1.type == EbtVoid) { - context->error($2.line, "illegal use of type 'void'", $2.string->c_str(), ""); + context->error($2.line, "illegal use of type 'void'", $2.string->c_str()); context->recover(); } if (context->reservedErrorCheck($2.line, *$2.string)) @@ -1191,7 +1201,7 @@ init_declarator_list | init_declarator_list COMMA IDENTIFIER { if ($1.type.type == EbtInvariant && !$3.symbol) { - context->error($3.line, "undeclared identifier declared as invariant", $3.string->c_str(), ""); + context->error($3.line, "undeclared identifier declared as invariant", $3.string->c_str()); context->recover(); } @@ -1298,7 +1308,7 @@ single_declaration symbol->setId(variable->getUniqueId()); } | fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET { - context->error($2.line, "unsized array declarations not supported", $2.string->c_str(), ""); + context->error($2.line, "unsized array declarations not supported", $2.string->c_str()); context->recover(); TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line); @@ -1364,7 +1374,7 @@ single_declaration $$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, $2.line); if (!$2.symbol) { - context->error($2.line, "undeclared identifier declared as invariant", $2.string->c_str(), ""); + context->error($2.line, "undeclared identifier declared as invariant", $2.string->c_str()); context->recover(); $$.intermAggregate = 0; @@ -1438,7 +1448,7 @@ single_declaration // context->recover(); // $$.variable = new TVariable($2.string, $1); // if (! context->symbolTable.insert(*$$.variable)) { -// context->error($2.line, "redefinition", $$.variable->getName().c_str(), ""); +// context->error($2.line, "redefinition", $$.variable->getName().c_str()); // context->recover(); // // don't have to delete $$.variable, the pool pop will take care of it // } @@ -1450,26 +1460,26 @@ fully_specified_type $$ = $1; if ($1.array) { - context->error($1.line, "not supported", "first-class array", ""); + context->error($1.line, "not supported", "first-class array"); context->recover(); $1.setArray(false); } } | type_qualifier type_specifier { if ($2.array) { - context->error($2.line, "not supported", "first-class array", ""); + context->error($2.line, "not supported", "first-class array"); context->recover(); $2.setArray(false); } if ($1.qualifier == EvqAttribute && ($2.type == EbtBool || $2.type == EbtInt)) { - context->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), ""); + context->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier)); context->recover(); } if (($1.qualifier == EvqVaryingIn || $1.qualifier == EvqVaryingOut) && ($2.type == EbtBool || $2.type == EbtInt)) { - context->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), ""); + context->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier)); context->recover(); } $$ = $2; @@ -1654,7 +1664,7 @@ type_specifier_nonarray } | SAMPLER_EXTERNAL_OES { if (!context->supportsExtension("GL_OES_EGL_image_external")) { - context->error($1.line, "unsupported type", "samplerExternalOES", ""); + context->error($1.line, "unsupported type", "samplerExternalOES"); context->recover(); } FRAG_VERT_ONLY("samplerExternalOES", $1.line); @@ -1663,7 +1673,7 @@ type_specifier_nonarray } | SAMPLER2DRECT { if (!context->supportsExtension("GL_ARB_texture_rectangle")) { - context->error($1.line, "unsupported type", "sampler2DRect", ""); + context->error($1.line, "unsupported type", "sampler2DRect"); context->recover(); } FRAG_VERT_ONLY("sampler2DRect", $1.line); @@ -1966,14 +1976,14 @@ for_rest_statement jump_statement : CONTINUE SEMICOLON { if (context->loopNestingLevel <= 0) { - context->error($1.line, "continue statement only allowed in loops", "", ""); + context->error($1.line, "continue statement only allowed in loops", ""); context->recover(); } $$ = context->intermediate.addBranch(EOpContinue, $1.line); } | BREAK SEMICOLON { if (context->loopNestingLevel <= 0) { - context->error($1.line, "break statement only allowed in loops", "", ""); + context->error($1.line, "break statement only allowed in loops", ""); context->recover(); } $$ = context->intermediate.addBranch(EOpBreak, $1.line); @@ -1981,7 +1991,7 @@ jump_statement | RETURN SEMICOLON { $$ = context->intermediate.addBranch(EOpReturn, $1.line); if (context->currentFunctionType->getBasicType() != EbtVoid) { - context->error($1.line, "non-void function must return a value", "return", ""); + context->error($1.line, "non-void function must return a value", "return"); context->recover(); } } @@ -1989,10 +1999,10 @@ jump_statement $$ = context->intermediate.addBranch(EOpReturn, $2, $1.line); context->functionReturnsValue = true; if (context->currentFunctionType->getBasicType() == EbtVoid) { - context->error($1.line, "void function cannot return a value", "return", ""); + context->error($1.line, "void function cannot return a value", "return"); context->recover(); } else if (*(context->currentFunctionType) != $2->getType()) { - context->error($1.line, "function return is not matching type:", "return", ""); + context->error($1.line, "function return is not matching type:", "return"); context->recover(); } } @@ -2037,7 +2047,7 @@ function_definition // // Then this function already has a body. // - context->error($1.line, "function already has a body", function->getName().c_str(), ""); + context->error($1.line, "function already has a body", function->getName().c_str()); context->recover(); } prevDec->setDefined(); @@ -2047,7 +2057,7 @@ function_definition // if (function->getName() == "main") { if (function->getParamCount() > 0) { - context->error($1.line, "function cannot take any parameter(s)", function->getName().c_str(), ""); + context->error($1.line, "function cannot take any parameter(s)", function->getName().c_str()); context->recover(); } if (function->getReturnType().getBasicType() != EbtVoid) { @@ -2079,7 +2089,7 @@ function_definition // Insert the parameters with name in the symbol table. // if (! context->symbolTable.insert(*variable)) { - context->error($1.line, "redefinition", variable->getName().c_str(), ""); + context->error($1.line, "redefinition", variable->getName().c_str()); context->recover(); delete variable; } @@ -2116,9 +2126,8 @@ function_definition // store the pragma information for debug and optimize and other vendor specific // information. This information can be queried from the parse tree - $$->getAsAggregate()->setOptimize(context->contextPragma.optimize); - $$->getAsAggregate()->setDebug(context->contextPragma.debug); - $$->getAsAggregate()->addToPragmaTable(context->contextPragma.pragmaTable); + $$->getAsAggregate()->setOptimize(context->pragma().optimize); + $$->getAsAggregate()->setDebug(context->pragma().debug); if ($3 && $3->getAsAggregate()) $$->getAsAggregate()->setEndLine($3->getAsAggregate()->getEndLine()); diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang_lex.cpp b/Source/ThirdParty/ANGLE/src/compiler/glslang_lex.cpp index 59b729913..a3bfa1340 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/glslang_lex.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/glslang_lex.cpp @@ -1,6 +1,6 @@ #line 17 "./glslang.l" // -// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -191,6 +191,11 @@ typedef void* yyscan_t; typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 @@ -204,7 +209,7 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; */ #define YY_LESS_LINENO(n) \ do { \ - int yyl;\ + yy_size_t yyl;\ for ( yyl = n; yyl < yyleng; ++yyl )\ if ( yytext[yyl] == '\n' )\ --yylineno;\ @@ -226,11 +231,6 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state @@ -248,7 +248,7 @@ struct yy_buffer_state /* Number of characters read into yy_ch_buf, not including EOB * characters. */ - int yy_n_chars; + yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to @@ -327,7 +327,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); void *yyalloc (yy_size_t ,yyscan_t yyscanner ); void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); @@ -383,8 +383,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 147 -#define YY_END_OF_BUFFER 148 +#define YY_NUM_RULES 155 +#define YY_END_OF_BUFFER 156 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -392,55 +392,58 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[426] = +static yyconst flex_int16_t yy_accept[459] = { 0, - 0, 0, 0, 0, 0, 0, 148, 146, 145, 145, - 130, 136, 141, 125, 126, 134, 133, 122, 131, 129, - 135, 94, 94, 123, 119, 137, 124, 138, 142, 90, - 127, 128, 140, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 120, 139, 121, 132, 3, 4, 3, - 144, 147, 143, 116, 102, 121, 110, 105, 100, 108, - 98, 109, 99, 97, 2, 1, 101, 96, 92, 93, - 0, 0, 94, 128, 120, 127, 117, 113, 115, 114, - 118, 90, 106, 112, 90, 90, 90, 90, 90, 90, - - 90, 90, 90, 90, 17, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 20, 22, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 107, 111, 5, 143, - 0, 1, 96, 0, 0, 95, 91, 103, 104, 50, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 18, 90, 90, - 90, 90, 90, 90, 90, 90, 26, 90, 90, 90, - 90, 90, 90, 90, 90, 23, 90, 90, 90, 90, - - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 0, 97, - 0, 96, 90, 28, 90, 90, 87, 90, 90, 90, - 90, 90, 90, 90, 21, 53, 90, 90, 90, 90, - 90, 58, 72, 90, 90, 90, 90, 90, 90, 90, - 90, 69, 9, 33, 34, 35, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 56, 29, 90, 90, 90, 90, 90, 90, 36, - 37, 38, 27, 90, 90, 90, 15, 42, 43, 44, - 51, 12, 90, 90, 90, 90, 83, 84, 85, 90, - - 30, 73, 25, 80, 81, 82, 7, 77, 78, 79, - 90, 24, 75, 90, 90, 39, 40, 41, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 70, 90, 90, - 90, 90, 90, 90, 90, 52, 90, 89, 90, 90, - 19, 90, 90, 90, 90, 71, 66, 61, 90, 90, - 90, 90, 90, 76, 57, 90, 64, 32, 90, 86, - 65, 49, 59, 90, 90, 90, 90, 90, 90, 90, - 90, 60, 31, 90, 90, 90, 8, 90, 90, 90, - 90, 90, 54, 13, 90, 14, 90, 90, 16, 67, - 90, 90, 90, 62, 90, 90, 90, 90, 55, 74, - - 63, 11, 68, 6, 88, 10, 45, 90, 90, 90, - 90, 90, 90, 46, 90, 90, 90, 48, 90, 90, - 90, 90, 90, 47, 0 + 0, 0, 0, 0, 0, 0, 156, 154, 153, 153, + 138, 144, 149, 133, 134, 142, 141, 130, 139, 137, + 143, 102, 102, 131, 127, 145, 132, 146, 150, 98, + 135, 136, 148, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 128, 147, 129, 140, 3, 4, 3, + 152, 155, 151, 124, 110, 129, 118, 113, 108, 116, + 106, 117, 107, 105, 2, 1, 109, 104, 100, 101, + 0, 0, 102, 136, 128, 135, 125, 121, 123, 122, + 126, 98, 114, 120, 98, 98, 98, 98, 98, 98, + + 98, 98, 98, 98, 17, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, 20, 22, + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 115, 119, 5, + 151, 0, 1, 104, 0, 0, 103, 99, 111, 112, + 50, 98, 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, 98, 18, + 98, 98, 98, 98, 98, 98, 98, 98, 26, 98, + 98, 98, 98, 98, 98, 98, 98, 23, 98, 98, + + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, + 98, 0, 105, 0, 104, 98, 28, 98, 98, 95, + 98, 98, 98, 98, 98, 98, 98, 21, 53, 98, + 98, 98, 69, 98, 98, 58, 73, 98, 98, 98, + 98, 98, 98, 98, 98, 70, 9, 33, 34, 35, + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 56, 29, 98, 98, + 98, 98, 98, 98, 36, 37, 38, 27, 98, 98, + 98, 15, 42, 43, 44, 51, 12, 98, 98, 98, + + 98, 82, 83, 84, 98, 30, 74, 25, 85, 86, + 87, 7, 79, 80, 81, 98, 24, 77, 98, 98, + 39, 40, 41, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 71, 98, 98, 98, 98, 98, 98, 98, + 98, 52, 98, 97, 98, 98, 19, 98, 98, 98, + 98, 72, 66, 61, 98, 98, 98, 98, 98, 78, + 57, 98, 64, 32, 98, 94, 65, 49, 76, 59, + 98, 98, 98, 98, 98, 98, 98, 98, 60, 31, + 98, 98, 98, 8, 98, 98, 98, 98, 98, 54, + 13, 98, 14, 98, 98, 16, 67, 98, 98, 98, + + 62, 98, 98, 98, 98, 98, 98, 55, 75, 63, + 11, 68, 6, 96, 10, 88, 45, 89, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, + 46, 98, 98, 98, 98, 98, 98, 98, 48, 98, + 92, 98, 98, 98, 98, 98, 90, 98, 91, 98, + 98, 98, 98, 98, 98, 47, 93, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -450,15 +453,15 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 1, 1, 1, 5, 6, 1, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 16, 16, 16, 20, 20, 21, 22, 23, - 24, 25, 26, 1, 27, 27, 28, 29, 30, 27, - 31, 31, 31, 31, 31, 31, 31, 31, 32, 31, - 31, 33, 34, 31, 31, 31, 31, 35, 31, 31, - 36, 1, 37, 38, 31, 1, 39, 40, 41, 42, - - 43, 44, 45, 46, 47, 31, 48, 49, 50, 51, - 52, 53, 31, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 1, 1, 1, 1, + 18, 19, 20, 20, 20, 21, 21, 22, 23, 24, + 25, 26, 27, 1, 28, 28, 29, 30, 31, 28, + 32, 32, 32, 32, 32, 32, 32, 32, 33, 32, + 32, 34, 35, 32, 32, 32, 32, 36, 32, 32, + 37, 1, 38, 39, 32, 1, 40, 41, 42, 43, + + 44, 45, 46, 47, 48, 32, 49, 50, 51, 52, + 53, 54, 32, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -475,201 +478,214 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[67] = +static yyconst flex_int32_t yy_meta[68] = { 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, - 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 1, 1, 1, 3, 3, - 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, + 3, 1, 1, 1, 1, 1, 1, 3, 3, 3, + 3, 4, 4, 4, 4, 4, 1, 1, 1, 3, + 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 1, 1, 1, 1 + 4, 4, 4, 1, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[431] = +static yyconst flex_int16_t yy_base[464] = { 0, - 0, 0, 64, 65, 74, 0, 627, 628, 628, 628, - 602, 45, 135, 628, 628, 601, 132, 628, 131, 129, - 143, 155, 163, 599, 628, 179, 599, 47, 628, 0, - 628, 628, 126, 98, 108, 147, 158, 158, 165, 570, - 130, 107, 569, 148, 156, 563, 172, 576, 174, 181, - 177, 195, 572, 628, 173, 628, 628, 628, 628, 603, - 628, 628, 0, 628, 628, 628, 628, 628, 628, 628, - 628, 628, 628, 233, 628, 0, 628, 239, 255, 271, - 287, 0, 300, 628, 628, 628, 592, 628, 628, 628, - 591, 0, 628, 628, 564, 557, 560, 568, 567, 554, - - 569, 556, 562, 550, 547, 560, 547, 544, 544, 550, - 538, 545, 542, 552, 538, 544, 547, 548, 0, 187, - 547, 241, 533, 546, 537, 539, 529, 543, 540, 542, - 525, 530, 527, 516, 192, 530, 526, 528, 517, 520, - 274, 525, 517, 529, 114, 522, 628, 628, 628, 0, - 316, 0, 322, 338, 344, 351, 0, 628, 628, 0, - 514, 518, 527, 524, 508, 508, 205, 523, 520, 520, - 518, 515, 507, 513, 500, 511, 514, 0, 511, 499, - 506, 503, 507, 500, 489, 488, 501, 504, 501, 496, - 487, 247, 492, 495, 486, 483, 487, 493, 484, 475, - - 478, 476, 486, 472, 470, 470, 472, 469, 480, 479, - 328, 474, 469, 458, 260, 476, 478, 467, 358, 366, - 372, 378, 468, 0, 466, 276, 0, 458, 456, 464, - 453, 470, 459, 291, 0, 0, 453, 463, 463, 448, - 305, 0, 0, 450, 327, 451, 445, 444, 445, 444, - 382, 0, 0, 0, 0, 0, 440, 441, 446, 437, - 450, 445, 444, 436, 440, 432, 435, 439, 444, 443, - 434, 0, 0, 440, 429, 429, 434, 433, 430, 0, - 0, 0, 0, 420, 432, 434, 0, 0, 0, 0, - 0, 0, 422, 423, 417, 427, 0, 0, 0, 418, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 425, 0, 0, 423, 419, 0, 0, 0, 415, 411, - 416, 406, 419, 405, 418, 407, 414, 0, 412, 414, - 398, 407, 413, 408, 396, 0, 398, 0, 397, 400, - 0, 389, 388, 388, 401, 0, 403, 0, 402, 401, - 386, 399, 386, 0, 0, 389, 0, 0, 381, 0, - 0, 0, 0, 378, 389, 382, 388, 385, 380, 372, - 382, 0, 0, 365, 371, 360, 0, 369, 366, 356, - 385, 364, 0, 0, 364, 0, 362, 361, 0, 0, - 360, 323, 308, 0, 298, 318, 270, 265, 0, 0, - - 0, 0, 0, 0, 0, 0, 279, 271, 240, 240, - 238, 237, 226, 0, 208, 188, 190, 0, 186, 173, - 187, 164, 158, 0, 628, 415, 417, 419, 423, 186 + 0, 0, 65, 66, 75, 0, 680, 681, 681, 681, + 654, 45, 137, 681, 681, 653, 134, 681, 133, 131, + 146, 159, 168, 651, 681, 186, 651, 47, 681, 0, + 681, 681, 128, 100, 110, 152, 156, 146, 166, 622, + 173, 109, 621, 126, 177, 615, 178, 628, 187, 184, + 141, 197, 624, 681, 157, 681, 681, 681, 681, 656, + 681, 681, 0, 681, 681, 681, 681, 681, 681, 681, + 681, 681, 681, 236, 681, 0, 681, 243, 273, 282, + 304, 0, 314, 681, 681, 681, 644, 681, 681, 681, + 643, 0, 681, 681, 616, 609, 612, 620, 619, 606, + + 621, 608, 614, 602, 599, 612, 599, 596, 596, 602, + 590, 189, 595, 605, 591, 597, 600, 601, 0, 216, + 600, 188, 586, 599, 590, 592, 582, 596, 593, 595, + 578, 583, 580, 569, 183, 577, 582, 578, 580, 569, + 572, 220, 577, 569, 581, 176, 574, 681, 681, 681, + 0, 331, 0, 344, 361, 290, 374, 0, 681, 681, + 0, 566, 570, 579, 576, 560, 560, 215, 575, 572, + 572, 570, 567, 559, 565, 552, 563, 549, 565, 0, + 562, 550, 557, 554, 558, 551, 540, 539, 552, 555, + 552, 547, 538, 260, 543, 546, 537, 534, 538, 544, + + 535, 526, 529, 527, 537, 523, 521, 534, 520, 522, + 519, 530, 529, 283, 524, 519, 508, 264, 526, 528, + 517, 381, 388, 395, 402, 518, 0, 516, 320, 0, + 508, 506, 514, 503, 520, 509, 336, 0, 0, 503, + 513, 513, 0, 498, 349, 0, 0, 500, 366, 501, + 495, 494, 495, 494, 407, 0, 0, 0, 0, 0, + 490, 491, 496, 487, 500, 495, 494, 486, 490, 482, + 485, 489, 494, 480, 492, 483, 0, 0, 489, 478, + 478, 483, 482, 479, 0, 0, 0, 0, 469, 481, + 483, 0, 0, 0, 0, 0, 0, 471, 472, 466, + + 476, 0, 0, 0, 467, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 474, 0, 0, 472, 468, + 0, 0, 0, 464, 460, 465, 455, 468, 454, 467, + 456, 463, 0, 461, 463, 447, 449, 455, 461, 456, + 444, 0, 446, 0, 445, 448, 0, 437, 436, 436, + 449, 0, 451, 0, 450, 449, 434, 447, 434, 0, + 0, 437, 0, 0, 429, 0, 0, 0, 0, 0, + 426, 437, 430, 436, 433, 428, 420, 432, 0, 0, + 425, 432, 421, 0, 430, 427, 417, 411, 425, 0, + 0, 425, 0, 423, 422, 0, 0, 421, 407, 419, + + 0, 410, 431, 430, 429, 400, 396, 0, 0, 0, + 0, 0, 0, 0, 0, 421, 250, 421, 411, 384, + 392, 394, 390, 392, 391, 390, 393, 390, 391, 388, + 0, 332, 343, 317, 329, 313, 317, 304, 321, 291, + 0, 302, 280, 271, 255, 262, 0, 256, 0, 232, + 206, 212, 148, 159, 113, 0, 0, 681, 442, 444, + 446, 450, 161 } ; -static yyconst flex_int16_t yy_def[431] = +static yyconst flex_int16_t yy_def[464] = { 0, - 425, 1, 426, 426, 425, 5, 425, 425, 425, 425, - 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, - 425, 425, 425, 425, 425, 425, 425, 425, 425, 427, - 425, 425, 425, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 425, 425, 425, 425, 425, 425, 425, - 425, 425, 428, 425, 425, 425, 425, 425, 425, 425, - 425, 425, 425, 425, 425, 429, 425, 425, 425, 425, - 425, 430, 425, 425, 425, 425, 425, 425, 425, 425, - 425, 427, 425, 425, 427, 427, 427, 427, 427, 427, - - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 425, 425, 425, 428, - 425, 429, 425, 425, 425, 425, 430, 425, 425, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 425, 425, - 425, 425, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 0, 425, 425, 425, 425, 425 + 458, 1, 459, 459, 458, 5, 458, 458, 458, 458, + 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, + 458, 458, 458, 458, 458, 458, 458, 458, 458, 460, + 458, 458, 458, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 458, 458, 458, 458, 458, 458, 458, + 458, 458, 461, 458, 458, 458, 458, 458, 458, 458, + 458, 458, 458, 458, 458, 462, 458, 458, 458, 458, + 458, 463, 458, 458, 458, 458, 458, 458, 458, 458, + 458, 460, 458, 458, 460, 460, 460, 460, 460, 460, + + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 458, 458, 458, + 461, 458, 462, 458, 458, 458, 458, 463, 458, 458, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 458, 458, 458, 458, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 0, 458, 458, + 458, 458, 458 } ; -static yyconst flex_int16_t yy_nxt[695] = +static yyconst flex_int16_t yy_nxt[749] = { 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 23, 23, 23, - 24, 25, 26, 27, 28, 29, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 30, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 30, - 30, 30, 54, 55, 56, 57, 59, 59, 65, 66, - 90, 91, 60, 60, 8, 61, 62, 8, 8, 8, + 23, 24, 25, 26, 27, 28, 29, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 30, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 30, 30, 30, 54, 55, 56, 57, 59, 59, 65, + 66, 90, 91, 60, 60, 8, 61, 62, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 8, 8, 8, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 8, 8, 8, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 8, 8, 8, 8, - 67, 70, 72, 74, 74, 74, 74, 74, 74, 93, - 119, 75, 95, 96, 73, 71, 76, 120, 68, 97, - 216, 98, 217, 94, 121, 99, 77, 78, 116, 79, - 79, 79, 79, 79, 80, 78, 117, 83, 83, 83, - 83, 83, 83, 85, 81, 100, 123, 118, 157, 82, - 124, 424, 81, 423, 125, 101, 147, 81, 102, 86, - - 103, 87, 88, 110, 104, 81, 107, 126, 108, 105, - 128, 111, 132, 112, 82, 106, 113, 109, 422, 133, - 134, 421, 114, 137, 420, 129, 138, 141, 130, 135, - 204, 142, 136, 143, 139, 184, 148, 144, 185, 186, - 419, 140, 187, 418, 188, 205, 145, 74, 74, 74, - 74, 74, 74, 153, 153, 153, 153, 153, 153, 229, - 230, 417, 151, 254, 255, 256, 416, 78, 154, 79, - 79, 79, 79, 79, 80, 151, 280, 281, 282, 415, - 414, 154, 413, 78, 81, 80, 80, 80, 80, 80, - 80, 190, 288, 289, 290, 412, 155, 81, 155, 191, - - 81, 156, 156, 156, 156, 156, 156, 297, 298, 299, - 411, 410, 78, 81, 83, 83, 83, 83, 83, 83, - 211, 304, 305, 306, 409, 219, 408, 219, 212, 81, - 220, 220, 220, 220, 220, 220, 153, 153, 153, 153, - 153, 153, 81, 308, 309, 310, 407, 221, 406, 221, - 405, 154, 222, 222, 222, 222, 222, 222, 156, 156, - 156, 156, 156, 156, 154, 156, 156, 156, 156, 156, - 156, 275, 220, 220, 220, 220, 220, 220, 404, 276, - 220, 220, 220, 220, 220, 220, 222, 222, 222, 222, - 222, 222, 222, 222, 222, 222, 222, 222, 316, 317, - - 318, 396, 403, 402, 401, 400, 399, 395, 394, 393, - 392, 391, 397, 390, 398, 58, 58, 58, 58, 92, - 92, 150, 150, 152, 389, 152, 152, 388, 387, 386, - 385, 384, 383, 382, 381, 380, 379, 378, 377, 376, - 375, 374, 373, 372, 371, 370, 369, 368, 367, 366, - 365, 364, 363, 362, 361, 360, 359, 358, 357, 356, - 355, 354, 353, 352, 351, 350, 349, 348, 347, 346, - 345, 344, 343, 342, 341, 340, 339, 338, 337, 336, - 335, 334, 333, 332, 331, 330, 329, 328, 327, 326, - 325, 324, 323, 322, 321, 320, 319, 315, 314, 313, - - 312, 311, 307, 303, 302, 301, 300, 296, 295, 294, - 293, 292, 291, 287, 286, 285, 284, 283, 279, 278, - 277, 274, 273, 272, 271, 270, 269, 268, 267, 266, - 265, 264, 263, 262, 261, 260, 259, 258, 257, 253, - 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, - 242, 241, 240, 239, 238, 237, 236, 235, 234, 233, - 232, 231, 228, 227, 226, 225, 224, 223, 218, 215, - 214, 213, 210, 209, 208, 207, 206, 203, 202, 201, - 200, 199, 198, 197, 196, 195, 194, 193, 192, 189, - 183, 182, 181, 180, 179, 178, 177, 176, 175, 174, - - 173, 172, 171, 170, 169, 168, 167, 166, 165, 164, - 163, 162, 161, 160, 159, 158, 149, 146, 131, 127, - 122, 115, 89, 84, 69, 64, 425, 7, 425, 425, - 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, - 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, - 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, - 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, - 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, - 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, - 425, 425, 425, 425 - + 63, 63, 63, 63, 63, 63, 63, 63, 8, 8, + 8, 8, 67, 70, 72, 74, 74, 74, 74, 74, + 74, 74, 93, 119, 75, 95, 96, 73, 71, 76, + 120, 68, 97, 158, 98, 123, 94, 121, 99, 124, + 77, 78, 457, 79, 79, 79, 79, 79, 79, 80, + 78, 148, 83, 83, 83, 83, 83, 83, 83, 81, + 85, 100, 142, 456, 82, 107, 143, 108, 81, 103, + + 455, 101, 81, 104, 102, 110, 109, 86, 105, 87, + 88, 81, 116, 111, 106, 112, 125, 128, 113, 82, + 117, 149, 206, 219, 114, 220, 132, 138, 178, 126, + 139, 118, 129, 133, 134, 130, 144, 207, 140, 192, + 145, 179, 454, 135, 136, 141, 137, 193, 453, 146, + 74, 74, 74, 74, 74, 74, 74, 154, 154, 154, + 154, 154, 154, 154, 452, 186, 152, 214, 187, 188, + 232, 233, 189, 155, 190, 215, 258, 259, 260, 152, + 285, 286, 287, 422, 423, 78, 155, 79, 79, 79, + 79, 79, 79, 80, 78, 451, 80, 80, 80, 80, + + 80, 80, 80, 81, 157, 157, 157, 157, 157, 157, + 157, 450, 81, 156, 449, 156, 81, 448, 157, 157, + 157, 157, 157, 157, 157, 81, 78, 280, 83, 83, + 83, 83, 83, 83, 83, 281, 293, 294, 295, 447, + 222, 446, 222, 445, 81, 223, 223, 223, 223, 223, + 223, 223, 302, 303, 304, 444, 443, 81, 154, 154, + 154, 154, 154, 154, 154, 309, 310, 311, 442, 441, + 224, 440, 224, 439, 155, 225, 225, 225, 225, 225, + 225, 225, 313, 314, 315, 438, 437, 155, 157, 157, + 157, 157, 157, 157, 157, 223, 223, 223, 223, 223, + + 223, 223, 223, 223, 223, 223, 223, 223, 223, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 321, 322, 323, 403, 404, 405, 436, + 435, 434, 433, 432, 431, 430, 429, 428, 427, 406, + 426, 407, 58, 58, 58, 58, 92, 92, 151, 151, + 153, 425, 153, 153, 424, 421, 420, 419, 418, 417, + 416, 415, 414, 413, 412, 411, 410, 409, 408, 402, + 401, 400, 399, 398, 397, 396, 395, 394, 393, 392, + 391, 390, 389, 388, 387, 386, 385, 384, 383, 382, + 381, 380, 379, 378, 377, 376, 375, 374, 373, 372, + + 371, 370, 369, 368, 367, 366, 365, 364, 363, 362, + 361, 360, 359, 358, 357, 356, 355, 354, 353, 352, + 351, 350, 349, 348, 347, 346, 345, 344, 343, 342, + 341, 340, 339, 338, 337, 336, 335, 334, 333, 332, + 331, 330, 329, 328, 327, 326, 325, 324, 320, 319, + 318, 317, 316, 312, 308, 307, 306, 305, 301, 300, + 299, 298, 297, 296, 292, 291, 290, 289, 288, 284, + 283, 282, 279, 278, 277, 276, 275, 274, 273, 272, + 271, 270, 269, 268, 267, 266, 265, 264, 263, 262, + 261, 257, 256, 255, 254, 253, 252, 251, 250, 249, + + 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, + 238, 237, 236, 235, 234, 231, 230, 229, 228, 227, + 226, 221, 218, 217, 216, 213, 212, 211, 210, 209, + 208, 205, 204, 203, 202, 201, 200, 199, 198, 197, + 196, 195, 194, 191, 185, 184, 183, 182, 181, 180, + 177, 176, 175, 174, 173, 172, 171, 170, 169, 168, + 167, 166, 165, 164, 163, 162, 161, 160, 159, 150, + 147, 131, 127, 122, 115, 89, 84, 69, 64, 458, + 7, 458, 458, 458, 458, 458, 458, 458, 458, 458, + 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, + + 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, + 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, + 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, + 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, + 458, 458, 458, 458, 458, 458, 458, 458 } ; -static yyconst flex_int16_t yy_chk[695] = +static yyconst flex_int16_t yy_chk[749] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -677,8 +693,8 @@ static yyconst flex_int16_t yy_chk[695] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 4, 12, 12, - 28, 28, 3, 4, 5, 5, 5, 5, 5, 5, + 1, 1, 1, 1, 1, 1, 1, 3, 4, 12, + 12, 28, 28, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, @@ -686,72 +702,77 @@ static yyconst flex_int16_t yy_chk[695] = 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 13, 17, 19, 20, 20, 20, 20, 20, 20, 33, - 42, 21, 34, 34, 19, 17, 21, 42, 13, 35, - 145, 35, 145, 33, 42, 35, 21, 22, 41, 22, - 22, 22, 22, 22, 22, 23, 41, 23, 23, 23, - 23, 23, 23, 26, 22, 36, 44, 41, 430, 22, - 44, 423, 23, 422, 45, 36, 55, 22, 36, 26, - - 37, 26, 26, 39, 37, 23, 38, 45, 38, 37, - 47, 39, 49, 39, 22, 37, 39, 38, 421, 49, - 49, 420, 39, 50, 419, 47, 50, 51, 47, 49, - 135, 51, 49, 52, 50, 120, 55, 52, 120, 120, - 417, 50, 120, 416, 120, 135, 52, 74, 74, 74, - 74, 74, 74, 78, 78, 78, 78, 78, 78, 167, - 167, 415, 74, 192, 192, 192, 413, 79, 78, 79, - 79, 79, 79, 79, 79, 74, 215, 215, 215, 412, - 411, 78, 410, 80, 79, 80, 80, 80, 80, 80, - 80, 122, 226, 226, 226, 409, 81, 79, 81, 122, - - 80, 81, 81, 81, 81, 81, 81, 234, 234, 234, - 408, 407, 83, 80, 83, 83, 83, 83, 83, 83, - 141, 241, 241, 241, 398, 151, 397, 151, 141, 83, - 151, 151, 151, 151, 151, 151, 153, 153, 153, 153, - 153, 153, 83, 245, 245, 245, 396, 154, 395, 154, - 393, 153, 154, 154, 154, 154, 154, 154, 155, 155, - 155, 155, 155, 155, 153, 156, 156, 156, 156, 156, - 156, 211, 219, 219, 219, 219, 219, 219, 392, 211, - 220, 220, 220, 220, 220, 220, 221, 221, 221, 221, - 221, 221, 222, 222, 222, 222, 222, 222, 251, 251, - - 251, 381, 391, 388, 387, 385, 382, 380, 379, 378, - 376, 375, 381, 374, 381, 426, 426, 426, 426, 427, - 427, 428, 428, 429, 371, 429, 429, 370, 369, 368, - 367, 366, 365, 364, 359, 356, 353, 352, 351, 350, - 349, 347, 345, 344, 343, 342, 340, 339, 337, 335, - 334, 333, 332, 331, 330, 329, 327, 326, 325, 324, - 323, 322, 321, 320, 319, 315, 314, 311, 300, 296, - 295, 294, 293, 286, 285, 284, 279, 278, 277, 276, - 275, 274, 271, 270, 269, 268, 267, 266, 265, 264, - 263, 262, 261, 260, 259, 258, 257, 250, 249, 248, - - 247, 246, 244, 240, 239, 238, 237, 233, 232, 231, - 230, 229, 228, 225, 223, 218, 217, 216, 214, 213, - 212, 210, 209, 208, 207, 206, 205, 204, 203, 202, - 201, 200, 199, 198, 197, 196, 195, 194, 193, 191, - 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, - 180, 179, 177, 176, 175, 174, 173, 172, 171, 170, - 169, 168, 166, 165, 164, 163, 162, 161, 146, 144, - 143, 142, 140, 139, 138, 137, 136, 134, 133, 132, - 131, 130, 129, 128, 127, 126, 125, 124, 123, 121, - 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, - - 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, - 98, 97, 96, 95, 91, 87, 60, 53, 48, 46, - 43, 40, 27, 24, 16, 11, 7, 425, 425, 425, - 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, - 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, - 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, - 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, - 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, - 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, - 425, 425, 425, 425 - + 5, 5, 13, 17, 19, 20, 20, 20, 20, 20, + 20, 20, 33, 42, 21, 34, 34, 19, 17, 21, + 42, 13, 35, 463, 35, 44, 33, 42, 35, 44, + 21, 22, 455, 22, 22, 22, 22, 22, 22, 22, + 23, 55, 23, 23, 23, 23, 23, 23, 23, 22, + 26, 36, 51, 454, 22, 38, 51, 38, 23, 37, + + 453, 36, 22, 37, 36, 39, 38, 26, 37, 26, + 26, 23, 41, 39, 37, 39, 45, 47, 39, 22, + 41, 55, 135, 146, 39, 146, 49, 50, 112, 45, + 50, 41, 47, 49, 49, 47, 52, 135, 50, 122, + 52, 112, 452, 49, 49, 50, 49, 122, 451, 52, + 74, 74, 74, 74, 74, 74, 74, 78, 78, 78, + 78, 78, 78, 78, 450, 120, 74, 142, 120, 120, + 168, 168, 120, 78, 120, 142, 194, 194, 194, 74, + 218, 218, 218, 417, 417, 79, 78, 79, 79, 79, + 79, 79, 79, 79, 80, 448, 80, 80, 80, 80, + + 80, 80, 80, 79, 156, 156, 156, 156, 156, 156, + 156, 446, 80, 81, 445, 81, 79, 444, 81, 81, + 81, 81, 81, 81, 81, 80, 83, 214, 83, 83, + 83, 83, 83, 83, 83, 214, 229, 229, 229, 443, + 152, 442, 152, 440, 83, 152, 152, 152, 152, 152, + 152, 152, 237, 237, 237, 439, 438, 83, 154, 154, + 154, 154, 154, 154, 154, 245, 245, 245, 437, 436, + 155, 435, 155, 434, 154, 155, 155, 155, 155, 155, + 155, 155, 249, 249, 249, 433, 432, 154, 157, 157, + 157, 157, 157, 157, 157, 222, 222, 222, 222, 222, + + 222, 222, 223, 223, 223, 223, 223, 223, 223, 224, + 224, 224, 224, 224, 224, 224, 225, 225, 225, 225, + 225, 225, 225, 255, 255, 255, 388, 388, 388, 430, + 429, 428, 427, 426, 425, 424, 423, 422, 421, 388, + 420, 388, 459, 459, 459, 459, 460, 460, 461, 461, + 462, 419, 462, 462, 418, 416, 407, 406, 405, 404, + 403, 402, 400, 399, 398, 395, 394, 392, 389, 387, + 386, 385, 383, 382, 381, 378, 377, 376, 375, 374, + 373, 372, 371, 365, 362, 359, 358, 357, 356, 355, + 353, 351, 350, 349, 348, 346, 345, 343, 341, 340, + + 339, 338, 337, 336, 335, 334, 332, 331, 330, 329, + 328, 327, 326, 325, 324, 320, 319, 316, 305, 301, + 300, 299, 298, 291, 290, 289, 284, 283, 282, 281, + 280, 279, 276, 275, 274, 273, 272, 271, 270, 269, + 268, 267, 266, 265, 264, 263, 262, 261, 254, 253, + 252, 251, 250, 248, 244, 242, 241, 240, 236, 235, + 234, 233, 232, 231, 228, 226, 221, 220, 219, 217, + 216, 215, 213, 212, 211, 210, 209, 208, 207, 206, + 205, 204, 203, 202, 201, 200, 199, 198, 197, 196, + 195, 193, 192, 191, 190, 189, 188, 187, 186, 185, + + 184, 183, 182, 181, 179, 178, 177, 176, 175, 174, + 173, 172, 171, 170, 169, 167, 166, 165, 164, 163, + 162, 147, 145, 144, 143, 141, 140, 139, 138, 137, + 136, 134, 133, 132, 131, 130, 129, 128, 127, 126, + 125, 124, 123, 121, 118, 117, 116, 115, 114, 113, + 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, + 101, 100, 99, 98, 97, 96, 95, 91, 87, 60, + 53, 48, 46, 43, 40, 27, 24, 16, 11, 7, + 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, + 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, + + 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, + 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, + 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, + 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, + 458, 458, 458, 458, 458, 458, 458, 458 } ; /* Table of booleans, true if rule could match eol. */ -static yyconst flex_int32_t yy_rule_can_match_eol[148] = +static yyconst flex_int32_t yy_rule_can_match_eol[156] = { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -760,7 +781,7 @@ static yyconst flex_int32_t yy_rule_can_match_eol[148] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, }; + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, }; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. @@ -771,7 +792,7 @@ static yyconst flex_int32_t yy_rule_can_match_eol[148] = #define YY_RESTORE_YY_MORE_OFFSET /* // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -786,6 +807,7 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp). #include "compiler/glslang.h" #include "compiler/ParseHelper.h" +#include "compiler/preprocessor/new/Token.h" #include "compiler/util.h" #include "glslang_tab.h" @@ -821,8 +843,8 @@ struct yyguts_t size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; - int yy_n_chars; - int yyleng_r; + yy_size_t yy_n_chars; + yy_size_t yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; @@ -875,7 +897,7 @@ FILE *yyget_out (yyscan_t yyscanner ); void yyset_out (FILE * out_str ,yyscan_t yyscanner ); -int yyget_leng (yyscan_t yyscanner ); +yy_size_t yyget_leng (yyscan_t yyscanner ); char *yyget_text (yyscan_t yyscanner ); @@ -1086,13 +1108,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 426 ) + if ( yy_current_state >= 459 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 425 ); + while ( yy_current_state != 458 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -1481,220 +1503,252 @@ YY_RULE_SETUP YY_BREAK case 90: YY_RULE_SETUP +{ return reserved_word(yyscanner); } + YY_BREAK +case 91: +YY_RULE_SETUP +{ return reserved_word(yyscanner); } + YY_BREAK +case 92: +YY_RULE_SETUP +{ return reserved_word(yyscanner); } + YY_BREAK +case 93: +YY_RULE_SETUP +{ return reserved_word(yyscanner); } + YY_BREAK +case 94: +YY_RULE_SETUP +{ return reserved_word(yyscanner); } + YY_BREAK +case 95: +YY_RULE_SETUP +{ return reserved_word(yyscanner); } + YY_BREAK +case 96: +YY_RULE_SETUP +{ return reserved_word(yyscanner); } + YY_BREAK +case 97: +YY_RULE_SETUP +{ return reserved_word(yyscanner); } + YY_BREAK +case 98: +YY_RULE_SETUP { yylval->lex.string = NewPoolTString(yytext); return check_type(yyscanner); } YY_BREAK -case 91: +case 99: YY_RULE_SETUP { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } YY_BREAK -case 92: +case 100: YY_RULE_SETUP { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } YY_BREAK -case 93: +case 101: YY_RULE_SETUP -{ context->error(yylineno, "Invalid Octal number.", yytext, "", ""); context->recover(); return 0;} +{ context->error(yylineno, "Invalid Octal number.", yytext); context->recover(); return 0;} YY_BREAK -case 94: +case 102: YY_RULE_SETUP { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } YY_BREAK -case 95: +case 103: YY_RULE_SETUP { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); } YY_BREAK -case 96: +case 104: YY_RULE_SETUP { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); } YY_BREAK -case 97: +case 105: YY_RULE_SETUP { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); } YY_BREAK -case 98: +case 106: YY_RULE_SETUP { return(ADD_ASSIGN); } YY_BREAK -case 99: +case 107: YY_RULE_SETUP { return(SUB_ASSIGN); } YY_BREAK -case 100: +case 108: YY_RULE_SETUP { return(MUL_ASSIGN); } YY_BREAK -case 101: +case 109: YY_RULE_SETUP { return(DIV_ASSIGN); } YY_BREAK -case 102: +case 110: YY_RULE_SETUP { return(MOD_ASSIGN); } YY_BREAK -case 103: +case 111: YY_RULE_SETUP { return(LEFT_ASSIGN); } YY_BREAK -case 104: +case 112: YY_RULE_SETUP { return(RIGHT_ASSIGN); } YY_BREAK -case 105: +case 113: YY_RULE_SETUP { return(AND_ASSIGN); } YY_BREAK -case 106: +case 114: YY_RULE_SETUP { return(XOR_ASSIGN); } YY_BREAK -case 107: +case 115: YY_RULE_SETUP { return(OR_ASSIGN); } YY_BREAK -case 108: +case 116: YY_RULE_SETUP { return(INC_OP); } YY_BREAK -case 109: +case 117: YY_RULE_SETUP { return(DEC_OP); } YY_BREAK -case 110: +case 118: YY_RULE_SETUP { return(AND_OP); } YY_BREAK -case 111: +case 119: YY_RULE_SETUP { return(OR_OP); } YY_BREAK -case 112: +case 120: YY_RULE_SETUP { return(XOR_OP); } YY_BREAK -case 113: +case 121: YY_RULE_SETUP { return(LE_OP); } YY_BREAK -case 114: +case 122: YY_RULE_SETUP { return(GE_OP); } YY_BREAK -case 115: +case 123: YY_RULE_SETUP { return(EQ_OP); } YY_BREAK -case 116: +case 124: YY_RULE_SETUP { return(NE_OP); } YY_BREAK -case 117: +case 125: YY_RULE_SETUP { return(LEFT_OP); } YY_BREAK -case 118: +case 126: YY_RULE_SETUP { return(RIGHT_OP); } YY_BREAK -case 119: +case 127: YY_RULE_SETUP { context->lexAfterType = false; return(SEMICOLON); } YY_BREAK -case 120: +case 128: YY_RULE_SETUP { context->lexAfterType = false; return(LEFT_BRACE); } YY_BREAK -case 121: +case 129: YY_RULE_SETUP { return(RIGHT_BRACE); } YY_BREAK -case 122: +case 130: YY_RULE_SETUP { if (context->inTypeParen) context->lexAfterType = false; return(COMMA); } YY_BREAK -case 123: +case 131: YY_RULE_SETUP { return(COLON); } YY_BREAK -case 124: +case 132: YY_RULE_SETUP { context->lexAfterType = false; return(EQUAL); } YY_BREAK -case 125: +case 133: YY_RULE_SETUP { context->lexAfterType = false; context->inTypeParen = true; return(LEFT_PAREN); } YY_BREAK -case 126: +case 134: YY_RULE_SETUP { context->inTypeParen = false; return(RIGHT_PAREN); } YY_BREAK -case 127: +case 135: YY_RULE_SETUP { return(LEFT_BRACKET); } YY_BREAK -case 128: +case 136: YY_RULE_SETUP { return(RIGHT_BRACKET); } YY_BREAK -case 129: +case 137: YY_RULE_SETUP { BEGIN(FIELDS); return(DOT); } YY_BREAK -case 130: +case 138: YY_RULE_SETUP { return(BANG); } YY_BREAK -case 131: +case 139: YY_RULE_SETUP { return(DASH); } YY_BREAK -case 132: +case 140: YY_RULE_SETUP { return(TILDE); } YY_BREAK -case 133: +case 141: YY_RULE_SETUP { return(PLUS); } YY_BREAK -case 134: +case 142: YY_RULE_SETUP { return(STAR); } YY_BREAK -case 135: +case 143: YY_RULE_SETUP { return(SLASH); } YY_BREAK -case 136: +case 144: YY_RULE_SETUP { return(PERCENT); } YY_BREAK -case 137: +case 145: YY_RULE_SETUP { return(LEFT_ANGLE); } YY_BREAK -case 138: +case 146: YY_RULE_SETUP { return(RIGHT_ANGLE); } YY_BREAK -case 139: +case 147: YY_RULE_SETUP { return(VERTICAL_BAR); } YY_BREAK -case 140: +case 148: YY_RULE_SETUP { return(CARET); } YY_BREAK -case 141: +case 149: YY_RULE_SETUP { return(AMPERSAND); } YY_BREAK -case 142: +case 150: YY_RULE_SETUP { return(QUESTION); } YY_BREAK -case 143: +case 151: YY_RULE_SETUP { BEGIN(INITIAL); @@ -1702,12 +1756,12 @@ YY_RULE_SETUP return FIELD_SELECTION; } YY_BREAK -case 144: +case 152: YY_RULE_SETUP {} YY_BREAK -case 145: -/* rule 145 can match eol */ +case 153: +/* rule 153 can match eol */ YY_RULE_SETUP { } YY_BREAK @@ -1716,11 +1770,11 @@ case YY_STATE_EOF(COMMENT): case YY_STATE_EOF(FIELDS): { context->AfterEOF = true; yyterminate(); } YY_BREAK -case 146: +case 154: YY_RULE_SETUP { context->warning(yylineno, "Unknown char", yytext, ""); return 0; } YY_BREAK -case 147: +case 155: YY_RULE_SETUP ECHO; YY_BREAK @@ -1909,7 +1963,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) else { - int num_to_read = + yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) @@ -1923,7 +1977,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) if ( b->yy_is_our_buffer ) { - int new_size = b->yy_buf_size * 2; + yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; @@ -1954,7 +2008,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, (size_t) num_to_read ); + yyg->yy_n_chars, num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } @@ -2016,7 +2070,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 426 ) + if ( yy_current_state >= 459 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -2045,11 +2099,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 426 ) + if ( yy_current_state >= 459 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 425); + yy_is_jam = (yy_current_state == 458); return yy_is_jam ? 0 : yy_current_state; } @@ -2079,7 +2133,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) else { /* need more input */ - int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; + yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr; ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) @@ -2103,7 +2157,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) case EOB_ACT_END_OF_FILE: { if ( yywrap(yyscanner ) ) - return EOF; + return 0; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; @@ -2366,7 +2420,7 @@ void yypop_buffer_state (yyscan_t yyscanner) */ static void yyensure_buffer_stack (yyscan_t yyscanner) { - int num_to_alloc; + yy_size_t num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { @@ -2464,12 +2518,11 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner) * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ -YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) +YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; - yy_size_t n; - int i; + yy_size_t n, i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; @@ -2619,7 +2672,7 @@ FILE *yyget_out (yyscan_t yyscanner) /** Get the length of the current token. * @param yyscanner The scanner object. */ -int yyget_leng (yyscan_t yyscanner) +yy_size_t yyget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; @@ -2894,10 +2947,15 @@ void yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" +#if !ANGLE_USE_NEW_PREPROCESSOR extern "C" { // Preprocessor interface. #include "compiler/preprocessor/preprocess.h" +extern int InitPreprocessor(); +extern int FinalizePreprocessor(); +extern void PredefineIntMacro(const char *name, int value); + #define SETUP_CONTEXT(pp) \ TParseContext* context = (TParseContext*) pp->pC; \ struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; @@ -2906,26 +2964,26 @@ extern "C" { void CPPDebugLogMsg(const char *msg) { SETUP_CONTEXT(cpp); - context->infoSink.debug.message(EPrefixNone, msg); + context->trace(msg); } void CPPWarningToInfoLog(const char *msg) { SETUP_CONTEXT(cpp); - context->warning(yylineno, msg, "", ""); + context->warning(yylineno, msg, ""); } void CPPShInfoLogMsg(const char *msg) { SETUP_CONTEXT(cpp); - context->error(yylineno, msg, "", ""); + context->error(yylineno, msg, ""); context->recover(); } -void CPPErrorToInfoLog(char *msg) +void CPPErrorToInfoLog(const char *msg) { SETUP_CONTEXT(cpp); - context->error(yylineno, msg, "", ""); + context->error(yylineno, msg, ""); context->recover(); } @@ -2980,88 +3038,15 @@ void DecLineNumber() void HandlePragma(const char **tokens, int numTokens) { SETUP_CONTEXT(cpp); - if (!strcmp(tokens[0], "optimize")) { - if (numTokens != 4) { - CPPShInfoLogMsg("optimize pragma syntax is incorrect"); - return; - } - - if (strcmp(tokens[1], "(")) { - CPPShInfoLogMsg("\"(\" expected after 'optimize' keyword"); - return; - } - - if (!strcmp(tokens[2], "on")) - context->contextPragma.optimize = true; - else if (!strcmp(tokens[2], "off")) - context->contextPragma.optimize = false; - else { - CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma"); - return; - } - - if (strcmp(tokens[3], ")")) { - CPPShInfoLogMsg("\")\" expected to end 'optimize' pragma"); - return; - } - } else if (!strcmp(tokens[0], "debug")) { - if (numTokens != 4) { - CPPShInfoLogMsg("debug pragma syntax is incorrect"); - return; - } - - if (strcmp(tokens[1], "(")) { - CPPShInfoLogMsg("\"(\" expected after 'debug' keyword"); - return; - } - - if (!strcmp(tokens[2], "on")) - context->contextPragma.debug = true; - else if (!strcmp(tokens[2], "off")) - context->contextPragma.debug = false; - else { - CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma"); - return; - } - - if (strcmp(tokens[3], ")")) { - CPPShInfoLogMsg("\")\" expected to end 'debug' pragma"); - return; - } - } else { -#ifdef PRAGMA_TABLE - // - // implementation specific pragma - // use ((TParseContext *)cpp->pC)->contextPragma.pragmaTable to store the information about pragma - // For now, just ignore the pragma that the implementation cannot recognize - // An Example of one such implementation for a pragma that has a syntax like - // #pragma pragmaname(pragmavalue) - // This implementation stores the current pragmavalue against the pragma name in pragmaTable. - // - if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) { - TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable; - TPragmaTable::iterator iter; - iter = pragmaTable.find(TString(tokens[0])); - if (iter != pragmaTable.end()) { - iter->second = tokens[2]; - } else { - pragmaTable[ tokens[0] ] = tokens[2]; - } - } else if (numTokens >= 2) { - TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable; - TPragmaTable::iterator iter; - iter = pragmaTable.find(TString(tokens[0])); - if (iter != pragmaTable.end()) { - iter->second = tokens[1]; - } else { - pragmaTable[ tokens[0] ] = tokens[1]; - } - } -#endif // PRAGMA_TABLE - } + + if (numTokens != 4) return; + if (strcmp(tokens[1], "(") != 0) return; + if (strcmp(tokens[3], ")") != 0) return; + + context->handlePragmaDirective(yylineno, tokens[0], tokens[2]); } -void StoreStr(char *string) +void StoreStr(const char *string) { SETUP_CONTEXT(cpp); TString strSrc; @@ -3083,71 +3068,33 @@ void ResetTString(void) context->HashErrMsg = ""; } -TBehavior GetBehavior(const char* behavior) -{ - if (!strcmp("require", behavior)) - return EBhRequire; - else if (!strcmp("enable", behavior)) - return EBhEnable; - else if (!strcmp("disable", behavior)) - return EBhDisable; - else if (!strcmp("warn", behavior)) - return EBhWarn; - else { - CPPShInfoLogMsg((TString("behavior '") + behavior + "' is not supported").c_str()); - return EBhDisable; - } -} - void updateExtensionBehavior(const char* extName, const char* behavior) { SETUP_CONTEXT(cpp); - TBehavior behaviorVal = GetBehavior(behavior); - TMap<TString, TBehavior>:: iterator iter; - TString msg; - - // special cased for all extension - if (!strcmp(extName, "all")) { - if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) { - CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior"); - return; - } else { - for (iter = context->extensionBehavior.begin(); iter != context->extensionBehavior.end(); ++iter) - iter->second = behaviorVal; - } - } else { - iter = context->extensionBehavior.find(TString(extName)); - if (iter == context->extensionBehavior.end()) { - switch (behaviorVal) { - case EBhRequire: - CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str()); - break; - case EBhEnable: - case EBhWarn: - case EBhDisable: - msg = TString("extension '") + extName + "' is not supported"; - context->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno); - break; - default: - break; - } - return; - } else - iter->second = behaviorVal; - } + context->handleExtensionDirective(yylineno, extName, behavior); } } // extern "C" +#endif // !ANGLE_USE_NEW_PREPROCESSOR int string_input(char* buf, int max_size, yyscan_t yyscanner) { - int len; - - if ((len = yylex_CPP(buf, max_size)) == 0) - return 0; - if (len >= max_size) - YY_FATAL_ERROR("input buffer overflow, can't enlarge buffer because scanner uses REJECT"); + int len = 0; + +#if ANGLE_USE_NEW_PREPROCESSOR + pp::Token token; + yyget_extra(yyscanner)->preprocessor.lex(&token); + len = token.type == pp::Token::LAST ? 0 : token.value.size(); + if ((len > 0) && (len < max_size)) + memcpy(buf, token.value.c_str(), len); + yyset_lineno(EncodeSourceLoc(token.location.file, token.location.line),yyscanner); +#else + len = yylex_CPP(buf, max_size); +#endif // ANGLE_USE_NEW_PREPROCESSOR - buf[len] = ' '; - return len+1; + if (len >= max_size) + YY_FATAL_ERROR("Input buffer overflow"); + else if (len > 0) + buf[len++] = ' '; + return len; } int check_type(yyscan_t yyscanner) { @@ -3178,9 +3125,9 @@ void yyerror(TParseContext* context, const char* reason) { struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; if (context->AfterEOF) { - context->error(yylineno, reason, "unexpected EOF", ""); + context->error(yylineno, reason, "unexpected EOF"); } else { - context->error(yylineno, reason, yytext, ""); + context->error(yylineno, reason, yytext); } context->recover(); } @@ -3199,22 +3146,43 @@ int glslang_finalize(TParseContext* context) { if (scanner == NULL) return 0; context->scanner = NULL; - return yylex_destroy(scanner); + yylex_destroy(scanner); + +#if !ANGLE_USE_NEW_PREPROCESSOR + FinalizePreprocessor(); +#endif + return 0; } -void glslang_scan(int count, const char* const string[], const int length[], - TParseContext* context) { +int glslang_scan(int count, const char* const string[], const int length[], + TParseContext* context) { yyrestart(NULL,context->scanner); yyset_lineno(EncodeSourceLoc(0, 1),context->scanner); context->AfterEOF = false; - - // Init preprocessor. + + // Initialize preprocessor. +#if ANGLE_USE_NEW_PREPROCESSOR + if (!context->preprocessor.init(count, string, length)) + return 1; +#else + if (InitPreprocessor()) + return 1; cpp->pC = context; - cpp->PaWhichStr = 0; - cpp->PaArgv = string; - cpp->PaArgc = count; - cpp->PaStrLen = length; cpp->pastFirstStatement = 0; - ScanFromString(string[0]); + if (InitScannerInput(cpp, count, string, length)) + return 1; +#endif // ANGLE_USE_NEW_PREPROCESSOR + + // Define extension macros. + const TExtensionBehavior& extBehavior = context->extensionBehavior(); + for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); + iter != extBehavior.end(); ++iter) { +#if ANGLE_USE_NEW_PREPROCESSOR + context->preprocessor.predefineMacro(iter->first.c_str(), 1); +#else + PredefineIntMacro(iter->first.c_str(), 1); +#endif + } + return 0; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.cpp b/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.cpp index 37a0f0522..46b514a07 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.cpp @@ -263,7 +263,7 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -286,6 +286,9 @@ #include "compiler/ParseHelper.h" #include "GLSLANG/ShaderLang.h" +#define YYENABLE_NLS 0 +#define YYLTYPE_IS_TRIVIAL 1 + #define YYLEX_PARAM context->scanner @@ -360,21 +363,21 @@ extern void yyerror(TParseContext* context, const char* reason); #define FRAG_VERT_ONLY(S, L) { \ if (context->shaderType != SH_FRAGMENT_SHADER && \ context->shaderType != SH_VERTEX_SHADER) { \ - context->error(L, " supported in vertex/fragment shaders only ", S, "", ""); \ + context->error(L, " supported in vertex/fragment shaders only ", S); \ context->recover(); \ } \ } #define VERTEX_ONLY(S, L) { \ if (context->shaderType != SH_VERTEX_SHADER) { \ - context->error(L, " supported in vertex shaders only ", S, "", ""); \ + context->error(L, " supported in vertex shaders only ", S); \ context->recover(); \ } \ } #define FRAG_ONLY(S, L) { \ if (context->shaderType != SH_FRAGMENT_SHADER) { \ - context->error(L, " supported in fragment shaders only ", S, "", ""); \ + context->error(L, " supported in fragment shaders only ", S); \ context->recover(); \ } \ } @@ -431,7 +434,7 @@ typedef short int yytype_int16; #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS +# if YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) @@ -748,27 +751,27 @@ static const yytype_int16 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 165, 165, 200, 203, 216, 221, 226, 232, 235, - 308, 311, 420, 430, 443, 451, 550, 553, 561, 565, - 572, 576, 583, 589, 598, 606, 661, 668, 678, 681, - 691, 701, 722, 723, 724, 729, 730, 739, 751, 752, - 760, 771, 775, 776, 786, 796, 806, 819, 820, 830, - 843, 847, 851, 855, 856, 869, 870, 883, 884, 897, - 898, 915, 916, 929, 930, 931, 932, 933, 937, 940, - 951, 959, 986, 991, 998, 1036, 1039, 1046, 1054, 1075, - 1096, 1107, 1136, 1141, 1151, 1156, 1166, 1169, 1172, 1175, - 1181, 1188, 1191, 1213, 1231, 1255, 1278, 1282, 1300, 1308, - 1340, 1360, 1449, 1458, 1481, 1484, 1490, 1498, 1506, 1514, - 1524, 1531, 1534, 1537, 1543, 1546, 1561, 1565, 1569, 1573, - 1582, 1587, 1592, 1597, 1602, 1607, 1612, 1617, 1622, 1627, - 1633, 1639, 1645, 1650, 1655, 1664, 1673, 1678, 1691, 1691, - 1705, 1705, 1714, 1717, 1732, 1768, 1772, 1778, 1786, 1802, - 1806, 1810, 1811, 1817, 1818, 1819, 1820, 1821, 1825, 1826, - 1826, 1826, 1836, 1837, 1841, 1841, 1842, 1842, 1847, 1850, - 1860, 1863, 1869, 1870, 1874, 1882, 1886, 1896, 1901, 1918, - 1918, 1923, 1923, 1930, 1930, 1938, 1941, 1947, 1950, 1956, - 1960, 1967, 1974, 1981, 1988, 1999, 2008, 2012, 2019, 2022, - 2028, 2028 + 0, 168, 168, 203, 206, 219, 224, 229, 235, 238, + 317, 320, 429, 439, 452, 460, 560, 563, 571, 575, + 582, 586, 593, 599, 608, 616, 671, 678, 688, 691, + 701, 711, 732, 733, 734, 739, 740, 749, 761, 762, + 770, 781, 785, 786, 796, 806, 816, 829, 830, 840, + 853, 857, 861, 865, 866, 879, 880, 893, 894, 907, + 908, 925, 926, 939, 940, 941, 942, 943, 947, 950, + 961, 969, 996, 1001, 1008, 1046, 1049, 1056, 1064, 1085, + 1106, 1117, 1146, 1151, 1161, 1166, 1176, 1179, 1182, 1185, + 1191, 1198, 1201, 1223, 1241, 1265, 1288, 1292, 1310, 1318, + 1350, 1370, 1459, 1468, 1491, 1494, 1500, 1508, 1516, 1524, + 1534, 1541, 1544, 1547, 1553, 1556, 1571, 1575, 1579, 1583, + 1592, 1597, 1602, 1607, 1612, 1617, 1622, 1627, 1632, 1637, + 1643, 1649, 1655, 1660, 1665, 1674, 1683, 1688, 1701, 1701, + 1715, 1715, 1724, 1727, 1742, 1778, 1782, 1788, 1796, 1812, + 1816, 1820, 1821, 1827, 1828, 1829, 1830, 1831, 1835, 1836, + 1836, 1836, 1846, 1847, 1851, 1851, 1852, 1852, 1857, 1860, + 1870, 1873, 1879, 1880, 1884, 1892, 1896, 1906, 1911, 1928, + 1928, 1933, 1933, 1940, 1940, 1948, 1951, 1957, 1960, 1966, + 1970, 1977, 1984, 1991, 1998, 2009, 2018, 2022, 2029, 2032, + 2038, 2038 }; #endif @@ -1404,7 +1407,7 @@ while (YYID (0)) we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +# if YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ @@ -2157,7 +2160,7 @@ yyreduce: const TSymbol* symbol = (yyvsp[(1) - (1)].lex).symbol; const TVariable* variable; if (symbol == 0) { - context->error((yyvsp[(1) - (1)].lex).line, "undeclared identifier", (yyvsp[(1) - (1)].lex).string->c_str(), ""); + context->error((yyvsp[(1) - (1)].lex).line, "undeclared identifier", (yyvsp[(1) - (1)].lex).string->c_str()); context->recover(); TType type(EbtFloat, EbpUndefined); TVariable* fakeVariable = new TVariable((yyvsp[(1) - (1)].lex).string, type); @@ -2166,7 +2169,7 @@ yyreduce: } else { // This identifier can only be a variable type symbol if (! symbol->isVariable()) { - context->error((yyvsp[(1) - (1)].lex).line, "variable expected", (yyvsp[(1) - (1)].lex).string->c_str(), ""); + context->error((yyvsp[(1) - (1)].lex).line, "variable expected", (yyvsp[(1) - (1)].lex).string->c_str()); context->recover(); } variable = static_cast<const TVariable*>(symbol); @@ -2201,7 +2204,7 @@ yyreduce: // check for overflow for constants // if (abs((yyvsp[(1) - (1)].lex).i) >= (1 << 16)) { - context->error((yyvsp[(1) - (1)].lex).line, " integer constant overflow", "", ""); + context->error((yyvsp[(1) - (1)].lex).line, " integer constant overflow", ""); context->recover(); } ConstantUnion *unionArray = new ConstantUnion[1]; @@ -2247,9 +2250,9 @@ yyreduce: { if (!(yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isVector()) { if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode()) - context->error((yyvsp[(2) - (4)].lex).line, " left of '[' is not of type array, matrix, or vector ", (yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode()->getSymbol().c_str(), ""); + context->error((yyvsp[(2) - (4)].lex).line, " left of '[' is not of type array, matrix, or vector ", (yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode()->getSymbol().c_str()); else - context->error((yyvsp[(2) - (4)].lex).line, " left of '[' is not of type array, matrix, or vector ", "expression", ""); + context->error((yyvsp[(2) - (4)].lex).line, " left of '[' is not of type array, matrix, or vector ", "expression"); context->recover(); } if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst && (yyvsp[(3) - (4)].interm.intermTypedNode)->getQualifier() == EvqConst) { @@ -2266,7 +2269,10 @@ yyreduce: } else { if ((yyvsp[(3) - (4)].interm.intermTypedNode)->getQualifier() == EvqConst) { if (((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector() || (yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix()) && (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getNominalSize() <= (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() ) { - context->error((yyvsp[(2) - (4)].lex).line, "", "[", "field selection out of range '%d'", (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst()); + std::stringstream extraInfoStream; + extraInfoStream << "field selection out of range '" << (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst() << "'"; + std::string extraInfo = extraInfoStream.str(); + context->error((yyvsp[(2) - (4)].lex).line, "", "[", extraInfo.c_str()); context->recover(); } else { if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) { @@ -2279,7 +2285,10 @@ yyreduce: context->recover(); } } else if ( (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getArraySize()) { - context->error((yyvsp[(2) - (4)].lex).line, "", "[", "array index out of range '%d'", (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst()); + std::stringstream extraInfoStream; + extraInfoStream << "array index out of range '" << (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst() << "'"; + std::string extraInfo = extraInfoStream.str(); + context->error((yyvsp[(2) - (4)].lex).line, "", "[", extraInfo.c_str()); context->recover(); } } @@ -2330,7 +2339,7 @@ yyreduce: { if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isArray()) { - context->error((yyvsp[(3) - (3)].lex).line, "cannot apply dot operator to an array", ".", ""); + context->error((yyvsp[(3) - (3)].lex).line, "cannot apply dot operator to an array", "."); context->recover(); } @@ -2375,7 +2384,7 @@ yyreduce: } if (fields.wholeRow || fields.wholeCol) { - context->error((yyvsp[(2) - (3)].lex).line, " non-scalar fields not implemented yet", ".", ""); + context->error((yyvsp[(2) - (3)].lex).line, " non-scalar fields not implemented yet", "."); context->recover(); ConstantUnion *unionArray = new ConstantUnion[1]; unionArray->setIConst(0); @@ -2393,7 +2402,7 @@ yyreduce: bool fieldFound = false; const TTypeList* fields = (yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getStruct(); if (fields == 0) { - context->error((yyvsp[(2) - (3)].lex).line, "structure has no fields", "Internal Error", ""); + context->error((yyvsp[(2) - (3)].lex).line, "structure has no fields", "Internal Error"); context->recover(); (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode); } else { @@ -2425,13 +2434,13 @@ yyreduce: (yyval.interm.intermTypedNode)->setType(*(*fields)[i].type); } } else { - context->error((yyvsp[(2) - (3)].lex).line, " no such field in structure", (yyvsp[(3) - (3)].lex).string->c_str(), ""); + context->error((yyvsp[(2) - (3)].lex).line, " no such field in structure", (yyvsp[(3) - (3)].lex).string->c_str()); context->recover(); (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode); } } } else { - context->error((yyvsp[(2) - (3)].lex).line, " field selection requires structure, vector, or matrix on left hand side", (yyvsp[(3) - (3)].lex).string->c_str(), ""); + context->error((yyvsp[(2) - (3)].lex).line, " field selection requires structure, vector, or matrix on left hand side", (yyvsp[(3) - (3)].lex).string->c_str()); context->recover(); (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode); } @@ -2530,9 +2539,10 @@ yyreduce: // (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(op, (yyvsp[(1) - (1)].interm).intermNode, 0, context->symbolTable); if ((yyval.interm.intermTypedNode) == 0) { - context->error((yyvsp[(1) - (1)].interm).intermNode->getLine(), " wrong operand type", "Internal Error", - "built in unary operator function. Type: %s", - static_cast<TIntermTyped*>((yyvsp[(1) - (1)].interm).intermNode)->getCompleteString().c_str()); + std::stringstream extraInfoStream; + extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>((yyvsp[(1) - (1)].interm).intermNode)->getCompleteString(); + std::string extraInfo = extraInfoStream.str(); + context->error((yyvsp[(1) - (1)].interm).intermNode->getLine(), " wrong operand type", "Internal Error", extraInfo.c_str()); YYERROR; } } else { @@ -2556,7 +2566,7 @@ yyreduce: qual = fnCandidate->getParam(i).type->getQualifier(); if (qual == EvqOut || qual == EvqInOut) { if (context->lValueErrorCheck((yyval.interm.intermTypedNode)->getLine(), "assign", (yyval.interm.intermTypedNode)->getAsAggregate()->getSequence()[i]->getAsTyped())) { - context->error((yyvsp[(1) - (1)].interm).intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", ""); + context->error((yyvsp[(1) - (1)].interm).intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error"); context->recover(); } } @@ -2586,7 +2596,7 @@ yyreduce: case 17: { - context->error((yyvsp[(3) - (3)].interm).line, "methods are not supported", "", ""); + context->error((yyvsp[(3) - (3)].interm).line, "methods are not supported", ""); context->recover(); (yyval.interm) = (yyvsp[(3) - (3)].interm); ;} @@ -2697,7 +2707,7 @@ yyreduce: default: break; } if (op == EOpNull) { - context->error((yyvsp[(1) - (1)].interm.type).line, "cannot construct this type", getBasicString((yyvsp[(1) - (1)].interm.type).type), ""); + context->error((yyvsp[(1) - (1)].interm.type).line, "cannot construct this type", getBasicString((yyvsp[(1) - (1)].interm.type).type)); context->recover(); (yyvsp[(1) - (1)].interm.type).type = EbtFloat; op = EOpConstructFloat; @@ -3191,12 +3201,12 @@ yyreduce: TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find((yyvsp[(1) - (2)].interm.function)->getMangledName())); if (prevDec) { if (prevDec->getReturnType() != (yyvsp[(1) - (2)].interm.function)->getReturnType()) { - context->error((yyvsp[(2) - (2)].lex).line, "overloaded functions must have the same return type", (yyvsp[(1) - (2)].interm.function)->getReturnType().getBasicString(), ""); + context->error((yyvsp[(2) - (2)].lex).line, "overloaded functions must have the same return type", (yyvsp[(1) - (2)].interm.function)->getReturnType().getBasicString()); context->recover(); } for (int i = 0; i < prevDec->getParamCount(); ++i) { if (prevDec->getParam(i).type->getQualifier() != (yyvsp[(1) - (2)].interm.function)->getParam(i).type->getQualifier()) { - context->error((yyvsp[(2) - (2)].lex).line, "overloaded functions must have the same parameter qualifiers", (yyvsp[(1) - (2)].interm.function)->getParam(i).type->getQualifierString(), ""); + context->error((yyvsp[(2) - (2)].lex).line, "overloaded functions must have the same parameter qualifiers", (yyvsp[(1) - (2)].interm.function)->getParam(i).type->getQualifierString()); context->recover(); } } @@ -3253,7 +3263,7 @@ yyreduce: // // This parameter > first is void // - context->error((yyvsp[(2) - (3)].lex).line, "cannot be an argument type except for '(void)'", "void", ""); + context->error((yyvsp[(2) - (3)].lex).line, "cannot be an argument type except for '(void)'", "void"); context->recover(); delete (yyvsp[(3) - (3)].interm).param.type; } else { @@ -3268,7 +3278,7 @@ yyreduce: { if ((yyvsp[(1) - (3)].interm.type).qualifier != EvqGlobal && (yyvsp[(1) - (3)].interm.type).qualifier != EvqTemporary) { - context->error((yyvsp[(2) - (3)].lex).line, "no qualifiers allowed for function return", getQualifierString((yyvsp[(1) - (3)].interm.type).qualifier), ""); + context->error((yyvsp[(2) - (3)].lex).line, "no qualifiers allowed for function return", getQualifierString((yyvsp[(1) - (3)].interm.type).qualifier)); context->recover(); } // make sure a sampler is not involved as well... @@ -3289,7 +3299,7 @@ yyreduce: { if ((yyvsp[(1) - (2)].interm.type).type == EbtVoid) { - context->error((yyvsp[(2) - (2)].lex).line, "illegal use of type 'void'", (yyvsp[(2) - (2)].lex).string->c_str(), ""); + context->error((yyvsp[(2) - (2)].lex).line, "illegal use of type 'void'", (yyvsp[(2) - (2)].lex).string->c_str()); context->recover(); } if (context->reservedErrorCheck((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string)) @@ -3410,7 +3420,7 @@ yyreduce: { if ((yyvsp[(1) - (3)].interm).type.type == EbtInvariant && !(yyvsp[(3) - (3)].lex).symbol) { - context->error((yyvsp[(3) - (3)].lex).line, "undeclared identifier declared as invariant", (yyvsp[(3) - (3)].lex).string->c_str(), ""); + context->error((yyvsp[(3) - (3)].lex).line, "undeclared identifier declared as invariant", (yyvsp[(3) - (3)].lex).string->c_str()); context->recover(); } @@ -3538,7 +3548,7 @@ yyreduce: case 98: { - context->error((yyvsp[(2) - (4)].lex).line, "unsized array declarations not supported", (yyvsp[(2) - (4)].lex).string->c_str(), ""); + context->error((yyvsp[(2) - (4)].lex).line, "unsized array declarations not supported", (yyvsp[(2) - (4)].lex).string->c_str()); context->recover(); TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (4)].lex).string, TType((yyvsp[(1) - (4)].interm.type)), (yyvsp[(2) - (4)].lex).line); @@ -3616,7 +3626,7 @@ yyreduce: (yyval.interm).type.setBasic(EbtInvariant, EvqInvariantVaryingOut, (yyvsp[(2) - (2)].lex).line); if (!(yyvsp[(2) - (2)].lex).symbol) { - context->error((yyvsp[(2) - (2)].lex).line, "undeclared identifier declared as invariant", (yyvsp[(2) - (2)].lex).string->c_str(), ""); + context->error((yyvsp[(2) - (2)].lex).line, "undeclared identifier declared as invariant", (yyvsp[(2) - (2)].lex).string->c_str()); context->recover(); (yyval.interm).intermAggregate = 0; @@ -3635,7 +3645,7 @@ yyreduce: (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type); if ((yyvsp[(1) - (1)].interm.type).array) { - context->error((yyvsp[(1) - (1)].interm.type).line, "not supported", "first-class array", ""); + context->error((yyvsp[(1) - (1)].interm.type).line, "not supported", "first-class array"); context->recover(); (yyvsp[(1) - (1)].interm.type).setArray(false); } @@ -3646,19 +3656,19 @@ yyreduce: { if ((yyvsp[(2) - (2)].interm.type).array) { - context->error((yyvsp[(2) - (2)].interm.type).line, "not supported", "first-class array", ""); + context->error((yyvsp[(2) - (2)].interm.type).line, "not supported", "first-class array"); context->recover(); (yyvsp[(2) - (2)].interm.type).setArray(false); } if ((yyvsp[(1) - (2)].interm.type).qualifier == EvqAttribute && ((yyvsp[(2) - (2)].interm.type).type == EbtBool || (yyvsp[(2) - (2)].interm.type).type == EbtInt)) { - context->error((yyvsp[(2) - (2)].interm.type).line, "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier), ""); + context->error((yyvsp[(2) - (2)].interm.type).line, "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier)); context->recover(); } if (((yyvsp[(1) - (2)].interm.type).qualifier == EvqVaryingIn || (yyvsp[(1) - (2)].interm.type).qualifier == EvqVaryingOut) && ((yyvsp[(2) - (2)].interm.type).type == EbtBool || (yyvsp[(2) - (2)].interm.type).type == EbtInt)) { - context->error((yyvsp[(2) - (2)].interm.type).line, "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier), ""); + context->error((yyvsp[(2) - (2)].interm.type).line, "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier)); context->recover(); } (yyval.interm.type) = (yyvsp[(2) - (2)].interm.type); @@ -3947,7 +3957,7 @@ yyreduce: { if (!context->supportsExtension("GL_OES_EGL_image_external")) { - context->error((yyvsp[(1) - (1)].lex).line, "unsupported type", "samplerExternalOES", ""); + context->error((yyvsp[(1) - (1)].lex).line, "unsupported type", "samplerExternalOES"); context->recover(); } FRAG_VERT_ONLY("samplerExternalOES", (yyvsp[(1) - (1)].lex).line); @@ -3960,7 +3970,7 @@ yyreduce: { if (!context->supportsExtension("GL_ARB_texture_rectangle")) { - context->error((yyvsp[(1) - (1)].lex).line, "unsupported type", "sampler2DRect", ""); + context->error((yyvsp[(1) - (1)].lex).line, "unsupported type", "sampler2DRect"); context->recover(); } FRAG_VERT_ONLY("sampler2DRect", (yyvsp[(1) - (1)].lex).line); @@ -4421,7 +4431,7 @@ yyreduce: { if (context->loopNestingLevel <= 0) { - context->error((yyvsp[(1) - (2)].lex).line, "continue statement only allowed in loops", "", ""); + context->error((yyvsp[(1) - (2)].lex).line, "continue statement only allowed in loops", ""); context->recover(); } (yyval.interm.intermNode) = context->intermediate.addBranch(EOpContinue, (yyvsp[(1) - (2)].lex).line); @@ -4432,7 +4442,7 @@ yyreduce: { if (context->loopNestingLevel <= 0) { - context->error((yyvsp[(1) - (2)].lex).line, "break statement only allowed in loops", "", ""); + context->error((yyvsp[(1) - (2)].lex).line, "break statement only allowed in loops", ""); context->recover(); } (yyval.interm.intermNode) = context->intermediate.addBranch(EOpBreak, (yyvsp[(1) - (2)].lex).line); @@ -4444,7 +4454,7 @@ yyreduce: { (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(1) - (2)].lex).line); if (context->currentFunctionType->getBasicType() != EbtVoid) { - context->error((yyvsp[(1) - (2)].lex).line, "non-void function must return a value", "return", ""); + context->error((yyvsp[(1) - (2)].lex).line, "non-void function must return a value", "return"); context->recover(); } ;} @@ -4456,10 +4466,10 @@ yyreduce: (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(2) - (3)].interm.intermTypedNode), (yyvsp[(1) - (3)].lex).line); context->functionReturnsValue = true; if (context->currentFunctionType->getBasicType() == EbtVoid) { - context->error((yyvsp[(1) - (3)].lex).line, "void function cannot return a value", "return", ""); + context->error((yyvsp[(1) - (3)].lex).line, "void function cannot return a value", "return"); context->recover(); } else if (*(context->currentFunctionType) != (yyvsp[(2) - (3)].interm.intermTypedNode)->getType()) { - context->error((yyvsp[(1) - (3)].lex).line, "function return is not matching type:", "return", ""); + context->error((yyvsp[(1) - (3)].lex).line, "function return is not matching type:", "return"); context->recover(); } ;} @@ -4517,7 +4527,7 @@ yyreduce: // // Then this function already has a body. // - context->error((yyvsp[(1) - (1)].interm).line, "function already has a body", function->getName().c_str(), ""); + context->error((yyvsp[(1) - (1)].interm).line, "function already has a body", function->getName().c_str()); context->recover(); } prevDec->setDefined(); @@ -4527,7 +4537,7 @@ yyreduce: // if (function->getName() == "main") { if (function->getParamCount() > 0) { - context->error((yyvsp[(1) - (1)].interm).line, "function cannot take any parameter(s)", function->getName().c_str(), ""); + context->error((yyvsp[(1) - (1)].interm).line, "function cannot take any parameter(s)", function->getName().c_str()); context->recover(); } if (function->getReturnType().getBasicType() != EbtVoid) { @@ -4559,7 +4569,7 @@ yyreduce: // Insert the parameters with name in the symbol table. // if (! context->symbolTable.insert(*variable)) { - context->error((yyvsp[(1) - (1)].interm).line, "redefinition", variable->getName().c_str(), ""); + context->error((yyvsp[(1) - (1)].interm).line, "redefinition", variable->getName().c_str()); context->recover(); delete variable; } @@ -4600,9 +4610,8 @@ yyreduce: // store the pragma information for debug and optimize and other vendor specific // information. This information can be queried from the parse tree - (yyval.interm.intermNode)->getAsAggregate()->setOptimize(context->contextPragma.optimize); - (yyval.interm.intermNode)->getAsAggregate()->setDebug(context->contextPragma.debug); - (yyval.interm.intermNode)->getAsAggregate()->addToPragmaTable(context->contextPragma.pragmaTable); + (yyval.interm.intermNode)->getAsAggregate()->setOptimize(context->pragma().optimize); + (yyval.interm.intermNode)->getAsAggregate()->setDebug(context->pragma().debug); if ((yyvsp[(3) - (3)].interm.intermNode) && (yyvsp[(3) - (3)].interm.intermNode)->getAsAggregate()) (yyval.interm.intermNode)->getAsAggregate()->setEndLine((yyvsp[(3) - (3)].interm.intermNode)->getAsAggregate()->getEndLine()); diff --git a/Source/ThirdParty/ANGLE/src/compiler/intermediate.h b/Source/ThirdParty/ANGLE/src/compiler/intermediate.h index 5441557ca..af78fa00e 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/intermediate.h +++ b/Source/ThirdParty/ANGLE/src/compiler/intermediate.h @@ -433,15 +433,15 @@ protected: typedef TVector<TIntermNode*> TIntermSequence; typedef TVector<int> TQualifierList; -typedef TMap<TString, TString> TPragmaTable; + // // Nodes that operate on an arbitrary sized set of children. // class TIntermAggregate : public TIntermOperator { public: - TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0), endLine(0), useEmulatedFunction(false) { } - TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0), useEmulatedFunction(false) { } - ~TIntermAggregate() { delete pragmaTable; } + TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), endLine(0), useEmulatedFunction(false) { } + TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { } + ~TIntermAggregate() { } virtual TIntermAggregate* getAsAggregate() { return this; } virtual void traverse(TIntermTraverser*); @@ -452,14 +452,13 @@ public: const TString& getName() const { return name; } void setUserDefined() { userDefined = true; } - bool isUserDefined() { return userDefined; } + bool isUserDefined() const { return userDefined; } void setOptimize(bool o) { optimize = o; } bool getOptimize() { return optimize; } void setDebug(bool d) { debug = d; } bool getDebug() { return debug; } - void addToPragmaTable(const TPragmaTable& pTable); - const TPragmaTable& getPragmaTable() const { return *pragmaTable; } + void setEndLine(TSourceLoc line) { endLine = line; } TSourceLoc getEndLine() const { return endLine; } @@ -475,7 +474,6 @@ protected: bool optimize; bool debug; - TPragmaTable *pragmaTable; TSourceLoc endLine; // If set to true, replace the built-in function call with an emulated one @@ -533,6 +531,7 @@ public: postVisit(postVisit), rightToLeft(rightToLeft), depth(0) {} + virtual ~TIntermTraverser() {}; virtual void visitSymbol(TIntermSymbol*) {} virtual void visitConstantUnion(TIntermConstantUnion*) {} diff --git a/Source/ThirdParty/ANGLE/src/compiler/osinclude.h b/Source/ThirdParty/ANGLE/src/compiler/osinclude.h index 9f9393a71..1d95907b7 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/osinclude.h +++ b/Source/ThirdParty/ANGLE/src/compiler/osinclude.h @@ -17,7 +17,8 @@ #elif defined(__APPLE__) || defined(__linux__) || \ defined(__FreeBSD__) || defined(__OpenBSD__) || \ defined(__sun) || defined(ANDROID) || \ - defined(__GLIBC__) || defined(__GNU__) || defined(__QNX__) + defined(__GLIBC__) || defined(__GNU__) || \ + defined(__QNX__) #define ANGLE_OS_POSIX #else #error Unsupported platform. diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/atom.c b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/atom.c index a17c319d2..39158d2fa 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/atom.c +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/atom.c @@ -50,6 +50,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdio.h> #include <string.h> +#include "common/angleutils.h" #include "compiler/debug.h" #include "compiler/preprocessor/slglobals.h" @@ -307,7 +308,7 @@ struct AtomTable_Rec { int size; }; -static AtomTable latable = { { 0 } }; +static AtomTable latable = { { NULL, 0, 0 }, { NULL, 0, 0, {0} }, NULL, NULL, 0, 0 }; AtomTable *atable = &latable; static int AddAtomFixed(AtomTable *atable, const char *s, int atom); @@ -434,14 +435,14 @@ static int FindHashLoc(AtomTable *atable, const char *s) if (cpp->options.DumpAtomTable) { int ii; char str[200]; - sprintf(str, "*** Hash failed with more than %d collisions. Must increase hash table size. ***", + snprintf(str, sizeof(str), "*** Hash failed with more than %d collisions. Must increase hash table size. ***", HASH_TABLE_MAX_COLLISIONS); CPPShInfoLogMsg(str); - sprintf(str, "*** New string \"%s\", hash=%04x, delta=%04x", s, collision[0], hashdelta); + snprintf(str, sizeof(str), "*** New string \"%s\", hash=%04x, delta=%04x", s, collision[0], hashdelta); CPPShInfoLogMsg(str); for (ii = 0; ii <= HASH_TABLE_MAX_COLLISIONS; ii++) { - sprintf(str, "*** Collides on try %d at hash entry %04x with \"%s\"", + snprintf(str, sizeof(str), "*** Collides on try %d at hash entry %04x with \"%s\"", ii + 1, collision[ii], GetAtomString(atable, atable->htable.entry[collision[ii]].value)); CPPShInfoLogMsg(str); } @@ -685,14 +686,14 @@ void PrintAtomTable(AtomTable *atable) char str[200]; for (ii = 0; ii < atable->nextFree; ii++) { - sprintf(str, "%d: \"%s\"", ii, &atable->stable.strings[atable->amap[ii]]); + snprintf(str, sizeof(str), "%d: \"%s\"", ii, &atable->stable.strings[atable->amap[ii]]); CPPDebugLogMsg(str); } - sprintf(str, "Hash table: size=%d, entries=%d, collisions=", + snprintf(str, sizeof(str), "Hash table: size=%d, entries=%d, collisions=", atable->htable.size, atable->htable.entries); CPPDebugLogMsg(str); for (ii = 0; ii < HASH_TABLE_MAX_COLLISIONS; ii++) { - sprintf(str, " %d", atable->htable.counts[ii]); + snprintf(str, sizeof(str), " %d", atable->htable.counts[ii]); CPPDebugLogMsg(str); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.c b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.c index 13a5df18a..8a1076b9d 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.c +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.c @@ -51,6 +51,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <string.h> #include <ctype.h> +#include "common/angleutils.h" #include "compiler/preprocessor/slglobals.h" #if defined(_MSC_VER) @@ -678,7 +679,7 @@ static int CPPpragma(yystypepp * yylvalpp) case -1: // EOF CPPShInfoLogMsg("#pragma directive must end with a newline"); - return token; + goto freeMemoryAndReturnToken; default: SrcStrName[0] = token; SrcStrName[1] = '\0'; @@ -688,10 +689,9 @@ static int CPPpragma(yystypepp * yylvalpp) token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); } - cpp->currentInput->ungetch(cpp->currentInput, token, yylvalpp); HandlePragma((const char**)allTokens, tokenCount); - token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); +freeMemoryAndReturnToken: for (i = 0; i < tokenCount; ++i) { free (allTokens[i]); } @@ -784,7 +784,6 @@ int readCPPline(yystypepp * yylvalpp) { int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); const char *message; - int isVersion = 0; if (token == CPP_IDENTIFIER) { if (yylvalpp->sc_ident == defineAtom) { @@ -861,7 +860,6 @@ int readCPPline(yystypepp * yylvalpp) token = CPPerror(yylvalpp); } else if (yylvalpp->sc_ident == versionAtom) { token = CPPversion(yylvalpp); - isVersion = 1; } else if (yylvalpp->sc_ident == extensionAtom) { token = CPPextension(yylvalpp); } else { @@ -886,15 +884,15 @@ void FreeMacro(MacroSymbol *s) { } void PredefineIntMacro(const char *name, int value) { - SourceLoc location = {0}; + SourceLoc location = {0, 0}; Symbol *symbol = NULL; - MacroSymbol macro = {0}; - yystypepp val = {0}; + MacroSymbol macro = {0, NULL, NULL, 0, 0}; + yystypepp val = {0, 0.0, 0, {0}}; int atom = 0; macro.body = NewTokenStream(name, macros->pool); val.sc_int = value; - sprintf(val.symbol_name, "%d", value); + snprintf(val.symbol_name, MAX_SYMBOL_NAME_LEN+1, "%d", value); RecordToken(macro.body, CPP_INTCONSTANT, &val); atom = LookUpAddString(atable, name); symbol = AddSymbol(&location, macros, atom, MACRO_S); @@ -991,13 +989,13 @@ int MacroExpand(int atom, yystypepp * yylvalpp) const char *message; if (atom == __LINE__Atom) { yylvalpp->sc_int = GetLineNumber(); - sprintf(yylvalpp->symbol_name,"%d",yylvalpp->sc_int); + snprintf(yylvalpp->symbol_name, MAX_SYMBOL_NAME_LEN+1, "%d", yylvalpp->sc_int); UngetToken(CPP_INTCONSTANT, yylvalpp); return 1; } if (atom == __FILE__Atom) { yylvalpp->sc_int = GetStringNumber(); - sprintf(yylvalpp->symbol_name,"%d",yylvalpp->sc_int); + snprintf(yylvalpp->symbol_name, MAX_SYMBOL_NAME_LEN+1, "%d", yylvalpp->sc_int); UngetToken(CPP_INTCONSTANT, yylvalpp); return 1; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.h index db4c184ae..802e23ef0 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.h @@ -73,8 +73,8 @@ void CPPShInfoLogMsg(const char*); // Store cpp Err Msg into Sh.Info.Lo void CPPWarningToInfoLog(const char *msg); // Prints warning messages into info log void HandlePragma(const char**, int numTokens); // #pragma directive container. void ResetTString(void); // #error Message as TString. -void CPPErrorToInfoLog(char*); // Stick all cpp errors into Sh.Info.log . -void StoreStr(char*); // Store the TString in Parse Context. +void CPPErrorToInfoLog(const char*); // Stick all cpp errors into Sh.Info.log. +void StoreStr(const char*); // Store the TString in Parse Context. void SetLineNumber(int); // Set line number. void SetStringNumber(int); // Set string number. int GetLineNumber(void); // Get the current String Number. diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/memory.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/memory.h index b3ae2f963..5fcadb32f 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/memory.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/memory.h @@ -45,6 +45,8 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef __MEMORY_H #define __MEMORY_H +#include <stddef.h> + typedef struct MemoryPool_rec MemoryPool; extern MemoryPool *mem_CreatePool(size_t chunksize, unsigned int align); diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Context.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Context.cpp deleted file mode 100644 index 259cc43ea..000000000 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Context.cpp +++ /dev/null @@ -1,139 +0,0 @@ -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "Context.h" - -#include <algorithm> -#include <sstream> - -#include "compiler/debug.h" -#include "stl_utils.h" -#include "token_type.h" - -static bool isMacroNameReserved(const std::string* name) -{ - ASSERT(name); - - // Names prefixed with "GL_" are reserved. - if (name->substr(0, 3) == "GL_") - return true; - - // Names containing two consecutive underscores are reserved. - if (name->find("__") != std::string::npos) - return true; - - return false; -} - -namespace pp -{ - -Context::Context() - : mLexer(NULL), - mInput(NULL), - mOutput(NULL) -{ -} - -Context::~Context() -{ - destroyLexer(); -} - -bool Context::init() -{ - return initLexer(); - - // TODO(alokp): Define built-in macros here so that we do not need to - // define them everytime in process(). -} - -bool Context::process(int count, - const char* const string[], - const int length[], - TokenVector* output) -{ - ASSERT((count >=0) && (string != NULL) && (output != NULL)); - - // Setup. - mInput = new Input(count, string, length); - mOutput = output; - defineBuiltInMacro("GL_ES", 1); - - // Parse. - bool success = parse(); - - // Cleanup. - reset(); - return success; -} - -bool Context::defineMacro(pp::Token::Location location, - pp::Macro::Type type, - std::string* name, - pp::TokenVector* parameters, - pp::TokenVector* replacements) -{ - std::auto_ptr<Macro> macro(new Macro(type, name, parameters, replacements)); - if (isMacroNameReserved(name)) - { - // TODO(alokp): Report error. - return false; - } - if (isMacroDefined(name)) - { - // TODO(alokp): Report error. - return false; - } - - mMacros[*name] = macro.release(); - return true; -} - -bool Context::undefineMacro(const std::string* name) -{ - MacroSet::iterator iter = mMacros.find(*name); - if (iter == mMacros.end()) - { - // TODO(alokp): Report error. - return false; - } - mMacros.erase(iter); - return true; -} - -bool Context::isMacroDefined(const std::string* name) -{ - return mMacros.find(*name) != mMacros.end(); -} - -// Reset to initialized state. -void Context::reset() -{ - std::for_each(mMacros.begin(), mMacros.end(), DeleteSecond()); - mMacros.clear(); - - delete mInput; - mInput = NULL; - - mOutput = NULL; -} - -void Context::defineBuiltInMacro(const std::string& name, int value) -{ - std::ostringstream stream; - stream << value; - Token* token = new Token(0, INT_CONSTANT, new std::string(stream.str())); - TokenVector* replacements = new pp::TokenVector(1, token); - - mMacros[name] = new Macro(Macro::kTypeObj, - new std::string(name), - NULL, - replacements); -} - -} // namespace pp - diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Context.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Context.h deleted file mode 100644 index a81274719..000000000 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Context.h +++ /dev/null @@ -1,60 +0,0 @@ -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_PREPROCESSOR_CONTEXT_H_ -#define COMPILER_PREPROCESSOR_CONTEXT_H_ - -#include <map> - -#include "common/angleutils.h" -#include "Input.h" -#include "Macro.h" -#include "Token.h" - -namespace pp -{ - -class Context -{ - public: - Context(); - ~Context(); - - bool init(); - bool process(int count, const char* const string[], const int length[], - TokenVector* output); - - void* lexer() { return mLexer; } - int readInput(char* buf, int maxSize); - TokenVector* output() { return mOutput; } - - bool defineMacro(pp::Token::Location location, - pp::Macro::Type type, - std::string* name, - pp::TokenVector* parameters, - pp::TokenVector* replacements); - bool undefineMacro(const std::string* name); - bool isMacroDefined(const std::string* name); - - private: - DISALLOW_COPY_AND_ASSIGN(Context); - typedef std::map<std::string, Macro*> MacroSet; - - void reset(); - bool initLexer(); - void destroyLexer(); - void defineBuiltInMacro(const std::string& name, int value); - bool parse(); - - void* mLexer; // Lexer handle. - Input* mInput; - TokenVector* mOutput; - MacroSet mMacros; // Defined macros. -}; - -} // namespace pp -#endif // COMPILER_PREPROCESSOR_CONTEXT_H_ - diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Diagnostics.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Diagnostics.h new file mode 100644 index 000000000..1a75a9c32 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Diagnostics.h @@ -0,0 +1,82 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_PREPROCESSOR_DIAGNOSTICS_H_ +#define COMPILER_PREPROCESSOR_DIAGNOSTICS_H_ + +#include <string> + +namespace pp +{ + +struct SourceLocation; + +// Base class for reporting diagnostic messages. +// Derived classes are responsible for formatting and printing the messages. +class Diagnostics +{ + public: + enum Severity + { + ERROR, + WARNING + }; + enum ID + { + ERROR_BEGIN, + INTERNAL_ERROR, + OUT_OF_MEMORY, + INVALID_CHARACTER, + INVALID_NUMBER, + INVALID_EXPRESSION, + DIVISION_BY_ZERO, + EOF_IN_COMMENT, + EOF_IN_DIRECTIVE, + UNEXPECTED_TOKEN, + DIRECTIVE_INVALID_NAME, + MACRO_NAME_RESERVED, + MACRO_REDEFINED, + MACRO_PREDEFINED_REDEFINED, + MACRO_PREDEFINED_UNDEFINED, + MACRO_UNTERMINATED_INVOCATION, + MACRO_TOO_FEW_ARGS, + MACRO_TOO_MANY_ARGS, + CONDITIONAL_ENDIF_WITHOUT_IF, + CONDITIONAL_ELSE_WITHOUT_IF, + CONDITIONAL_ELSE_AFTER_ELSE, + CONDITIONAL_ELIF_WITHOUT_IF, + CONDITIONAL_ELIF_AFTER_ELSE, + CONDITIONAL_UNTERMINATED, + INVALID_EXTENSION_NAME, + INVALID_EXTENSION_BEHAVIOR, + INVALID_EXTENSION_DIRECTIVE, + INVALID_VERSION_NUMBER, + INVALID_VERSION_DIRECTIVE, + INVALID_LINE_NUMBER, + INVALID_FILE_NUMBER, + INVALID_LINE_DIRECTIVE, + ERROR_END, + + WARNING_BEGIN, + CONDITIONAL_UNEXPECTED_TOKEN, + UNRECOGNIZED_PRAGMA, + WARNING_END + }; + + virtual ~Diagnostics(); + + void report(ID id, const SourceLocation& loc, const std::string& text); + + protected: + Severity severity(ID id); + + virtual void print(ID id, + const SourceLocation& loc, + const std::string& text) = 0; +}; + +} // namespace pp +#endif // COMPILER_PREPROCESSOR_DIAGNOSTICS_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DiagnosticsBase.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DiagnosticsBase.cpp new file mode 100644 index 000000000..7b32540b7 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DiagnosticsBase.cpp @@ -0,0 +1,38 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "Diagnostics.h" + +#include <cassert> + +namespace pp +{ + +Diagnostics::~Diagnostics() +{ +} + +void Diagnostics::report(ID id, + const SourceLocation& loc, + const std::string& text) +{ + // TODO(alokp): Keep a count of errors and warnings. + print(id, loc, text); +} + +Diagnostics::Severity Diagnostics::severity(ID id) +{ + if ((id > ERROR_BEGIN) && (id < ERROR_END)) + return ERROR; + + if ((id > WARNING_BEGIN) && (id < WARNING_END)) + return WARNING; + + assert(false); + return ERROR; +} + +} // namespace pp diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DirectiveHandler.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DirectiveHandler.h new file mode 100644 index 000000000..2aaeec281 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DirectiveHandler.h @@ -0,0 +1,43 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_ +#define COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_ + +#include <string> + +namespace pp +{ + +struct SourceLocation; + +// Base class for handling directives. +// Preprocessor uses this class to notify the clients about certain +// preprocessor directives. Derived classes are responsible for +// handling them in an appropriate manner. +class DirectiveHandler +{ + public: + virtual ~DirectiveHandler(); + + virtual void handleError(const SourceLocation& loc, + const std::string& msg) = 0; + + // Handle pragma of form: #pragma name[(value)] + virtual void handlePragma(const SourceLocation& loc, + const std::string& name, + const std::string& value) = 0; + + virtual void handleExtension(const SourceLocation& loc, + const std::string& name, + const std::string& behavior) = 0; + + virtual void handleVersion(const SourceLocation& loc, + int version) = 0; +}; + +} // namespace pp +#endif // COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DirectiveHandlerBase.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DirectiveHandlerBase.cpp new file mode 100644 index 000000000..ca91e1c71 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DirectiveHandlerBase.cpp @@ -0,0 +1,16 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "DirectiveHandler.h" + +namespace pp +{ + +DirectiveHandler::~DirectiveHandler() +{ +} + +} // namespace pp diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DirectiveParser.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DirectiveParser.cpp new file mode 100644 index 000000000..585a90e59 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DirectiveParser.cpp @@ -0,0 +1,899 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "DirectiveParser.h" + +#include <cassert> +#include <cstdlib> +#include <sstream> + +#include "Diagnostics.h" +#include "DirectiveHandler.h" +#include "ExpressionParser.h" +#include "MacroExpander.h" +#include "Token.h" +#include "Tokenizer.h" + +namespace { +enum DirectiveType +{ + DIRECTIVE_NONE, + DIRECTIVE_DEFINE, + DIRECTIVE_UNDEF, + DIRECTIVE_IF, + DIRECTIVE_IFDEF, + DIRECTIVE_IFNDEF, + DIRECTIVE_ELSE, + DIRECTIVE_ELIF, + DIRECTIVE_ENDIF, + DIRECTIVE_ERROR, + DIRECTIVE_PRAGMA, + DIRECTIVE_EXTENSION, + DIRECTIVE_VERSION, + DIRECTIVE_LINE +}; +} // namespace + +static DirectiveType getDirective(const pp::Token* token) +{ + static const std::string kDirectiveDefine("define"); + static const std::string kDirectiveUndef("undef"); + static const std::string kDirectiveIf("if"); + static const std::string kDirectiveIfdef("ifdef"); + static const std::string kDirectiveIfndef("ifndef"); + static const std::string kDirectiveElse("else"); + static const std::string kDirectiveElif("elif"); + static const std::string kDirectiveEndif("endif"); + static const std::string kDirectiveError("error"); + static const std::string kDirectivePragma("pragma"); + static const std::string kDirectiveExtension("extension"); + static const std::string kDirectiveVersion("version"); + static const std::string kDirectiveLine("line"); + + if (token->type != pp::Token::IDENTIFIER) + return DIRECTIVE_NONE; + + if (token->value == kDirectiveDefine) + return DIRECTIVE_DEFINE; + else if (token->value == kDirectiveUndef) + return DIRECTIVE_UNDEF; + else if (token->value == kDirectiveIf) + return DIRECTIVE_IF; + else if (token->value == kDirectiveIfdef) + return DIRECTIVE_IFDEF; + else if (token->value == kDirectiveIfndef) + return DIRECTIVE_IFNDEF; + else if (token->value == kDirectiveElse) + return DIRECTIVE_ELSE; + else if (token->value == kDirectiveElif) + return DIRECTIVE_ELIF; + else if (token->value == kDirectiveEndif) + return DIRECTIVE_ENDIF; + else if (token->value == kDirectiveError) + return DIRECTIVE_ERROR; + else if (token->value == kDirectivePragma) + return DIRECTIVE_PRAGMA; + else if (token->value == kDirectiveExtension) + return DIRECTIVE_EXTENSION; + else if (token->value == kDirectiveVersion) + return DIRECTIVE_VERSION; + else if (token->value == kDirectiveLine) + return DIRECTIVE_LINE; + + return DIRECTIVE_NONE; +} + +static bool isConditionalDirective(DirectiveType directive) +{ + switch (directive) + { + case DIRECTIVE_IF: + case DIRECTIVE_IFDEF: + case DIRECTIVE_IFNDEF: + case DIRECTIVE_ELSE: + case DIRECTIVE_ELIF: + case DIRECTIVE_ENDIF: + return true; + default: + return false; + } +} + +// Returns true if the token represents End Of Directive. +static bool isEOD(const pp::Token* token) +{ + return (token->type == '\n') || (token->type == pp::Token::LAST); +} + +static void skipUntilEOD(pp::Lexer* lexer, pp::Token* token) +{ + while(!isEOD(token)) + { + lexer->lex(token); + } +} + +static bool isMacroNameReserved(const std::string& name) +{ + // Names prefixed with "GL_" are reserved. + if (name.substr(0, 3) == "GL_") + return true; + + // Names containing two consecutive underscores are reserved. + if (name.find("__") != std::string::npos) + return true; + + return false; +} + +static bool isMacroPredefined(const std::string& name, + const pp::MacroSet& macroSet) +{ + pp::MacroSet::const_iterator iter = macroSet.find(name); + return iter != macroSet.end() ? iter->second.predefined : false; +} + +namespace pp +{ + +class DefinedParser : public Lexer +{ + public: + DefinedParser(Lexer* lexer, + const MacroSet* macroSet, + Diagnostics* diagnostics) : + mLexer(lexer), + mMacroSet(macroSet), + mDiagnostics(diagnostics) + { + } + + protected: + virtual void lex(Token* token) + { + static const std::string kDefined("defined"); + + mLexer->lex(token); + if (token->type != Token::IDENTIFIER) + return; + if (token->value != kDefined) + return; + + bool paren = false; + mLexer->lex(token); + if (token->type == '(') + { + paren = true; + mLexer->lex(token); + } + + if (token->type != Token::IDENTIFIER) + { + mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN, + token->location, token->value); + skipUntilEOD(mLexer, token); + return; + } + MacroSet::const_iterator iter = mMacroSet->find(token->value); + std::string expression = iter != mMacroSet->end() ? "1" : "0"; + + if (paren) + { + mLexer->lex(token); + if (token->type != ')') + { + mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN, + token->location, token->value); + skipUntilEOD(mLexer, token); + return; + } + } + + // We have a valid defined operator. + // Convert the current token into a CONST_INT token. + token->type = Token::CONST_INT; + token->value = expression; + } + + private: + Lexer* mLexer; + const MacroSet* mMacroSet; + Diagnostics* mDiagnostics; +}; + +DirectiveParser::DirectiveParser(Tokenizer* tokenizer, + MacroSet* macroSet, + Diagnostics* diagnostics, + DirectiveHandler* directiveHandler) : + mTokenizer(tokenizer), + mMacroSet(macroSet), + mDiagnostics(diagnostics), + mDirectiveHandler(directiveHandler) +{ +} + +void DirectiveParser::lex(Token* token) +{ + do + { + mTokenizer->lex(token); + + if (token->type == Token::PP_HASH) + { + parseDirective(token); + } + + if (token->type == Token::LAST) + { + if (!mConditionalStack.empty()) + { + const ConditionalBlock& block = mConditionalStack.back(); + mDiagnostics->report(Diagnostics::CONDITIONAL_UNTERMINATED, + block.location, block.type); + } + break; + } + + } while (skipping() || (token->type == '\n')); +} + +void DirectiveParser::parseDirective(Token* token) +{ + assert(token->type == Token::PP_HASH); + + mTokenizer->lex(token); + DirectiveType directive = getDirective(token); + + // While in an excluded conditional block/group, + // we only parse conditional directives. + if (skipping() && !isConditionalDirective(directive)) + { + skipUntilEOD(mTokenizer, token); + return; + } + + switch(directive) + { + case DIRECTIVE_NONE: + mDiagnostics->report(Diagnostics::DIRECTIVE_INVALID_NAME, + token->location, token->value); + skipUntilEOD(mTokenizer, token); + break; + case DIRECTIVE_DEFINE: + parseDefine(token); + break; + case DIRECTIVE_UNDEF: + parseUndef(token); + break; + case DIRECTIVE_IF: + parseIf(token); + break; + case DIRECTIVE_IFDEF: + parseIfdef(token); + break; + case DIRECTIVE_IFNDEF: + parseIfndef(token); + break; + case DIRECTIVE_ELSE: + parseElse(token); + break; + case DIRECTIVE_ELIF: + parseElif(token); + break; + case DIRECTIVE_ENDIF: + parseEndif(token); + break; + case DIRECTIVE_ERROR: + parseError(token); + break; + case DIRECTIVE_PRAGMA: + parsePragma(token); + break; + case DIRECTIVE_EXTENSION: + parseExtension(token); + break; + case DIRECTIVE_VERSION: + parseVersion(token); + break; + case DIRECTIVE_LINE: + parseLine(token); + break; + default: + assert(false); + break; + } + + skipUntilEOD(mTokenizer, token); + if (token->type == Token::LAST) + { + mDiagnostics->report(Diagnostics::EOF_IN_DIRECTIVE, + token->location, token->value); + } +} + +void DirectiveParser::parseDefine(Token* token) +{ + assert(getDirective(token) == DIRECTIVE_DEFINE); + + mTokenizer->lex(token); + if (token->type != Token::IDENTIFIER) + { + mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN, + token->location, token->value); + return; + } + if (isMacroPredefined(token->value, *mMacroSet)) + { + mDiagnostics->report(Diagnostics::MACRO_PREDEFINED_REDEFINED, + token->location, token->value); + return; + } + if (isMacroNameReserved(token->value)) + { + mDiagnostics->report(Diagnostics::MACRO_NAME_RESERVED, + token->location, token->value); + return; + } + + Macro macro; + macro.type = Macro::kTypeObj; + macro.name = token->value; + + mTokenizer->lex(token); + if (token->type == '(' && !token->hasLeadingSpace()) + { + // Function-like macro. Collect arguments. + macro.type = Macro::kTypeFunc; + do { + mTokenizer->lex(token); + if (token->type != Token::IDENTIFIER) + break; + macro.parameters.push_back(token->value); + + mTokenizer->lex(token); // Get ','. + } while (token->type == ','); + + if (token->type != ')') + { + mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN, + token->location, + token->value); + return; + } + mTokenizer->lex(token); // Get ')'. + } + + while ((token->type != '\n') && (token->type != Token::LAST)) + { + // Reset the token location because it is unnecessary in replacement + // list. Resetting it also allows us to reuse Token::equals() to + // compare macros. + token->location = SourceLocation(); + macro.replacements.push_back(*token); + mTokenizer->lex(token); + } + if (!macro.replacements.empty()) + { + // Whitespace preceding the replacement list is not considered part of + // the replacement list for either form of macro. + macro.replacements.front().setHasLeadingSpace(false); + } + + // Check for macro redefinition. + MacroSet::const_iterator iter = mMacroSet->find(macro.name); + if (iter != mMacroSet->end() && !macro.equals(iter->second)) + { + mDiagnostics->report(Diagnostics::MACRO_REDEFINED, + token->location, + macro.name); + return; + } + mMacroSet->insert(std::make_pair(macro.name, macro)); +} + +void DirectiveParser::parseUndef(Token* token) +{ + assert(getDirective(token) == DIRECTIVE_UNDEF); + + mTokenizer->lex(token); + if (token->type != Token::IDENTIFIER) + { + mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN, + token->location, token->value); + return; + } + + MacroSet::iterator iter = mMacroSet->find(token->value); + if (iter != mMacroSet->end()) + { + if (iter->second.predefined) + { + mDiagnostics->report(Diagnostics::MACRO_PREDEFINED_UNDEFINED, + token->location, token->value); + } + else + { + mMacroSet->erase(iter); + } + } + + mTokenizer->lex(token); +} + +void DirectiveParser::parseIf(Token* token) +{ + assert(getDirective(token) == DIRECTIVE_IF); + parseConditionalIf(token); +} + +void DirectiveParser::parseIfdef(Token* token) +{ + assert(getDirective(token) == DIRECTIVE_IFDEF); + parseConditionalIf(token); +} + +void DirectiveParser::parseIfndef(Token* token) +{ + assert(getDirective(token) == DIRECTIVE_IFNDEF); + parseConditionalIf(token); +} + +void DirectiveParser::parseElse(Token* token) +{ + assert(getDirective(token) == DIRECTIVE_ELSE); + + if (mConditionalStack.empty()) + { + mDiagnostics->report(Diagnostics::CONDITIONAL_ELSE_WITHOUT_IF, + token->location, token->value); + skipUntilEOD(mTokenizer, token); + return; + } + + ConditionalBlock& block = mConditionalStack.back(); + if (block.skipBlock) + { + // No diagnostics. Just skip the whole line. + skipUntilEOD(mTokenizer, token); + return; + } + if (block.foundElseGroup) + { + mDiagnostics->report(Diagnostics::CONDITIONAL_ELSE_AFTER_ELSE, + token->location, token->value); + skipUntilEOD(mTokenizer, token); + return; + } + + block.foundElseGroup = true; + block.skipGroup = block.foundValidGroup; + block.foundValidGroup = true; + + // Warn if there are extra tokens after #else. + mTokenizer->lex(token); + if (!isEOD(token)) + { + mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN, + token->location, token->value); + skipUntilEOD(mTokenizer, token); + } +} + +void DirectiveParser::parseElif(Token* token) +{ + assert(getDirective(token) == DIRECTIVE_ELIF); + + if (mConditionalStack.empty()) + { + mDiagnostics->report(Diagnostics::CONDITIONAL_ELIF_WITHOUT_IF, + token->location, token->value); + skipUntilEOD(mTokenizer, token); + return; + } + + ConditionalBlock& block = mConditionalStack.back(); + if (block.skipBlock) + { + // No diagnostics. Just skip the whole line. + skipUntilEOD(mTokenizer, token); + return; + } + if (block.foundElseGroup) + { + mDiagnostics->report(Diagnostics::CONDITIONAL_ELIF_AFTER_ELSE, + token->location, token->value); + skipUntilEOD(mTokenizer, token); + return; + } + if (block.foundValidGroup) + { + // Do not parse the expression. + // Also be careful not to emit a diagnostic. + block.skipGroup = true; + skipUntilEOD(mTokenizer, token); + return; + } + + int expression = parseExpressionIf(token); + block.skipGroup = expression == 0; + block.foundValidGroup = expression != 0; +} + +void DirectiveParser::parseEndif(Token* token) +{ + assert(getDirective(token) == DIRECTIVE_ENDIF); + + if (mConditionalStack.empty()) + { + mDiagnostics->report(Diagnostics::CONDITIONAL_ENDIF_WITHOUT_IF, + token->location, token->value); + skipUntilEOD(mTokenizer, token); + return; + } + + mConditionalStack.pop_back(); + + // Warn if there are tokens after #endif. + mTokenizer->lex(token); + if (!isEOD(token)) + { + mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN, + token->location, token->value); + skipUntilEOD(mTokenizer, token); + } +} + +void DirectiveParser::parseError(Token* token) +{ + assert(getDirective(token) == DIRECTIVE_ERROR); + + std::stringstream stream; + mTokenizer->lex(token); + while ((token->type != '\n') && (token->type != Token::LAST)) + { + stream << *token; + mTokenizer->lex(token); + } + mDirectiveHandler->handleError(token->location, stream.str()); +} + +// Parses pragma of form: #pragma name[(value)]. +void DirectiveParser::parsePragma(Token* token) +{ + assert(getDirective(token) == DIRECTIVE_PRAGMA); + + enum State + { + PRAGMA_NAME, + LEFT_PAREN, + PRAGMA_VALUE, + RIGHT_PAREN + }; + + bool valid = true; + std::string name, value; + int state = PRAGMA_NAME; + + mTokenizer->lex(token); + while ((token->type != '\n') && (token->type != Token::LAST)) + { + switch(state++) + { + case PRAGMA_NAME: + name = token->value; + valid = valid && (token->type == Token::IDENTIFIER); + break; + case LEFT_PAREN: + valid = valid && (token->type == '('); + break; + case PRAGMA_VALUE: + value = token->value; + valid = valid && (token->type == Token::IDENTIFIER); + break; + case RIGHT_PAREN: + valid = valid && (token->type == ')'); + break; + default: + valid = false; + break; + } + mTokenizer->lex(token); + } + + valid = valid && ((state == PRAGMA_NAME) || // Empty pragma. + (state == LEFT_PAREN) || // Without value. + (state == RIGHT_PAREN + 1)); // With value. + if (!valid) + { + mDiagnostics->report(Diagnostics::UNRECOGNIZED_PRAGMA, + token->location, name); + } + else if (state > PRAGMA_NAME) // Do not notify for empty pragma. + { + mDirectiveHandler->handlePragma(token->location, name, value); + } +} + +void DirectiveParser::parseExtension(Token* token) +{ + assert(getDirective(token) == DIRECTIVE_EXTENSION); + + enum State + { + EXT_NAME, + COLON, + EXT_BEHAVIOR + }; + + bool valid = true; + std::string name, behavior; + int state = EXT_NAME; + + mTokenizer->lex(token); + while ((token->type != '\n') && (token->type != Token::LAST)) + { + switch (state++) + { + case EXT_NAME: + if (valid && (token->type != Token::IDENTIFIER)) + { + mDiagnostics->report(Diagnostics::INVALID_EXTENSION_NAME, + token->location, token->value); + valid = false; + } + if (valid) name = token->value; + break; + case COLON: + if (valid && (token->type != ':')) + { + mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN, + token->location, token->value); + valid = false; + } + break; + case EXT_BEHAVIOR: + if (valid && (token->type != Token::IDENTIFIER)) + { + mDiagnostics->report(Diagnostics::INVALID_EXTENSION_BEHAVIOR, + token->location, token->value); + valid = false; + } + if (valid) behavior = token->value; + break; + default: + if (valid) + { + mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN, + token->location, token->value); + valid = false; + } + break; + } + mTokenizer->lex(token); + } + if (valid && (state != EXT_BEHAVIOR + 1)) + { + mDiagnostics->report(Diagnostics::INVALID_EXTENSION_DIRECTIVE, + token->location, token->value); + valid = false; + } + if (valid) + mDirectiveHandler->handleExtension(token->location, name, behavior); +} + +void DirectiveParser::parseVersion(Token* token) +{ + assert(getDirective(token) == DIRECTIVE_VERSION); + + enum State + { + VERSION_NUMBER + }; + + bool valid = true; + int version = 0; + int state = VERSION_NUMBER; + + mTokenizer->lex(token); + while ((token->type != '\n') && (token->type != Token::LAST)) + { + switch (state++) + { + case VERSION_NUMBER: + if (valid && (token->type != Token::CONST_INT)) + { + mDiagnostics->report(Diagnostics::INVALID_VERSION_NUMBER, + token->location, token->value); + valid = false; + } + if (valid) version = atoi(token->value.c_str()); + break; + default: + if (valid) + { + mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN, + token->location, token->value); + valid = false; + } + break; + } + mTokenizer->lex(token); + } + if (valid && (state != VERSION_NUMBER + 1)) + { + mDiagnostics->report(Diagnostics::INVALID_VERSION_DIRECTIVE, + token->location, token->value); + valid = false; + } + if (valid) + mDirectiveHandler->handleVersion(token->location, version); +} + +void DirectiveParser::parseLine(Token* token) +{ + assert(getDirective(token) == DIRECTIVE_LINE); + + enum State + { + LINE_NUMBER, + FILE_NUMBER + }; + + bool valid = true; + int line = 0, file = 0; + int state = LINE_NUMBER; + + MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics); + macroExpander.lex(token); + while ((token->type != '\n') && (token->type != Token::LAST)) + { + switch (state++) + { + case LINE_NUMBER: + if (valid && (token->type != Token::CONST_INT)) + { + mDiagnostics->report(Diagnostics::INVALID_LINE_NUMBER, + token->location, token->value); + valid = false; + } + if (valid) line = atoi(token->value.c_str()); + break; + case FILE_NUMBER: + if (valid && (token->type != Token::CONST_INT)) + { + mDiagnostics->report(Diagnostics::INVALID_FILE_NUMBER, + token->location, token->value); + valid = false; + } + if (valid) file = atoi(token->value.c_str()); + break; + default: + if (valid) + { + mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN, + token->location, token->value); + valid = false; + } + break; + } + macroExpander.lex(token); + } + + if (valid && (state != FILE_NUMBER) && (state != FILE_NUMBER + 1)) + { + mDiagnostics->report(Diagnostics::INVALID_LINE_DIRECTIVE, + token->location, token->value); + valid = false; + } + if (valid) + { + mTokenizer->setLineNumber(line); + if (state == FILE_NUMBER + 1) mTokenizer->setFileNumber(file); + } +} + +bool DirectiveParser::skipping() const +{ + if (mConditionalStack.empty()) return false; + + const ConditionalBlock& block = mConditionalStack.back(); + return block.skipBlock || block.skipGroup; +} + +void DirectiveParser::parseConditionalIf(Token* token) +{ + ConditionalBlock block; + block.type = token->value; + block.location = token->location; + + if (skipping()) + { + // This conditional block is inside another conditional group + // which is skipped. As a consequence this whole block is skipped. + // Be careful not to parse the conditional expression that might + // emit a diagnostic. + skipUntilEOD(mTokenizer, token); + block.skipBlock = true; + } + else + { + DirectiveType directive = getDirective(token); + + int expression = 0; + switch (directive) + { + case DIRECTIVE_IF: + expression = parseExpressionIf(token); + break; + case DIRECTIVE_IFDEF: + expression = parseExpressionIfdef(token); + break; + case DIRECTIVE_IFNDEF: + expression = parseExpressionIfdef(token) == 0 ? 1 : 0; + break; + default: + assert(false); + break; + } + block.skipGroup = expression == 0; + block.foundValidGroup = expression != 0; + } + mConditionalStack.push_back(block); +} + +int DirectiveParser::parseExpressionIf(Token* token) +{ + assert((getDirective(token) == DIRECTIVE_IF) || + (getDirective(token) == DIRECTIVE_ELIF)); + + DefinedParser definedParser(mTokenizer, mMacroSet, mDiagnostics); + MacroExpander macroExpander(&definedParser, mMacroSet, mDiagnostics); + ExpressionParser expressionParser(¯oExpander, mDiagnostics); + + int expression = 0; + macroExpander.lex(token); + expressionParser.parse(token, &expression); + + // Warn if there are tokens after #if expression. + if (!isEOD(token)) + { + mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN, + token->location, token->value); + skipUntilEOD(mTokenizer, token); + } + + return expression; +} + +int DirectiveParser::parseExpressionIfdef(Token* token) +{ + assert((getDirective(token) == DIRECTIVE_IFDEF) || + (getDirective(token) == DIRECTIVE_IFNDEF)); + + mTokenizer->lex(token); + if (token->type != Token::IDENTIFIER) + { + mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN, + token->location, token->value); + skipUntilEOD(mTokenizer, token); + return 0; + } + + MacroSet::const_iterator iter = mMacroSet->find(token->value); + int expression = iter != mMacroSet->end() ? 1 : 0; + + // Warn if there are tokens after #ifdef expression. + mTokenizer->lex(token); + if (!isEOD(token)) + { + mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN, + token->location, token->value); + skipUntilEOD(mTokenizer, token); + } + return expression; +} + +} // namespace pp diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DirectiveParser.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DirectiveParser.h new file mode 100644 index 000000000..115a01e8a --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DirectiveParser.h @@ -0,0 +1,81 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_PREPROCESSOR_DIRECTIVE_PARSER_H_ +#define COMPILER_PREPROCESSOR_DIRECTIVE_PARSER_H_ + +#include "Lexer.h" +#include "Macro.h" +#include "pp_utils.h" +#include "SourceLocation.h" + +namespace pp +{ + +class Diagnostics; +class DirectiveHandler; +class Tokenizer; + +class DirectiveParser : public Lexer +{ + public: + DirectiveParser(Tokenizer* tokenizer, + MacroSet* macroSet, + Diagnostics* diagnostics, + DirectiveHandler* directiveHandler); + + virtual void lex(Token* token); + + private: + PP_DISALLOW_COPY_AND_ASSIGN(DirectiveParser); + + void parseDirective(Token* token); + void parseDefine(Token* token); + void parseUndef(Token* token); + void parseIf(Token* token); + void parseIfdef(Token* token); + void parseIfndef(Token* token); + void parseElse(Token* token); + void parseElif(Token* token); + void parseEndif(Token* token); + void parseError(Token* token); + void parsePragma(Token* token); + void parseExtension(Token* token); + void parseVersion(Token* token); + void parseLine(Token* token); + + bool skipping() const; + void parseConditionalIf(Token* token); + int parseExpressionIf(Token* token); + int parseExpressionIfdef(Token* token); + + struct ConditionalBlock + { + std::string type; + SourceLocation location; + bool skipBlock; + bool skipGroup; + bool foundValidGroup; + bool foundElseGroup; + + ConditionalBlock() : + skipBlock(false), + skipGroup(false), + foundValidGroup(false), + foundElseGroup(false) + { + } + }; + std::vector<ConditionalBlock> mConditionalStack; + Tokenizer* mTokenizer; + MacroSet* mMacroSet; + Diagnostics* mDiagnostics; + DirectiveHandler* mDirectiveHandler; +}; + +} // namespace pp +#endif // COMPILER_PREPROCESSOR_DIRECTIVE_PARSER_H_ + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_tab.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/ExpressionParser.cpp index a7b6aa006..b3a9ce920 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_tab.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/ExpressionParser.cpp @@ -56,7 +56,7 @@ #define YYPURE 1 /* Using locations. */ -#define YYLSP_NEEDED 1 +#define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse ppparse @@ -66,7 +66,7 @@ #define yychar ppchar #define yydebug ppdebug #define yynerrs ppnerrs -#define yylloc pplloc + /* Tokens. */ #ifndef YYTOKENTYPE @@ -74,47 +74,29 @@ /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { - HASH = 258, - HASH_UNDEF = 259, - HASH_IF = 260, - HASH_IFDEF = 261, - HASH_IFNDEF = 262, - HASH_ELSE = 263, - HASH_ELIF = 264, - HASH_ENDIF = 265, - DEFINED = 266, - HASH_ERROR = 267, - HASH_PRAGMA = 268, - HASH_EXTENSION = 269, - HASH_VERSION = 270, - HASH_LINE = 271, - HASH_DEFINE_OBJ = 272, - HASH_DEFINE_FUNC = 273, - INT_CONSTANT = 274, - FLOAT_CONSTANT = 275, - IDENTIFIER = 276 + TOK_CONST_INT = 258, + TOK_OP_OR = 259, + TOK_OP_AND = 260, + TOK_OP_NE = 261, + TOK_OP_EQ = 262, + TOK_OP_GE = 263, + TOK_OP_LE = 264, + TOK_OP_RIGHT = 265, + TOK_OP_LEFT = 266, + TOK_UNARY = 267 }; #endif /* Tokens. */ -#define HASH 258 -#define HASH_UNDEF 259 -#define HASH_IF 260 -#define HASH_IFDEF 261 -#define HASH_IFNDEF 262 -#define HASH_ELSE 263 -#define HASH_ELIF 264 -#define HASH_ENDIF 265 -#define DEFINED 266 -#define HASH_ERROR 267 -#define HASH_PRAGMA 268 -#define HASH_EXTENSION 269 -#define HASH_VERSION 270 -#define HASH_LINE 271 -#define HASH_DEFINE_OBJ 272 -#define HASH_DEFINE_FUNC 273 -#define INT_CONSTANT 274 -#define FLOAT_CONSTANT 275 -#define IDENTIFIER 276 +#define TOK_CONST_INT 258 +#define TOK_OP_OR 259 +#define TOK_OP_AND 260 +#define TOK_OP_NE 261 +#define TOK_OP_EQ 262 +#define TOK_OP_GE 263 +#define TOK_OP_LE 264 +#define TOK_OP_RIGHT 265 +#define TOK_OP_LEFT 266 +#define TOK_UNARY 267 @@ -123,17 +105,55 @@ // -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT! +// This file is auto-generated by generate_parser.sh. DO NOT EDIT! + +#if defined(__GNUC__) +// Triggered by the auto-generated pplval variable. +#pragma GCC diagnostic ignored "-Wuninitialized" +#elif defined(_MSC_VER) +#pragma warning(disable: 4065 4701) +#endif + +#include "ExpressionParser.h" -#include "Context.h" +#include <cassert> +#include <cstdlib> +#include <sstream> -#define YYLEX_PARAM context->lexer() -#define YYDEBUG 1 +#include "Diagnostics.h" +#include "Lexer.h" +#include "Token.h" + +#if defined(_MSC_VER) +typedef __int64 YYSTYPE; +#define strtoll _strtoi64 +#else +#include <stdint.h> +typedef intmax_t YYSTYPE; +#endif // _MSC_VER +#define YYENABLE_NLS 0 +#define YYLTYPE_IS_TRIVIAL 1 +#define YYSTYPE_IS_TRIVIAL 1 +#define YYSTYPE_IS_DECLARED 1 + +namespace { +struct Context +{ + pp::Diagnostics* diagnostics; + pp::Lexer* lexer; + pp::Token* token; + int* result; +}; +} // namespace + + +static int yylex(YYSTYPE* lvalp, Context* context); +static void yyerror(Context* context, const char* reason); /* Enabling traces. */ @@ -155,48 +175,17 @@ #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE - -{ - int ival; - std::string* sval; - pp::Token* tval; - pp::TokenVector* tlist; -} -/* Line 187 of yacc.c. */ - - YYSTYPE; +typedef int YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif /* Copy the second part of user declarations. */ -extern int yylex(YYSTYPE* lvalp, YYLTYPE* llocp, void* lexer); -static void yyerror(YYLTYPE* llocp, - pp::Context* context, - const char* reason); - -static void pushConditionalBlock(pp::Context* context, bool condition); -static void popConditionalBlock(pp::Context* context); - - /* Line 216 of yacc.c. */ @@ -330,7 +319,7 @@ YYID (i) # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) + && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 @@ -356,16 +345,14 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; - YYLTYPE yyls; -}; + }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) @@ -373,8 +360,8 @@ union yyalloc /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAXIMUM) + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ @@ -383,13 +370,13 @@ union yyalloc # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ while (YYID (0)) # endif # endif @@ -399,56 +386,56 @@ union yyalloc elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 2 +#define YYFINAL 14 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 247 +#define YYLAST 175 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 47 +#define YYNTOKENS 27 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 12 +#define YYNNTS 3 /* YYNRULES -- Number of rules. */ -#define YYNRULES 62 +#define YYNRULES 26 /* YYNRULES -- Number of states. */ -#define YYNSTATES 91 +#define YYNSTATES 52 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 276 +#define YYMAXUTOK 267 -#define YYTRANSLATE(YYX) \ +#define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 22, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 43, 2, 2, 2, 37, 40, 2, - 23, 24, 36, 33, 25, 34, 32, 35, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 44, 45, - 28, 42, 29, 46, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 23, 2, 2, 2, 21, 8, 2, + 25, 26, 19, 17, 2, 18, 2, 20, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 26, 2, 27, 38, 2, 2, 2, 2, 2, + 11, 2, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 30, 39, 31, 41, 2, 2, 2, + 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 6, 2, 24, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -462,8 +449,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21 + 5, 9, 10, 13, 14, 15, 16, 22 }; #if YYDEBUG @@ -471,46 +457,32 @@ static const yytype_uint8 yytranslate[] = YYRHS. */ static const yytype_uint8 yyprhs[] = { - 0, 0, 3, 4, 7, 9, 11, 13, 16, 19, - 23, 30, 34, 38, 42, 46, 50, 53, 56, 59, - 62, 65, 68, 71, 72, 74, 75, 77, 81, 83, - 86, 88, 91, 94, 99, 101, 103, 105, 107, 109, - 111, 113, 115, 117, 119, 121, 123, 125, 127, 129, - 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, - 151, 153, 155 + 0, 0, 3, 5, 7, 11, 15, 19, 23, 27, + 31, 35, 39, 43, 47, 51, 55, 59, 63, 67, + 71, 75, 79, 82, 85, 88, 91 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 48, 0, -1, -1, 48, 49, -1, 50, -1, 51, - -1, 22, -1, 55, 22, -1, 3, 22, -1, 17, - 52, 22, -1, 18, 23, 53, 24, 52, 22, -1, - 4, 21, 22, -1, 5, 54, 22, -1, 6, 21, - 22, -1, 7, 21, 22, -1, 9, 54, 22, -1, - 8, 22, -1, 10, 22, -1, 12, 22, -1, 13, - 22, -1, 14, 22, -1, 15, 22, -1, 16, 22, - -1, -1, 55, -1, -1, 21, -1, 53, 25, 21, - -1, 56, -1, 54, 56, -1, 57, -1, 55, 57, - -1, 11, 21, -1, 11, 23, 21, 24, -1, 57, - -1, 58, -1, 19, -1, 20, -1, 21, -1, 26, - -1, 27, -1, 28, -1, 29, -1, 23, -1, 24, - -1, 30, -1, 31, -1, 32, -1, 33, -1, 34, - -1, 35, -1, 36, -1, 37, -1, 38, -1, 39, - -1, 40, -1, 41, -1, 42, -1, 43, -1, 44, - -1, 45, -1, 25, -1, 46, -1 + 28, 0, -1, 29, -1, 3, -1, 29, 4, 29, + -1, 29, 5, 29, -1, 29, 6, 29, -1, 29, + 7, 29, -1, 29, 8, 29, -1, 29, 9, 29, + -1, 29, 10, 29, -1, 29, 13, 29, -1, 29, + 14, 29, -1, 29, 12, 29, -1, 29, 11, 29, + -1, 29, 15, 29, -1, 29, 16, 29, -1, 29, + 18, 29, -1, 29, 17, 29, -1, 29, 21, 29, + -1, 29, 20, 29, -1, 29, 19, 29, -1, 23, + 29, -1, 24, 29, -1, 18, 29, -1, 17, 29, + -1, 25, 29, 26, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 63, 63, 65, 69, 70, 74, 75, 84, 85, - 88, 91, 94, 97, 100, 103, 105, 107, 110, 111, - 112, 113, 114, 118, 119, 122, 123, 127, 133, 137, - 144, 148, 155, 157, 159, 163, 166, 169, 172, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201 + 0, 89, 89, 96, 97, 100, 103, 106, 109, 112, + 115, 118, 121, 124, 127, 130, 133, 136, 139, 142, + 155, 168, 171, 174, 177, 180, 183 }; #endif @@ -519,16 +491,11 @@ static const yytype_uint8 yyrline[] = First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$end", "error", "$undefined", "HASH", "HASH_UNDEF", "HASH_IF", - "HASH_IFDEF", "HASH_IFNDEF", "HASH_ELSE", "HASH_ELIF", "HASH_ENDIF", - "DEFINED", "HASH_ERROR", "HASH_PRAGMA", "HASH_EXTENSION", "HASH_VERSION", - "HASH_LINE", "HASH_DEFINE_OBJ", "HASH_DEFINE_FUNC", "INT_CONSTANT", - "FLOAT_CONSTANT", "IDENTIFIER", "'\\n'", "'('", "')'", "','", "'['", - "']'", "'<'", "'>'", "'{'", "'}'", "'.'", "'+'", "'-'", "'/'", "'*'", - "'%'", "'^'", "'|'", "'&'", "'~'", "'='", "'!'", "':'", "';'", "'?'", - "$accept", "input", "line", "text_line", "control_line", - "replacement_list", "parameter_list", "conditional_list", "token_list", - "conditional_token", "token", "operator", 0 + "$end", "error", "$undefined", "TOK_CONST_INT", "TOK_OP_OR", + "TOK_OP_AND", "'|'", "'^'", "'&'", "TOK_OP_NE", "TOK_OP_EQ", "'<'", + "'>'", "TOK_OP_GE", "TOK_OP_LE", "TOK_OP_RIGHT", "TOK_OP_LEFT", "'+'", + "'-'", "'*'", "'/'", "'%'", "TOK_UNARY", "'!'", "'~'", "'('", "')'", + "$accept", "input", "expression", 0 }; #endif @@ -537,36 +504,26 @@ static const char *const yytname[] = token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 10, 40, 41, 44, 91, 93, 60, 62, - 123, 125, 46, 43, 45, 47, 42, 37, 94, 124, - 38, 126, 61, 33, 58, 59, 63 + 0, 256, 257, 258, 259, 260, 124, 94, 38, 261, + 262, 60, 62, 263, 264, 265, 266, 43, 45, 42, + 47, 37, 267, 33, 126, 40, 41 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 47, 48, 48, 49, 49, 50, 50, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 52, 52, 53, 53, 53, 54, 54, - 55, 55, 56, 56, 56, 57, 57, 57, 57, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58 + 0, 27, 28, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 0, 2, 1, 1, 1, 2, 2, 3, - 6, 3, 3, 3, 3, 3, 2, 2, 2, 2, - 2, 2, 2, 0, 1, 0, 1, 3, 1, 2, - 1, 2, 2, 4, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1 + 0, 2, 1, 1, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 2, 2, 2, 2, 3 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -574,47 +531,37 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 23, 0, 36, 37, - 38, 6, 43, 44, 61, 39, 40, 41, 42, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 62, 3, 4, 5, 0, - 30, 35, 8, 0, 0, 0, 28, 34, 0, 0, - 16, 0, 17, 18, 19, 20, 21, 22, 0, 24, - 25, 7, 31, 11, 32, 0, 12, 29, 13, 14, - 15, 9, 26, 0, 0, 23, 0, 33, 0, 27, - 10 + 0, 3, 0, 0, 0, 0, 0, 0, 2, 25, + 24, 22, 23, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 26, 4, 5, 6, 7, 8, 9, + 10, 14, 13, 11, 12, 15, 16, 18, 17, 21, + 20, 19 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 1, 46, 47, 48, 68, 83, 55, 69, 56, - 57, 51 + -1, 7, 8 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -55 +#define YYPACT_NINF -11 static const yytype_int16 yypact[] = { - -55, 73, -55, -17, -18, 145, -10, -9, -16, 145, - -8, 22, 23, 24, 25, 27, 201, 28, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, 173, - -55, -55, -55, 30, -19, -3, -55, -55, 31, 32, - -55, 109, -55, -55, -55, -55, -55, -55, 33, 201, - 29, -55, -55, -55, -55, 35, -55, -55, -55, -55, - -55, -55, -55, -15, -11, 201, 36, -55, 37, -55, - -55 + 46, -11, 46, 46, 46, 46, 46, 12, 68, -11, + -11, -11, -11, 27, -11, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, -11, 85, 101, 116, 130, 143, 154, + 154, -10, -10, -10, -10, 37, 37, 31, 31, -11, + -11, -11 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -55, -55, -55, -55, -55, -27, -55, 51, 60, -54, - -1, -55 + -11, -11, -2 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -624,116 +571,98 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { - 50, 77, 74, 53, 75, 52, 60, 77, 54, 85, - 86, 58, 59, 87, 62, 50, 18, 19, 20, 76, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 63, 64, 65, 66, 72, 67, - 82, 70, 73, 78, 79, 81, 84, 89, 88, 90, - 61, 49, 0, 0, 0, 0, 0, 0, 72, 0, - 0, 0, 0, 2, 0, 0, 3, 4, 5, 6, - 7, 8, 9, 10, 50, 11, 12, 13, 14, 15, + 9, 10, 11, 12, 13, 26, 27, 28, 29, 30, + 31, 32, 14, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 1, + 30, 31, 32, 33, 28, 29, 30, 31, 32, 0, + 0, 0, 0, 2, 3, 0, 0, 0, 0, 4, + 5, 6, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 54, 0, 0, 0, 0, 0, 0, 0, 18, 19, - 20, 80, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 54, 0, 0, 0, - 0, 0, 0, 0, 18, 19, 20, 0, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 18, 19, 20, 71, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 18, 19, 20, 0, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45 + 26, 27, 28, 29, 30, 31, 32, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32 }; static const yytype_int8 yycheck[] = { - 1, 55, 21, 21, 23, 22, 22, 61, 11, 24, - 25, 21, 21, 24, 22, 16, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 22, 22, 22, 22, 49, 22, - 21, 23, 22, 22, 22, 22, 21, 21, 85, 22, - 9, 1, -1, -1, -1, -1, -1, -1, 69, -1, - -1, -1, -1, 0, -1, -1, 3, 4, 5, 6, - 7, 8, 9, 10, 85, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 11, -1, -1, -1, -1, -1, -1, -1, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 11, -1, -1, -1, - -1, -1, -1, -1, 19, 20, 21, -1, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 19, 20, 21, -1, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46 + 2, 3, 4, 5, 6, 15, 16, 17, 18, 19, + 20, 21, 0, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 3, + 19, 20, 21, 26, 17, 18, 19, 20, 21, -1, + -1, -1, -1, 17, 18, -1, -1, -1, -1, 23, + 24, 25, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 48, 0, 3, 4, 5, 6, 7, 8, 9, - 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 49, 50, 51, 55, - 57, 58, 22, 21, 11, 54, 56, 57, 21, 21, - 22, 54, 22, 22, 22, 22, 22, 22, 52, 55, - 23, 22, 57, 22, 21, 23, 22, 56, 22, 22, - 22, 22, 21, 53, 21, 24, 25, 24, 52, 21, - 22 + 0, 3, 17, 18, 23, 24, 25, 28, 29, 29, + 29, 29, 29, 29, 0, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 26, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29 }; -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab +#define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (&yylloc, context, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (context, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ while (YYID (0)) -#define YYTERROR 1 -#define YYERRCODE 256 +#define YYTERROR 1 +#define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. @@ -742,22 +671,22 @@ while (YYID (0)) #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ while (YYID (0)) #endif @@ -768,10 +697,10 @@ while (YYID (0)) #ifndef YY_LOCATION_PRINT # if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif @@ -781,9 +710,9 @@ while (YYID (0)) /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) +# define YYLEX yylex (&yylval, YYLEX_PARAM) #else -# define YYLEX yylex (&yylval, &yylloc) +# define YYLEX yylex (&yylval, context) #endif /* Enable debugging if requested. */ @@ -794,21 +723,21 @@ while (YYID (0)) # define YYFPRINTF fprintf # endif -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ } while (YYID (0)) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, Location, context); \ - YYFPRINTF (stderr, "\n"); \ - } \ +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, context); \ + YYFPRINTF (stderr, "\n"); \ + } \ } while (YYID (0)) @@ -820,20 +749,18 @@ do { \ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, pp::Context* context) +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Context *context) #else static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context) +yy_symbol_value_print (yyoutput, yytype, yyvaluep, context) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - pp::Context* context; + Context *context; #endif { if (!yyvaluep) return; - YYUSE (yylocationp); YYUSE (context); # ifdef YYPRINT if (yytype < YYNTOKENS) @@ -844,7 +771,7 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context) switch (yytype) { default: - break; + break; } } @@ -856,15 +783,14 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, pp::Context* context) +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Context *context) #else static void -yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, context) +yy_symbol_print (yyoutput, yytype, yyvaluep, context) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - pp::Context* context; + Context *context; #endif { if (yytype < YYNTOKENS) @@ -872,9 +798,7 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, context) else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context); + yy_symbol_value_print (yyoutput, yytype, yyvaluep, context); YYFPRINTF (yyoutput, ")"); } @@ -900,10 +824,10 @@ yy_stack_print (bottom, top) YYFPRINTF (stderr, "\n"); } -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) @@ -914,36 +838,35 @@ do { \ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, pp::Context* context) +yy_reduce_print (YYSTYPE *yyvsp, int yyrule, Context *context) #else static void -yy_reduce_print (yyvsp, yylsp, yyrule, context) +yy_reduce_print (yyvsp, yyrule, context) YYSTYPE *yyvsp; - YYLTYPE *yylsp; int yyrule; - pp::Context* context; + Context *context; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); + yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , &(yylsp[(yyi + 1) - (yynrhs)]) , context); + &(yyvsp[(yyi + 1) - (yynrhs)]) + , context); fprintf (stderr, "\n"); } } -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, yylsp, Rule, context); \ +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule, context); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that @@ -958,7 +881,7 @@ int yydebug; /* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH +#ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif @@ -1045,27 +968,27 @@ yytnamerr (char *yyres, const char *yystr) char const *yyp = yystr; for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } do_not_strip_quotes: ; } @@ -1103,7 +1026,7 @@ yysyntax_error (char *yyresult, int yystate, int yychar) # if 0 /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ + constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); @@ -1116,13 +1039,13 @@ yysyntax_error (char *yyresult, int yystate, int yychar) static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ + YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ @@ -1134,22 +1057,22 @@ yysyntax_error (char *yyresult, int yystate, int yychar) yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); @@ -1157,29 +1080,29 @@ yysyntax_error (char *yyresult, int yystate, int yychar) yysize = yysize1; if (yysize_overflow) - return YYSIZE_MAXIMUM; + return YYSIZE_MAXIMUM; if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } return yysize; } } @@ -1194,19 +1117,17 @@ yysyntax_error (char *yyresult, int yystate, int yychar) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, pp::Context* context) +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, Context *context) #else static void -yydestruct (yymsg, yytype, yyvaluep, yylocationp, context) +yydestruct (yymsg, yytype, yyvaluep, context) const char *yymsg; int yytype; YYSTYPE *yyvaluep; - YYLTYPE *yylocationp; - pp::Context* context; + Context *context; #endif { YYUSE (yyvaluep); - YYUSE (yylocationp); YYUSE (context); if (!yymsg) @@ -1217,7 +1138,7 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp, context) { default: - break; + break; } } @@ -1232,7 +1153,7 @@ int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus -int yyparse (pp::Context* context); +int yyparse (Context *context); #else int yyparse (); #endif @@ -1261,11 +1182,11 @@ yyparse (YYPARSE_PARAM) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int -yyparse (pp::Context* context) +yyparse (Context *context) #else int yyparse (context) - pp::Context* context; + Context *context; #endif #endif { @@ -1277,8 +1198,6 @@ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; -/* Location data for the look-ahead symbol. */ -YYLTYPE yylloc; int yystate; int yyn; @@ -1312,21 +1231,16 @@ YYLTYPE yylloc; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[2]; -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; - YYLTYPE yyloc; + /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ @@ -1337,7 +1251,7 @@ YYLTYPE yylloc; yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack @@ -1346,12 +1260,6 @@ YYLTYPE yylloc; yyssp = yyss; yyvsp = yyvs; - yylsp = yyls; -#if YYLTYPE_IS_TRIVIAL - /* Initialize the default location before parsing starts. */ - yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = 0; -#endif goto yysetstate; @@ -1373,25 +1281,25 @@ YYLTYPE yylloc; #ifdef yyoverflow { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - YYLTYPE *yyls1 = yyls; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - yyls = yyls1; - yyss = yyss1; - yyvs = yyvs1; + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE @@ -1399,36 +1307,36 @@ YYLTYPE yylloc; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; + goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; + yystacksize = YYMAXDEPTH; { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - YYSTACK_RELOCATE (yyls); + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + # undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; - yylsp = yyls + yysize - 1; + YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) - YYABORT; + YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); @@ -1477,7 +1385,7 @@ yybackup: if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; + goto yyerrlab; yyn = -yyn; goto yyreduce; } @@ -1499,7 +1407,7 @@ yybackup: yystate = yyn; *++yyvsp = yylval; - *++yylsp = yylloc; + goto yynewstate; @@ -1530,298 +1438,197 @@ yyreduce: GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; - /* Default location. */ - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); + YY_REDUCE_PRINT (yyn); switch (yyn) { - case 7: + case 2: { - // TODO(alokp): Expand macros. - pp::TokenVector* out = context->output(); - out->insert(out->end(), (yyvsp[(1) - (2)].tlist)->begin(), (yyvsp[(1) - (2)].tlist)->end()); - delete (yyvsp[(1) - (2)].tlist); + *(context->result) = static_cast<int>((yyvsp[(1) - (1)])); + YYACCEPT; ;} break; - case 9: + case 4: { - context->defineMacro((yylsp[(1) - (3)]).first_line, pp::Macro::kTypeObj, (yyvsp[(1) - (3)].sval), NULL, (yyvsp[(2) - (3)].tlist)); + (yyval) = (yyvsp[(1) - (3)]) || (yyvsp[(3) - (3)]); ;} break; - case 10: + case 5: { - context->defineMacro((yylsp[(1) - (6)]).first_line, pp::Macro::kTypeFunc, (yyvsp[(1) - (6)].sval), (yyvsp[(3) - (6)].tlist), (yyvsp[(5) - (6)].tlist)); + (yyval) = (yyvsp[(1) - (3)]) && (yyvsp[(3) - (3)]); ;} break; - case 11: + case 6: { - context->undefineMacro((yyvsp[(2) - (3)].sval)); + (yyval) = (yyvsp[(1) - (3)]) | (yyvsp[(3) - (3)]); ;} break; - case 12: + case 7: { - pushConditionalBlock(context, (yyvsp[(2) - (3)].tlist) ? true : false); + (yyval) = (yyvsp[(1) - (3)]) ^ (yyvsp[(3) - (3)]); ;} break; - case 13: + case 8: { - pushConditionalBlock(context, context->isMacroDefined((yyvsp[(2) - (3)].sval))); + (yyval) = (yyvsp[(1) - (3)]) & (yyvsp[(3) - (3)]); ;} break; - case 14: + case 9: { - pushConditionalBlock(context, !context->isMacroDefined((yyvsp[(2) - (3)].sval))); + (yyval) = (yyvsp[(1) - (3)]) != (yyvsp[(3) - (3)]); ;} break; - case 15: + case 10: { + (yyval) = (yyvsp[(1) - (3)]) == (yyvsp[(3) - (3)]); ;} break; - case 16: + case 11: { + (yyval) = (yyvsp[(1) - (3)]) >= (yyvsp[(3) - (3)]); ;} break; - case 17: + case 12: { - popConditionalBlock(context); + (yyval) = (yyvsp[(1) - (3)]) <= (yyvsp[(3) - (3)]); ;} break; - case 23: - - { (yyval.tlist) = NULL; ;} - break; - - case 25: - - { (yyval.tlist) = NULL; ;} - break; - - case 26: + case 13: { - (yyval.tlist) = new pp::TokenVector; - (yyval.tlist)->push_back(new pp::Token((yylsp[(1) - (1)]).first_line, IDENTIFIER, (yyvsp[(1) - (1)].sval))); + (yyval) = (yyvsp[(1) - (3)]) > (yyvsp[(3) - (3)]); ;} break; - case 27: + case 14: { - (yyval.tlist) = (yyvsp[(1) - (3)].tlist); - (yyval.tlist)->push_back(new pp::Token((yylsp[(3) - (3)]).first_line, IDENTIFIER, (yyvsp[(3) - (3)].sval))); + (yyval) = (yyvsp[(1) - (3)]) < (yyvsp[(3) - (3)]); ;} break; - case 28: + case 15: { - (yyval.tlist) = new pp::TokenVector; - (yyval.tlist)->push_back((yyvsp[(1) - (1)].tval)); + (yyval) = (yyvsp[(1) - (3)]) >> (yyvsp[(3) - (3)]); ;} break; - case 29: + case 16: { - (yyval.tlist) = (yyvsp[(1) - (2)].tlist); - (yyval.tlist)->push_back((yyvsp[(2) - (2)].tval)); + (yyval) = (yyvsp[(1) - (3)]) << (yyvsp[(3) - (3)]); ;} break; - case 30: + case 17: { - (yyval.tlist) = new pp::TokenVector; - (yyval.tlist)->push_back((yyvsp[(1) - (1)].tval)); + (yyval) = (yyvsp[(1) - (3)]) - (yyvsp[(3) - (3)]); ;} break; - case 31: + case 18: { - (yyval.tlist) = (yyvsp[(1) - (2)].tlist); - (yyval.tlist)->push_back((yyvsp[(2) - (2)].tval)); + (yyval) = (yyvsp[(1) - (3)]) + (yyvsp[(3) - (3)]); ;} break; - case 32: + case 19: { + if ((yyvsp[(3) - (3)]) == 0) { + std::stringstream stream; + stream << (yyvsp[(1) - (3)]) << " % " << (yyvsp[(3) - (3)]); + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO, + context->token->location, + text.c_str()); + YYABORT; + } else { + (yyval) = (yyvsp[(1) - (3)]) % (yyvsp[(3) - (3)]); + } ;} break; - case 33: + case 20: { + if ((yyvsp[(3) - (3)]) == 0) { + std::stringstream stream; + stream << (yyvsp[(1) - (3)]) << " / " << (yyvsp[(3) - (3)]); + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO, + context->token->location, + text.c_str()); + YYABORT; + } else { + (yyval) = (yyvsp[(1) - (3)]) / (yyvsp[(3) - (3)]); + } ;} break; - case 35: + case 21: { - (yyval.tval) = new pp::Token((yylsp[(1) - (1)]).first_line, (yyvsp[(1) - (1)].ival), NULL); + (yyval) = (yyvsp[(1) - (3)]) * (yyvsp[(3) - (3)]); ;} break; - case 36: + case 22: { - (yyval.tval) = new pp::Token((yylsp[(1) - (1)]).first_line, INT_CONSTANT, (yyvsp[(1) - (1)].sval)); + (yyval) = ! (yyvsp[(2) - (2)]); ;} break; - case 37: + case 23: { - (yyval.tval) = new pp::Token((yylsp[(1) - (1)]).first_line, FLOAT_CONSTANT, (yyvsp[(1) - (1)].sval)); + (yyval) = ~ (yyvsp[(2) - (2)]); ;} break; - case 38: + case 24: { - (yyval.tval) = new pp::Token((yylsp[(1) - (1)]).first_line, IDENTIFIER, (yyvsp[(1) - (1)].sval)); + (yyval) = - (yyvsp[(2) - (2)]); ;} break; - case 39: - - { (yyval.ival) = '['; ;} - break; - - case 40: - - { (yyval.ival) = ']'; ;} - break; - - case 41: - - { (yyval.ival) = '<'; ;} - break; - - case 42: - - { (yyval.ival) = '>'; ;} - break; - - case 43: - - { (yyval.ival) = '('; ;} - break; - - case 44: - - { (yyval.ival) = ')'; ;} - break; - - case 45: - - { (yyval.ival) = '{'; ;} - break; - - case 46: - - { (yyval.ival) = '}'; ;} - break; - - case 47: - - { (yyval.ival) = '.'; ;} - break; - - case 48: - - { (yyval.ival) = '+'; ;} - break; - - case 49: - - { (yyval.ival) = '-'; ;} - break; - - case 50: - - { (yyval.ival) = '/'; ;} - break; - - case 51: - - { (yyval.ival) = '*'; ;} - break; - - case 52: - - { (yyval.ival) = '%'; ;} - break; - - case 53: - - { (yyval.ival) = '^'; ;} - break; - - case 54: - - { (yyval.ival) = '|'; ;} - break; - - case 55: - - { (yyval.ival) = '&'; ;} - break; - - case 56: - - { (yyval.ival) = '~'; ;} - break; - - case 57: - - { (yyval.ival) = '='; ;} - break; - - case 58: - - { (yyval.ival) = '!'; ;} - break; - - case 59: - - { (yyval.ival) = ':'; ;} - break; - - case 60: - - { (yyval.ival) = ';'; ;} - break; - - case 61: + case 25: - { (yyval.ival) = ','; ;} + { + (yyval) = + (yyvsp[(2) - (2)]); + ;} break; - case 62: + case 26: - { (yyval.ival) = '?'; ;} + { + (yyval) = (yyvsp[(2) - (3)]); + ;} break; @@ -1836,7 +1643,7 @@ yyreduce: YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; - *++yylsp = yyloc; + /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule @@ -1862,61 +1669,61 @@ yyerrlab: { ++yynerrs; #if ! YYERROR_VERBOSE - yyerror (&yylloc, context, YY_("syntax error")); + yyerror (context, YY_("syntax error")); #else { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (&yylloc, context, yymsg); - } - else - { - yyerror (&yylloc, context, YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (context, yymsg); + } + else + { + yyerror (context, YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } } #endif } - yyerror_range[0] = yylloc; + if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an - error, discard it. */ + error, discard it. */ if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } else - { - yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc, context); - yychar = YYEMPTY; - } + { + yydestruct ("Error: discarding", + yytoken, &yylval, context); + yychar = YYEMPTY; + } } /* Else will try to reuse look-ahead token after shifting the error @@ -1935,7 +1742,6 @@ yyerrorlab: if (/*CONSTCOND*/ 0) goto yyerrorlab; - yyerror_range[0] = yylsp[1-yylen]; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); @@ -1949,29 +1755,29 @@ yyerrorlab: | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ + yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) - YYABORT; + YYABORT; + - yyerror_range[0] = *yylsp; yydestruct ("Error: popping", - yystos[yystate], yyvsp, yylsp, context); + yystos[yystate], yyvsp, context); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); @@ -1982,11 +1788,6 @@ yyerrlab1: *++yyvsp = yylval; - yyerror_range[1] = yylloc; - /* Using YYLLOC is tempting, but would change the location of - the look-ahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); - *++yylsp = yyloc; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); @@ -2014,7 +1815,7 @@ yyabortlab: | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: - yyerror (&yylloc, context, YY_("memory exhausted")); + yyerror (context, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif @@ -2022,7 +1823,7 @@ yyexhaustedlab: yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc, context); + yytoken, &yylval, context); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); @@ -2030,7 +1831,7 @@ yyreturn: while (yyssp != yyss) { yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, yylsp, context); + yystos[*yyssp], yyvsp, context); YYPOPSTACK (1); } #ifndef yyoverflow @@ -2049,24 +1850,91 @@ yyreturn: -void yyerror(YYLTYPE* llocp, pp::Context* context, const char* reason) +int yylex(YYSTYPE* lvalp, Context* context) { + int type = 0; + + pp::Token* token = context->token; + switch (token->type) + { + case pp::Token::CONST_INT: + *lvalp = strtoll(token->value.c_str(), NULL, 0); + type = TOK_CONST_INT; + break; + + case pp::Token::OP_OR: type = TOK_OP_OR; break; + case pp::Token::OP_AND: type = TOK_OP_AND; break; + case pp::Token::OP_NE: type = TOK_OP_NE; break; + case pp::Token::OP_EQ: type = TOK_OP_EQ; break; + case pp::Token::OP_GE: type = TOK_OP_GE; break; + case pp::Token::OP_LE: type = TOK_OP_LE; break; + case pp::Token::OP_RIGHT: type = TOK_OP_RIGHT; break; + case pp::Token::OP_LEFT: type = TOK_OP_LEFT; break; + case '|': type = '|'; break; + case '^': type = '^'; break; + case '&': type = '&'; break; + case '>': type = '>'; break; + case '<': type = '<'; break; + case '-': type = '-'; break; + case '+': type = '+'; break; + case '%': type = '%'; break; + case '/': type = '/'; break; + case '*': type = '*'; break; + case '!': type = '!'; break; + case '~': type = '~'; break; + case '(': type = '('; break; + case ')': type = ')'; break; + + default: break; + } + + // Advance to the next token if the current one is valid. + if (type != 0) context->lexer->lex(token); + + return type; } -void pushConditionalBlock(pp::Context* context, bool condition) +void yyerror(Context* context, const char* reason) { + context->diagnostics->report(pp::Diagnostics::INVALID_EXPRESSION, + context->token->location, + reason); } -void popConditionalBlock(pp::Context* context) +namespace pp { + +ExpressionParser::ExpressionParser(Lexer* lexer, Diagnostics* diagnostics) : + mLexer(lexer), + mDiagnostics(diagnostics) { } -namespace pp { -bool Context::parse() +bool ExpressionParser::parse(Token* token, int* result) { - yydebug = 1; - return yyparse(this) == 0 ? true : false; + Context context; + context.diagnostics = mDiagnostics; + context.lexer = mLexer; + context.token = token; + context.result = result; + int ret = yyparse(&context); + switch (ret) + { + case 0: + case 1: + break; + + case 2: + mDiagnostics->report(Diagnostics::OUT_OF_MEMORY, token->location, ""); + break; + + default: + assert(false); + mDiagnostics->report(Diagnostics::INTERNAL_ERROR, token->location, ""); + break; + } + + return ret == 0; } -} // namespace pp +} // namespace pp diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/ExpressionParser.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/ExpressionParser.h new file mode 100644 index 000000000..092d05941 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/ExpressionParser.h @@ -0,0 +1,34 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_PREPROCESSOR_EXPRESSION_PARSER_H_ +#define COMPILER_PREPROCESSOR_EXPRESSION_PARSER_H_ + +#include "pp_utils.h" + +namespace pp +{ + +class Diagnostics; +class Lexer; +struct Token; + +class ExpressionParser +{ + public: + ExpressionParser(Lexer* lexer, Diagnostics* diagnostics); + + bool parse(Token* token, int* result); + + private: + PP_DISALLOW_COPY_AND_ASSIGN(ExpressionParser); + + Lexer* mLexer; + Diagnostics* mDiagnostics; +}; + +} // namespace pp +#endif // COMPILER_PREPROCESSOR_EXPRESSION_PARSER_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/ExpressionParser.y b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/ExpressionParser.y new file mode 100644 index 000000000..b03f9eb56 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/ExpressionParser.y @@ -0,0 +1,276 @@ +/* +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +This file contains the Yacc grammar for GLSL ES preprocessor expression. + +IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh, +WHICH GENERATES THE GLSL ES preprocessor expression parser. +*/ + +%{ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// This file is auto-generated by generate_parser.sh. DO NOT EDIT! + +#if defined(__GNUC__) +// Triggered by the auto-generated pplval variable. +#pragma GCC diagnostic ignored "-Wuninitialized" +#elif defined(_MSC_VER) +#pragma warning(disable: 4065 4701) +#endif + +#include "ExpressionParser.h" + +#include <cassert> +#include <cstdlib> +#include <sstream> + +#include "Diagnostics.h" +#include "Lexer.h" +#include "Token.h" + +#if defined(_MSC_VER) +typedef __int64 YYSTYPE; +#define strtoll _strtoi64 +#else +#include <stdint.h> +typedef intmax_t YYSTYPE; +#endif // _MSC_VER +#define YYENABLE_NLS 0 +#define YYLTYPE_IS_TRIVIAL 1 +#define YYSTYPE_IS_TRIVIAL 1 +#define YYSTYPE_IS_DECLARED 1 + +namespace { +struct Context +{ + pp::Diagnostics* diagnostics; + pp::Lexer* lexer; + pp::Token* token; + int* result; +}; +} // namespace +%} + +%pure-parser +%name-prefix="pp" +%parse-param {Context *context} +%lex-param {Context *context} + +%{ +static int yylex(YYSTYPE* lvalp, Context* context); +static void yyerror(Context* context, const char* reason); +%} + +%token TOK_CONST_INT +%left TOK_OP_OR +%left TOK_OP_AND +%left '|' +%left '^' +%left '&' +%left TOK_OP_EQ TOK_OP_NE +%left '<' '>' TOK_OP_LE TOK_OP_GE +%left TOK_OP_LEFT TOK_OP_RIGHT +%left '+' '-' +%left '*' '/' '%' +%right TOK_UNARY + +%% + +input + : expression { + *(context->result) = static_cast<int>($1); + YYACCEPT; + } +; + +expression + : TOK_CONST_INT + | expression TOK_OP_OR expression { + $$ = $1 || $3; + } + | expression TOK_OP_AND expression { + $$ = $1 && $3; + } + | expression '|' expression { + $$ = $1 | $3; + } + | expression '^' expression { + $$ = $1 ^ $3; + } + | expression '&' expression { + $$ = $1 & $3; + } + | expression TOK_OP_NE expression { + $$ = $1 != $3; + } + | expression TOK_OP_EQ expression { + $$ = $1 == $3; + } + | expression TOK_OP_GE expression { + $$ = $1 >= $3; + } + | expression TOK_OP_LE expression { + $$ = $1 <= $3; + } + | expression '>' expression { + $$ = $1 > $3; + } + | expression '<' expression { + $$ = $1 < $3; + } + | expression TOK_OP_RIGHT expression { + $$ = $1 >> $3; + } + | expression TOK_OP_LEFT expression { + $$ = $1 << $3; + } + | expression '-' expression { + $$ = $1 - $3; + } + | expression '+' expression { + $$ = $1 + $3; + } + | expression '%' expression { + if ($3 == 0) { + std::stringstream stream; + stream << $1 << " % " << $3; + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO, + context->token->location, + text.c_str()); + YYABORT; + } else { + $$ = $1 % $3; + } + } + | expression '/' expression { + if ($3 == 0) { + std::stringstream stream; + stream << $1 << " / " << $3; + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO, + context->token->location, + text.c_str()); + YYABORT; + } else { + $$ = $1 / $3; + } + } + | expression '*' expression { + $$ = $1 * $3; + } + | '!' expression %prec TOK_UNARY { + $$ = ! $2; + } + | '~' expression %prec TOK_UNARY { + $$ = ~ $2; + } + | '-' expression %prec TOK_UNARY { + $$ = - $2; + } + | '+' expression %prec TOK_UNARY { + $$ = + $2; + } + | '(' expression ')' { + $$ = $2; + } +; + +%% + +int yylex(YYSTYPE* lvalp, Context* context) +{ + int type = 0; + + pp::Token* token = context->token; + switch (token->type) + { + case pp::Token::CONST_INT: + *lvalp = strtoll(token->value.c_str(), NULL, 0); + type = TOK_CONST_INT; + break; + + case pp::Token::OP_OR: type = TOK_OP_OR; break; + case pp::Token::OP_AND: type = TOK_OP_AND; break; + case pp::Token::OP_NE: type = TOK_OP_NE; break; + case pp::Token::OP_EQ: type = TOK_OP_EQ; break; + case pp::Token::OP_GE: type = TOK_OP_GE; break; + case pp::Token::OP_LE: type = TOK_OP_LE; break; + case pp::Token::OP_RIGHT: type = TOK_OP_RIGHT; break; + case pp::Token::OP_LEFT: type = TOK_OP_LEFT; break; + case '|': type = '|'; break; + case '^': type = '^'; break; + case '&': type = '&'; break; + case '>': type = '>'; break; + case '<': type = '<'; break; + case '-': type = '-'; break; + case '+': type = '+'; break; + case '%': type = '%'; break; + case '/': type = '/'; break; + case '*': type = '*'; break; + case '!': type = '!'; break; + case '~': type = '~'; break; + case '(': type = '('; break; + case ')': type = ')'; break; + + default: break; + } + + // Advance to the next token if the current one is valid. + if (type != 0) context->lexer->lex(token); + + return type; +} + +void yyerror(Context* context, const char* reason) +{ + context->diagnostics->report(pp::Diagnostics::INVALID_EXPRESSION, + context->token->location, + reason); +} + +namespace pp { + +ExpressionParser::ExpressionParser(Lexer* lexer, Diagnostics* diagnostics) : + mLexer(lexer), + mDiagnostics(diagnostics) +{ +} + +bool ExpressionParser::parse(Token* token, int* result) +{ + Context context; + context.diagnostics = mDiagnostics; + context.lexer = mLexer; + context.token = token; + context.result = result; + int ret = yyparse(&context); + switch (ret) + { + case 0: + case 1: + break; + + case 2: + mDiagnostics->report(Diagnostics::OUT_OF_MEMORY, token->location, ""); + break; + + default: + assert(false); + mDiagnostics->report(Diagnostics::INTERNAL_ERROR, token->location, ""); + break; + } + + return ret == 0; +} + +} // namespace pp diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.cpp index 694c3bda8..c3de95f31 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.cpp @@ -6,159 +6,49 @@ #include "Input.h" -#include <cstdio> - -#include "compiler/debug.h" +#include <algorithm> +#include <cassert> +#include <cstring> namespace pp { -Input::Input(int count, const char* const string[], const int length[]) - : mCount(count), - mString(string), - mLength(length), - mIndex(-1), - mSize(0), - mError(kErrorNone), - mState(kStateInitial) +Input::Input() : mCount(0), mString(0) { - ASSERT(mCount >= 0); - switchToNextString(); } -bool Input::eof() const +Input::Input(int count, const char* const string[], const int length[]) : + mCount(count), + mString(string) { - ASSERT(mIndex <= mCount); - return mIndex == mCount; + assert(mCount >= 0); + mLength.reserve(mCount); + for (int i = 0; i < mCount; ++i) + { + int len = length ? length[i] : -1; + mLength.push_back(len < 0 ? strlen(mString[i]) : len); + } } -int Input::read(char* buf, int bufSize) +int Input::read(char* buf, int maxSize) { - int nread = 0; - int startIndex = mIndex; - // Keep reading until the buffer is full or the current string is exhausted. - while ((mIndex == startIndex) && (nread < bufSize)) + int nRead = 0; + while ((nRead < maxSize) && (mReadLoc.sIndex < mCount)) { - int c = getChar(); - if (c == EOF) - { - if (mState == kStateBlockComment) - mError = kErrorUnexpectedEOF; - break; - } - - switch (mState) + int size = mLength[mReadLoc.sIndex] - mReadLoc.cIndex; + size = std::min(size, maxSize); + memcpy(buf + nRead, mString[mReadLoc.sIndex] + mReadLoc.cIndex, size); + nRead += size; + mReadLoc.cIndex += size; + + // Advance string if we reached the end of current string. + if (mReadLoc.cIndex == mLength[mReadLoc.sIndex]) { - case kStateInitial: - if (c == '/') - { - // Potentially a comment. - switch (peekChar()) - { - case '/': - getChar(); // Eat '/'. - mState = kStateLineComment; - break; - case '*': - getChar(); // Eat '*'. - mState = kStateBlockComment; - break; - default: - // Not a comment. - buf[nread++] = c; - break; - } - } else - { - buf[nread++] = c; - } - break; - - case kStateLineComment: - if (c == '\n') - { - buf[nread++] = c; - mState = kStateInitial; - } - break; - - case kStateBlockComment: - if (c == '*' && (peekChar() == '/')) - { - getChar(); // Eat '/'. - buf[nread++] = ' '; // Replace comment with whitespace. - mState = kStateInitial; - } else if (c == '\n') - { - // Line breaks are never skipped. - buf[nread++] = c; - } - break; - - default: - ASSERT(false); - break; + ++mReadLoc.sIndex; + mReadLoc.cIndex = 0; } } - - return nread; -} - -int Input::getChar() -{ - if (eof()) return EOF; - - const char* str = mString[mIndex]; - int c = str[mSize++]; - - // Switch to next string if the current one is fully read. - int length = stringLength(mIndex); - // We never read from empty string. - ASSERT(length != 0); - if (((length < 0) && (str[mSize] == '\0')) || - ((length > 0) && (mSize == length))) - switchToNextString(); - - return c; -} - -int Input::peekChar() -{ - // Save the current read position. - int index = mIndex; - int size = mSize; - int c = getChar(); - - // Restore read position. - mIndex = index; - mSize = size; - return c; -} - -void Input::switchToNextString() -{ - ASSERT(mIndex < mCount); - - mSize = 0; - do - { - ++mIndex; - } while (!eof() && isStringEmpty(mIndex)); -} - -bool Input::isStringEmpty(int index) -{ - ASSERT(index < mCount); - - const char* str = mString[mIndex]; - int length = stringLength(mIndex); - return (length == 0) || ((length < 0) && (str[0] == '\0')); -} - -int Input::stringLength(int index) -{ - ASSERT(index < mCount); - return mLength ? mLength[index] : -1; + return nRead; } } // namespace pp diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.h index 5a1b5d1a4..dac734b68 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.h @@ -7,66 +7,40 @@ #ifndef COMPILER_PREPROCESSOR_INPUT_H_ #define COMPILER_PREPROCESSOR_INPUT_H_ +#include <vector> + namespace pp { -// Reads the given set of strings into input buffer. -// Strips comments. +// Holds and reads input for Lexer. class Input { public: + Input(); Input(int count, const char* const string[], const int length[]); - enum Error - { - kErrorNone, - kErrorUnexpectedEOF - }; - Error error() const { return mError; } - - // Returns the index of string currently being scanned. - int stringIndex() const { return mIndex; } - // Returns true if EOF has reached. - bool eof() const; + int count() const { return mCount; } + const char* string(int index) const { return mString[index]; } + int length(int index) const { return mLength[index]; } - // Reads up to bufSize characters into buf. - // Returns the number of characters read. - // It replaces each comment by a whitespace. It reads only one string - // at a time so that the lexer has opportunity to update the string number - // for meaningful diagnostic messages. - int read(char* buf, int bufSize); + int read(char* buf, int maxSize); -private: - enum State + struct Location { - kStateInitial, - kStateLineComment, - kStateBlockComment - }; + int sIndex; // String index; + int cIndex; // Char index. - int getChar(); - int peekChar(); - // Switches input buffer to the next non-empty string. - // This is called when the current string is fully read. - void switchToNextString(); - // Returns true if the given string is empty. - bool isStringEmpty(int index); - // Return the length of the given string. - // Returns a negative value for null-terminated strings. - int stringLength(int index); + Location() : sIndex(0), cIndex(0) { } + }; + const Location& readLoc() const { return mReadLoc; } + private: // Input. int mCount; const char* const* mString; - const int* mLength; - - // Current read position. - int mIndex; // Index of string currently being scanned. - int mSize; // Size of string already scanned. + std::vector<int> mLength; - // Current error and state. - Error mError; - State mState; + Location mReadLoc; }; } // namespace pp diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Lexer.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Lexer.cpp new file mode 100644 index 000000000..7c663ee76 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Lexer.cpp @@ -0,0 +1,16 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "Lexer.h" + +namespace pp +{ + +Lexer::~Lexer() +{ +} + +} // namespace pp diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Lexer.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Lexer.h new file mode 100644 index 000000000..eb85cea87 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Lexer.h @@ -0,0 +1,25 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_PREPROCESSOR_LEXER_H_ +#define COMPILER_PREPROCESSOR_LEXER_H_ + +namespace pp +{ + +struct Token; + +class Lexer +{ + public: + virtual ~Lexer(); + + virtual void lex(Token* token) = 0; +}; + +} // namespace pp +#endif // COMPILER_PREPROCESSOR_LEXER_H_ + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Macro.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Macro.cpp index fccca966d..b2e3088e3 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Macro.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Macro.cpp @@ -6,39 +6,17 @@ #include "Macro.h" -#include <algorithm> - -#include "stl_utils.h" +#include "Token.h" namespace pp { -Macro::Macro(Type type, - std::string* name, - TokenVector* parameters, - TokenVector* replacements) - : mType(type), - mName(name), - mParameters(parameters), - mReplacements(replacements) -{ -} - -Macro::~Macro() +bool Macro::equals(const Macro& other) const { - delete mName; - - if (mParameters) - { - std::for_each(mParameters->begin(), mParameters->end(), Delete()); - delete mParameters; - } - - if (mReplacements) - { - std::for_each(mReplacements->begin(), mReplacements->end(), Delete()); - delete mReplacements; - } + return (type == other.type) && + (name == other.name) && + (parameters == other.parameters) && + (replacements == other.replacements); } } // namespace pp diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Macro.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Macro.h index e24330660..7ec014911 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Macro.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Macro.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -7,45 +7,38 @@ #ifndef COMPILER_PREPROCESSOR_MACRO_H_ #define COMPILER_PREPROCESSOR_MACRO_H_ +#include <map> #include <string> #include <vector> -#include "common/angleutils.h" -#include "Token.h" - namespace pp { -class Macro +struct Token; + +struct Macro { - public: enum Type { kTypeObj, kTypeFunc }; + typedef std::vector<std::string> Parameters; + typedef std::vector<Token> Replacements; + + Macro() : predefined(false), disabled(false), type(kTypeObj) { } + bool equals(const Macro& other) const; - // Takes ownership of pointer parameters. - Macro(Type type, - std::string* name, - TokenVector* parameters, - TokenVector* replacements); - ~Macro(); - - Type type() const { return mType; } - const std::string* identifier() const { return mName; } - const TokenVector* parameters() const { return mParameters; } - const TokenVector* replacements() const { return mReplacements; } - - private: - DISALLOW_COPY_AND_ASSIGN(Macro); - - Type mType; - std::string* mName; - TokenVector* mParameters; - TokenVector* mReplacements; + bool predefined; + mutable bool disabled; + + Type type; + std::string name; + Parameters parameters; + Replacements replacements; }; -} // namespace pp -#endif COMPILER_PREPROCESSOR_MACRO_H_ +typedef std::map<std::string, Macro> MacroSet; +} // namespace pp +#endif // COMPILER_PREPROCESSOR_MACRO_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/MacroExpander.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/MacroExpander.cpp new file mode 100644 index 000000000..fe5a7ae8c --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/MacroExpander.cpp @@ -0,0 +1,368 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "MacroExpander.h" + +#include <algorithm> +#include <cassert> +#include <sstream> + +#include "Diagnostics.h" +#include "Token.h" + +namespace pp +{ + +class TokenLexer : public Lexer +{ + public: + typedef std::vector<Token> TokenVector; + + TokenLexer(TokenVector* tokens) + { + tokens->swap(mTokens); + mIter = mTokens.begin(); + } + + virtual void lex(Token* token) + { + if (mIter == mTokens.end()) + { + token->reset(); + token->type = Token::LAST; + } + else + { + *token = *mIter++; + } + } + + private: + PP_DISALLOW_COPY_AND_ASSIGN(TokenLexer); + + TokenVector mTokens; + TokenVector::const_iterator mIter; +}; + +MacroExpander::MacroExpander(Lexer* lexer, + MacroSet* macroSet, + Diagnostics* diagnostics) : + mLexer(lexer), + mMacroSet(macroSet), + mDiagnostics(diagnostics) +{ +} + +MacroExpander::~MacroExpander() +{ + while (!mContextStack.empty()) popMacro(); +} + +void MacroExpander::lex(Token* token) +{ + while (true) + { + getToken(token); + + if (token->type != Token::IDENTIFIER) + break; + + if (token->expansionDisabled()) + break; + + MacroSet::const_iterator iter = mMacroSet->find(token->value); + if (iter == mMacroSet->end()) + break; + + const Macro& macro = iter->second; + if (macro.disabled) + { + // If a particular token is not expanded, it is never expanded. + token->setExpansionDisabled(true); + break; + } + if ((macro.type == Macro::kTypeFunc) && !isNextTokenLeftParen()) + { + // If the token immediately after the macro name is not a '(', + // this macro should not be expanded. + break; + } + + pushMacro(macro, *token); + } +} + +void MacroExpander::getToken(Token* token) +{ + if (mReserveToken.get()) + { + *token = *mReserveToken; + mReserveToken.reset(); + return; + } + + // First pop all empty macro contexts. + while (!mContextStack.empty() && mContextStack.back()->empty()) + { + popMacro(); + } + + if (!mContextStack.empty()) + { + *token = mContextStack.back()->get(); + } + else + { + mLexer->lex(token); + } +} + +void MacroExpander::ungetToken(const Token& token) +{ + if (!mContextStack.empty()) + { + MacroContext* context = mContextStack.back(); + context->unget(); + assert(context->replacements[context->index] == token); + } + else + { + assert(!mReserveToken.get()); + mReserveToken.reset(new Token(token)); + } +} + +bool MacroExpander::isNextTokenLeftParen() +{ + Token token; + getToken(&token); + + bool lparen = token.type == '('; + ungetToken(token); + + return lparen; +} + +bool MacroExpander::pushMacro(const Macro& macro, const Token& identifier) +{ + assert(!macro.disabled); + assert(!identifier.expansionDisabled()); + assert(identifier.type == Token::IDENTIFIER); + assert(identifier.value == macro.name); + + std::vector<Token> replacements; + if (!expandMacro(macro, identifier, &replacements)) + return false; + + // Macro is disabled for expansion until it is popped off the stack. + macro.disabled = true; + + MacroContext* context = new MacroContext; + context->macro = ¯o; + context->replacements.swap(replacements); + mContextStack.push_back(context); + return true; +} + +void MacroExpander::popMacro() +{ + assert(!mContextStack.empty()); + + MacroContext* context = mContextStack.back(); + mContextStack.pop_back(); + + assert(context->empty()); + assert(context->macro->disabled); + context->macro->disabled = false; + delete context; +} + +bool MacroExpander::expandMacro(const Macro& macro, + const Token& identifier, + std::vector<Token>* replacements) +{ + replacements->clear(); + if (macro.type == Macro::kTypeObj) + { + replacements->assign(macro.replacements.begin(), + macro.replacements.end()); + + if (macro.predefined) + { + static const std::string kLine = "__LINE__"; + static const std::string kFile = "__FILE__"; + + assert(replacements->size() == 1); + Token& repl = replacements->front(); + if (macro.name == kLine) + { + std::stringstream stream; + stream << identifier.location.line; + repl.value = stream.str(); + } + else if (macro.name == kFile) + { + std::stringstream stream; + stream << identifier.location.file; + repl.value = stream.str(); + } + } + } + else + { + assert(macro.type == Macro::kTypeFunc); + std::vector<MacroArg> args; + args.reserve(macro.parameters.size()); + if (!collectMacroArgs(macro, identifier, &args)) + return false; + + replaceMacroParams(macro, args, replacements); + } + + for (size_t i = 0; i < replacements->size(); ++i) + { + Token& repl = replacements->at(i); + if (i == 0) + { + // The first token in the replacement list inherits the padding + // properties of the identifier token. + repl.setAtStartOfLine(identifier.atStartOfLine()); + repl.setHasLeadingSpace(identifier.hasLeadingSpace()); + } + repl.location = identifier.location; + } + return true; +} + +bool MacroExpander::collectMacroArgs(const Macro& macro, + const Token& identifier, + std::vector<MacroArg>* args) +{ + Token token; + getToken(&token); + assert(token.type == '('); + + args->push_back(MacroArg()); + for (int openParens = 1; openParens != 0; ) + { + getToken(&token); + + if (token.type == Token::LAST) + { + mDiagnostics->report(Diagnostics::MACRO_UNTERMINATED_INVOCATION, + identifier.location, identifier.value); + // Do not lose EOF token. + ungetToken(token); + return false; + } + + bool isArg = false; // True if token is part of the current argument. + switch (token.type) + { + case '(': + ++openParens; + isArg = true; + break; + case ')': + --openParens; + isArg = openParens != 0; + break; + case ',': + // The individual arguments are separated by comma tokens, but + // the comma tokens between matching inner parentheses do not + // seperate arguments. + if (openParens == 1) args->push_back(MacroArg()); + isArg = openParens != 1; + break; + default: + isArg = true; + break; + } + if (isArg) + { + MacroArg& arg = args->back(); + // Initial whitespace is not part of the argument. + if (arg.empty()) token.setHasLeadingSpace(false); + arg.push_back(token); + } + } + + const Macro::Parameters& params = macro.parameters; + // If there is only one empty argument, it is equivalent to no argument. + if (params.empty() && (args->size() == 1) && args->front().empty()) + { + args->clear(); + } + // Validate the number of arguments. + if (args->size() != params.size()) + { + Diagnostics::ID id = args->size() < macro.parameters.size() ? + Diagnostics::MACRO_TOO_FEW_ARGS : + Diagnostics::MACRO_TOO_MANY_ARGS; + mDiagnostics->report(id, identifier.location, identifier.value); + return false; + } + + // Pre-expand each argument before substitution. + // This step expands each argument individually before they are + // inserted into the macro body. + for (size_t i = 0; i < args->size(); ++i) + { + MacroArg& arg = args->at(i); + TokenLexer lexer(&arg); + MacroExpander expander(&lexer, mMacroSet, mDiagnostics); + + arg.clear(); + expander.lex(&token); + while (token.type != Token::LAST) + { + arg.push_back(token); + expander.lex(&token); + } + } + return true; +} + +void MacroExpander::replaceMacroParams(const Macro& macro, + const std::vector<MacroArg>& args, + std::vector<Token>* replacements) +{ + for (size_t i = 0; i < macro.replacements.size(); ++i) + { + const Token& repl = macro.replacements[i]; + if (repl.type != Token::IDENTIFIER) + { + replacements->push_back(repl); + continue; + } + + // TODO(alokp): Optimize this. + // There is no need to search for macro params every time. + // The param index can be cached with the replacement token. + Macro::Parameters::const_iterator iter = std::find( + macro.parameters.begin(), macro.parameters.end(), repl.value); + if (iter == macro.parameters.end()) + { + replacements->push_back(repl); + continue; + } + + size_t iArg = std::distance(macro.parameters.begin(), iter); + const MacroArg& arg = args[iArg]; + if (arg.empty()) + { + continue; + } + size_t iRepl = replacements->size(); + replacements->insert(replacements->end(), arg.begin(), arg.end()); + // The replacement token inherits padding properties from + // macro replacement token. + replacements->at(iRepl).setHasLeadingSpace(repl.hasLeadingSpace()); + } +} + +} // namespace pp + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/MacroExpander.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/MacroExpander.h new file mode 100644 index 000000000..4504eba14 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/MacroExpander.h @@ -0,0 +1,74 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_ +#define COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_ + +#include <memory> +#include <vector> + +#include "Lexer.h" +#include "Macro.h" +#include "pp_utils.h" + +namespace pp +{ + +class Diagnostics; + +class MacroExpander : public Lexer +{ + public: + MacroExpander(Lexer* lexer, MacroSet* macroSet, Diagnostics* diagnostics); + virtual ~MacroExpander(); + + virtual void lex(Token* token); + + private: + PP_DISALLOW_COPY_AND_ASSIGN(MacroExpander); + + void getToken(Token* token); + void ungetToken(const Token& token); + bool isNextTokenLeftParen(); + + bool pushMacro(const Macro& macro, const Token& identifier); + void popMacro(); + + bool expandMacro(const Macro& macro, + const Token& identifier, + std::vector<Token>* replacements); + + typedef std::vector<Token> MacroArg; + bool collectMacroArgs(const Macro& macro, + const Token& identifier, + std::vector<MacroArg>* args); + void replaceMacroParams(const Macro& macro, + const std::vector<MacroArg>& args, + std::vector<Token>* replacements); + + struct MacroContext + { + const Macro* macro; + size_t index; + std::vector<Token> replacements; + + MacroContext() : macro(0), index(0) { } + bool empty() const { return index == replacements.size(); } + const Token& get() { return replacements[index++]; } + void unget() { --index; } + }; + + Lexer* mLexer; + MacroSet* mMacroSet; + Diagnostics* mDiagnostics; + + std::auto_ptr<Token> mReserveToken; + std::vector<MacroContext*> mContextStack; +}; + +} // namespace pp +#endif // COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_ + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Preprocessor.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Preprocessor.cpp index ef49e5772..21901fae0 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Preprocessor.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Preprocessor.cpp @@ -6,47 +6,108 @@ #include "Preprocessor.h" -#include <algorithm> +#include <cassert> +#include <sstream> -#include "compiler/debug.h" -#include "Context.h" -#include "stl_utils.h" +#include "Diagnostics.h" +#include "DirectiveParser.h" +#include "Macro.h" +#include "MacroExpander.h" +#include "Token.h" +#include "Tokenizer.h" namespace pp { -Preprocessor::Preprocessor() : mContext(NULL) +struct PreprocessorImpl { + Diagnostics* diagnostics; + MacroSet macroSet; + Tokenizer tokenizer; + DirectiveParser directiveParser; + MacroExpander macroExpander; + + PreprocessorImpl(Diagnostics* diag, + DirectiveHandler* directiveHandler) : + diagnostics(diag), + tokenizer(diag), + directiveParser(&tokenizer, ¯oSet, diag, directiveHandler), + macroExpander(&directiveParser, ¯oSet, diag) + { + } +}; + +Preprocessor::Preprocessor(Diagnostics* diagnostics, + DirectiveHandler* directiveHandler) +{ + mImpl = new PreprocessorImpl(diagnostics, directiveHandler); } Preprocessor::~Preprocessor() { - delete mContext; + delete mImpl; } -bool Preprocessor::init() +bool Preprocessor::init(int count, + const char* const string[], + const int length[]) { - mContext = new Context; - return mContext->init(); + static const int kGLSLVersion = 100; + + // Add standard pre-defined macros. + predefineMacro("__LINE__", 0); + predefineMacro("__FILE__", 0); + predefineMacro("__VERSION__", kGLSLVersion); + predefineMacro("GL_ES", 1); + + return mImpl->tokenizer.init(count, string, length); } -bool Preprocessor::process(int count, - const char* const string[], - const int length[]) +void Preprocessor::predefineMacro(const char* name, int value) { - ASSERT((count >=0) && (string != NULL)); - if ((count < 0) || (string == NULL)) - return false; + std::stringstream stream; + stream << value; + + Token token; + token.type = Token::CONST_INT; + token.value = stream.str(); - reset(); + Macro macro; + macro.predefined = true; + macro.type = Macro::kTypeObj; + macro.name = name; + macro.replacements.push_back(token); - return mContext->process(count, string, length, &mTokens); + mImpl->macroSet[name] = macro; } -void Preprocessor::reset() +void Preprocessor::lex(Token* token) { - std::for_each(mTokens.begin(), mTokens.end(), Delete()); - mTokens.clear(); + bool validToken = false; + while (!validToken) + { + mImpl->macroExpander.lex(token); + switch (token->type) + { + // We should not be returning internal preprocessing tokens. + // Convert preprocessing tokens to compiler tokens or report + // diagnostics. + case Token::PP_HASH: + assert(false); + break; + case Token::PP_NUMBER: + mImpl->diagnostics->report(Diagnostics::INVALID_NUMBER, + token->location, token->value); + break; + case Token::PP_OTHER: + mImpl->diagnostics->report(Diagnostics::INVALID_CHARACTER, + token->location, token->value); + break; + default: + validToken = true; + break; + } + } } } // namespace pp diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Preprocessor.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Preprocessor.h index 885bb70dd..5fe35b27b 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Preprocessor.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Preprocessor.h @@ -7,34 +7,41 @@ #ifndef COMPILER_PREPROCESSOR_PREPROCESSOR_H_ #define COMPILER_PREPROCESSOR_PREPROCESSOR_H_ -#include "common/angleutils.h" -#include "Token.h" +#include "pp_utils.h" namespace pp { -class Context; +class Diagnostics; +class DirectiveHandler; +struct PreprocessorImpl; +struct Token; class Preprocessor { public: - Preprocessor(); + Preprocessor(Diagnostics* diagnostics, DirectiveHandler* directiveHandler); ~Preprocessor(); - bool init(); - - bool process(int count, const char* const string[], const int length[]); - TokenIterator begin() const { return mTokens.begin(); } - TokenIterator end() const { return mTokens.end(); } + // count: specifies the number of elements in the string and length arrays. + // string: specifies an array of pointers to strings. + // length: specifies an array of string lengths. + // If length is NULL, each string is assumed to be null terminated. + // If length is a value other than NULL, it points to an array containing + // a string length for each of the corresponding elements of string. + // Each element in the length array may contain the length of the + // corresponding string or a value less than 0 to indicate that the string + // is null terminated. + bool init(int count, const char* const string[], const int length[]); + // Adds a pre-defined macro. + void predefineMacro(const char* name, int value); + + void lex(Token* token); private: - DISALLOW_COPY_AND_ASSIGN(Preprocessor); - - // Reset to initialized state. - void reset(); + PP_DISALLOW_COPY_AND_ASSIGN(Preprocessor); - Context* mContext; - TokenVector mTokens; // Output. + PreprocessorImpl* mImpl; }; } // namespace pp diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/SourceLocation.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/SourceLocation.h new file mode 100644 index 000000000..6982613ac --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/SourceLocation.h @@ -0,0 +1,38 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_PREPROCESSOR_SOURCE_LOCATION_H_ +#define COMPILER_PREPROCESSOR_SOURCE_LOCATION_H_ + +namespace pp +{ + +struct SourceLocation +{ + SourceLocation() : file(0), line(0) { } + SourceLocation(int f, int l) : file(f), line(l) { } + + bool equals(const SourceLocation& other) const + { + return (file == other.file) && (line == other.line); + } + + int file; + int line; +}; + +inline bool operator==(const SourceLocation& lhs, const SourceLocation& rhs) +{ + return lhs.equals(rhs); +} + +inline bool operator!=(const SourceLocation& lhs, const SourceLocation& rhs) +{ + return !lhs.equals(rhs); +} + +} // namespace pp +#endif // COMPILER_PREPROCESSOR_SOURCE_LOCATION_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Token.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Token.cpp index a2e759c69..960380ce9 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Token.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Token.cpp @@ -6,50 +6,56 @@ #include "Token.h" -#include "token_type.h" - -static const int kLocationLineSize = 16; // in bits. -static const int kLocationLineMask = (1 << kLocationLineSize) - 1; - namespace pp { -Token::Location Token::encodeLocation(int line, int file) +void Token::reset() { - return (file << kLocationLineSize) | (line & kLocationLineMask); + type = 0; + flags = 0; + location = SourceLocation(); + value.clear(); } -void Token::decodeLocation(Location loc, int* line, int* file) +bool Token::equals(const Token& other) const { - if (file) *file = loc >> kLocationLineSize; - if (line) *line = loc & kLocationLineMask; + return (type == other.type) && + (flags == other.flags) && + (location == other.location) && + (value == other.value); } -Token::Token(Location location, int type, std::string* value) - : mLocation(location), - mType(type), - mValue(value) +void Token::setAtStartOfLine(bool start) { + if (start) + flags |= AT_START_OF_LINE; + else + flags &= ~AT_START_OF_LINE; } -Token::~Token() { - delete mValue; +void Token::setHasLeadingSpace(bool space) +{ + if (space) + flags |= HAS_LEADING_SPACE; + else + flags &= ~HAS_LEADING_SPACE; +} + +void Token::setExpansionDisabled(bool disable) +{ + if (disable) + flags |= EXPANSION_DISABLED; + else + flags &= ~EXPANSION_DISABLED; } std::ostream& operator<<(std::ostream& out, const Token& token) { - switch (token.type()) - { - case INT_CONSTANT: - case FLOAT_CONSTANT: - case IDENTIFIER: - out << *(token.value()); - break; - default: - out << static_cast<char>(token.type()); - break; - } + if (token.hasLeadingSpace()) + out << " "; + + out << token.value; return out; } -} // namespace pp +} // namespace pp diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Token.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Token.h index 4f5a12bf1..5231021ed 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Token.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Token.h @@ -7,42 +7,94 @@ #ifndef COMPILER_PREPROCESSOR_TOKEN_H_ #define COMPILER_PREPROCESSOR_TOKEN_H_ +#include <ostream> #include <string> -#include <vector> -#include "common/angleutils.h" +#include "SourceLocation.h" namespace pp { -class Token +struct Token { - public: - typedef int Location; - static Location encodeLocation(int line, int file); - static void decodeLocation(Location loc, int* line, int* file); + enum Type + { + LAST = 0, // EOF. - // Takes ownership of string. - Token(Location location, int type, std::string* value); - ~Token(); + IDENTIFIER = 258, - Location location() const { return mLocation; } - int type() const { return mType; } - const std::string* value() const { return mValue; } + CONST_INT, + CONST_FLOAT, - private: - DISALLOW_COPY_AND_ASSIGN(Token); + OP_INC, + OP_DEC, + OP_LEFT, + OP_RIGHT, + OP_LE, + OP_GE, + OP_EQ, + OP_NE, + OP_AND, + OP_XOR, + OP_OR, + OP_ADD_ASSIGN, + OP_SUB_ASSIGN, + OP_MUL_ASSIGN, + OP_DIV_ASSIGN, + OP_MOD_ASSIGN, + OP_LEFT_ASSIGN, + OP_RIGHT_ASSIGN, + OP_AND_ASSIGN, + OP_XOR_ASSIGN, + OP_OR_ASSIGN, - Location mLocation; - int mType; - std::string* mValue; + // Preprocessing token types. + // These types are used by the preprocessor internally. + // Preprocessor clients must not depend or check for them. + PP_HASH, + PP_NUMBER, + PP_OTHER + }; + enum Flags + { + AT_START_OF_LINE = 1 << 0, + HAS_LEADING_SPACE = 1 << 1, + EXPANSION_DISABLED = 1 << 2 + }; + + Token() : type(0), flags(0) { } + + void reset(); + bool equals(const Token& other) const; + + // Returns true if this is the first token on line. + // It disregards any leading whitespace. + bool atStartOfLine() const { return (flags & AT_START_OF_LINE) != 0; } + void setAtStartOfLine(bool start); + + bool hasLeadingSpace() const { return (flags & HAS_LEADING_SPACE) != 0; } + void setHasLeadingSpace(bool space); + + bool expansionDisabled() const { return (flags & EXPANSION_DISABLED) != 0; } + void setExpansionDisabled(bool disable); + + int type; + unsigned int flags; + SourceLocation location; + std::string value; }; -typedef std::vector<Token*> TokenVector; -typedef TokenVector::const_iterator TokenIterator; +inline bool operator==(const Token& lhs, const Token& rhs) +{ + return lhs.equals(rhs); +} + +inline bool operator!=(const Token& lhs, const Token& rhs) +{ + return !lhs.equals(rhs); +} extern std::ostream& operator<<(std::ostream& out, const Token& token); } // namepsace pp #endif // COMPILER_PREPROCESSOR_TOKEN_H_ - diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Tokenizer.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Tokenizer.cpp new file mode 100644 index 000000000..3bc3d1c4b --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Tokenizer.cpp @@ -0,0 +1,2344 @@ +#line 16 "./preprocessor/new/Tokenizer.l" +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// This file is auto-generated by generate_parser.sh. DO NOT EDIT! + + + +#line 13 "./preprocessor/new/Tokenizer.cpp" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include <inttypes.h> +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin yyg->yyin_r +#define yyout yyg->yyout_r +#define yyextra yyg->yyextra_r +#define yyleng yyg->yyleng_r +#define yytext yyg->yytext_r +#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) +#define yy_flex_debug yyg->yy_flex_debug_r + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yyg->yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yyg->yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE pprestart(yyin ,yyscanner ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = yyg->yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via pprestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ + ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] + +void pprestart (FILE *input_file ,yyscan_t yyscanner ); +void pp_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +YY_BUFFER_STATE pp_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); +void pp_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void pp_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void pppush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +void pppop_buffer_state (yyscan_t yyscanner ); + +static void ppensure_buffer_stack (yyscan_t yyscanner ); +static void pp_load_buffer_state (yyscan_t yyscanner ); +static void pp_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); + +#define YY_FLUSH_BUFFER pp_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) + +YY_BUFFER_STATE pp_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); +YY_BUFFER_STATE pp_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); +YY_BUFFER_STATE pp_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); + +void *ppalloc (yy_size_t ,yyscan_t yyscanner ); +void *pprealloc (void *,yy_size_t ,yyscan_t yyscanner ); +void ppfree (void * ,yyscan_t yyscanner ); + +#define yy_new_buffer pp_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + ppensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + ppensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define ppwrap(n) 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +typedef int yy_state_type; + +#define yytext_ptr yytext_r + +static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); +static int yy_get_next_buffer (yyscan_t yyscanner ); +static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yyg->yytext_ptr = yy_bp; \ + yyleng = (size_t) (yy_cp - yy_bp); \ + yyg->yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yyg->yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 37 +#define YY_END_OF_BUFFER 38 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[84] = + { 0, + 0, 0, 0, 0, 38, 36, 34, 35, 35, 33, + 7, 33, 33, 33, 33, 33, 33, 33, 33, 9, + 9, 33, 33, 33, 8, 33, 33, 3, 5, 5, + 4, 34, 35, 19, 27, 20, 30, 25, 12, 23, + 13, 24, 10, 2, 1, 26, 10, 9, 11, 11, + 11, 11, 9, 14, 16, 18, 17, 15, 8, 31, + 21, 32, 22, 3, 5, 6, 11, 10, 11, 1, + 10, 11, 0, 10, 9, 28, 29, 0, 10, 10, + 10, 10, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 5, 1, 6, 1, 7, 8, 1, 9, + 9, 10, 11, 9, 12, 13, 14, 15, 16, 16, + 16, 16, 16, 16, 16, 17, 17, 9, 9, 18, + 19, 20, 9, 1, 21, 21, 21, 21, 22, 21, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 24, 23, 23, + 9, 1, 9, 25, 23, 1, 21, 21, 21, 21, + + 22, 21, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, + 23, 23, 9, 26, 9, 9, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[27] = + { 0, + 1, 1, 2, 2, 1, 1, 1, 1, 1, 3, + 1, 1, 4, 1, 5, 5, 5, 1, 1, 1, + 5, 5, 5, 5, 1, 1 + } ; + +static yyconst flex_int16_t yy_base[89] = + { 0, + 0, 0, 24, 26, 158, 159, 150, 159, 145, 128, + 159, 112, 23, 159, 111, 21, 25, 30, 29, 36, + 46, 36, 100, 45, 0, 16, 47, 0, 159, 84, + 65, 73, 159, 159, 159, 159, 159, 159, 159, 159, + 159, 159, 61, 159, 0, 159, 73, 32, 56, 83, + 95, 68, 0, 31, 159, 159, 159, 19, 0, 159, + 159, 159, 159, 0, 159, 159, 98, 0, 110, 0, + 0, 117, 52, 90, 80, 159, 159, 101, 97, 112, + 120, 123, 159, 140, 28, 145, 150, 152 + } ; + +static yyconst flex_int16_t yy_def[89] = + { 0, + 83, 1, 84, 84, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 20, 83, 83, 83, 85, 83, 83, 86, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 87, 83, 83, 20, 20, 47, + 50, 88, 21, 83, 83, 83, 83, 83, 85, 83, + 83, 83, 83, 86, 83, 83, 43, 43, 67, 87, + 47, 50, 83, 51, 88, 83, 83, 83, 69, 72, + 83, 83, 0, 83, 83, 83, 83, 83 + } ; + +static yyconst flex_int16_t yy_nxt[186] = + { 0, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, + 25, 25, 25, 25, 26, 27, 29, 30, 29, 30, + 36, 39, 59, 31, 60, 31, 41, 77, 44, 40, + 61, 37, 45, 42, 43, 43, 43, 46, 47, 76, + 48, 48, 49, 54, 55, 50, 50, 51, 50, 52, + 53, 53, 53, 57, 58, 62, 81, 81, 81, 50, + 49, 49, 63, 67, 32, 68, 68, 68, 66, 50, + 50, 67, 69, 67, 67, 50, 65, 71, 71, 71, + 50, 50, 50, 50, 72, 50, 50, 50, 50, 50, + + 83, 83, 50, 50, 50, 73, 73, 83, 83, 74, + 74, 74, 67, 67, 67, 82, 82, 82, 56, 67, + 78, 78, 83, 83, 79, 79, 79, 78, 78, 38, + 35, 80, 80, 80, 81, 81, 81, 82, 82, 82, + 28, 28, 28, 28, 28, 64, 34, 33, 64, 64, + 70, 32, 70, 70, 70, 75, 75, 83, 5, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83 + } ; + +static yyconst flex_int16_t yy_chk[186] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 3, 4, 4, + 13, 16, 85, 3, 26, 4, 17, 58, 19, 16, + 26, 13, 19, 17, 18, 18, 18, 19, 20, 54, + 20, 20, 20, 22, 22, 48, 20, 20, 20, 20, + 21, 21, 21, 24, 24, 27, 73, 73, 73, 21, + 49, 49, 27, 43, 32, 43, 43, 43, 31, 49, + 52, 43, 43, 43, 43, 47, 30, 47, 47, 47, + 52, 52, 75, 47, 47, 47, 47, 50, 50, 50, + + 74, 74, 75, 75, 50, 51, 51, 79, 79, 51, + 51, 51, 67, 67, 67, 78, 78, 78, 23, 67, + 69, 69, 80, 80, 69, 69, 69, 72, 72, 15, + 12, 72, 72, 72, 81, 81, 81, 82, 82, 82, + 84, 84, 84, 84, 84, 86, 10, 9, 86, 86, + 87, 7, 87, 87, 87, 88, 88, 5, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83 + } ; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +/* +// +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +This file contains the Lex specification for GLSL ES preprocessor. +Based on Microsoft Visual Studio 2010 Preprocessor Grammar: +http://msdn.microsoft.com/en-us/library/2scxys89.aspx + +IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. +*/ + +#include "Tokenizer.h" + +#include "Diagnostics.h" +#include "Token.h" + +#if defined(__GNUC__) +// Triggered by the auto-generated yy_fatal_error function. +#pragma GCC diagnostic ignored "-Wmissing-noreturn" +#endif + +typedef std::string YYSTYPE; +typedef pp::SourceLocation YYLTYPE; + +// Use the unused yycolumn variable to track file (string) number. +#define yyfileno yycolumn + +#define YY_USER_INIT \ + do { \ + yyfileno = 0; \ + yylineno = 1; \ + yyextra->leadingSpace = false; \ + yyextra->lineStart = true; \ + } while(0); + +#define YY_USER_ACTION \ + do \ + { \ + pp::Input* input = &yyextra->input; \ + pp::Input::Location* scanLoc = &yyextra->scanLoc; \ + while ((scanLoc->sIndex < input->count()) && \ + (scanLoc->cIndex >= input->length(scanLoc->sIndex))) \ + { \ + scanLoc->cIndex -= input->length(scanLoc->sIndex++); \ + ++yyfileno; yylineno = 1; \ + } \ + yylloc->file = yyfileno; \ + yylloc->line = yylineno; \ + scanLoc->cIndex += yyleng; \ + } while(0); + +#define YY_INPUT(buf, result, maxSize) \ + result = yyextra->input.read(buf, maxSize); + +#define INITIAL 0 +#define COMMENT 1 + +#define YY_EXTRA_TYPE pp::Tokenizer::Context* + +/* Holds the entire state of the reentrant scanner. */ +struct yyguts_t + { + + /* User-defined. Not touched by flex. */ + YY_EXTRA_TYPE yyextra_r; + + /* The rest are the same as the globals declared in the non-reentrant scanner. */ + FILE *yyin_r, *yyout_r; + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ + char yy_hold_char; + yy_size_t yy_n_chars; + yy_size_t yyleng_r; + char *yy_c_buf_p; + int yy_init; + int yy_start; + int yy_did_buffer_switch_on_eof; + int yy_start_stack_ptr; + int yy_start_stack_depth; + int *yy_start_stack; + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + int yylineno_r; + int yy_flex_debug_r; + + char *yytext_r; + int yy_more_flag; + int yy_more_len; + + YYSTYPE * yylval_r; + + YYLTYPE * yylloc_r; + + }; /* end struct yyguts_t */ + +static int yy_init_globals (yyscan_t yyscanner ); + + /* This must go here because YYSTYPE and YYLTYPE are included + * from bison output in section 1.*/ + # define yylval yyg->yylval_r + + # define yylloc yyg->yylloc_r + +int pplex_init (yyscan_t* scanner); + +int pplex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int pplex_destroy (yyscan_t yyscanner ); + +int ppget_debug (yyscan_t yyscanner ); + +void ppset_debug (int debug_flag ,yyscan_t yyscanner ); + +YY_EXTRA_TYPE ppget_extra (yyscan_t yyscanner ); + +void ppset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); + +FILE *ppget_in (yyscan_t yyscanner ); + +void ppset_in (FILE * in_str ,yyscan_t yyscanner ); + +FILE *ppget_out (yyscan_t yyscanner ); + +void ppset_out (FILE * out_str ,yyscan_t yyscanner ); + +yy_size_t ppget_leng (yyscan_t yyscanner ); + +char *ppget_text (yyscan_t yyscanner ); + +int ppget_lineno (yyscan_t yyscanner ); + +void ppset_lineno (int line_number ,yyscan_t yyscanner ); + +YYSTYPE * ppget_lval (yyscan_t yyscanner ); + +void ppset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); + + YYLTYPE *ppget_lloc (yyscan_t yyscanner ); + + void ppset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int ppwrap (yyscan_t yyscanner ); +#else +extern int ppwrap (yyscan_t yyscanner ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (yyscan_t yyscanner ); +#else +static int input (yyscan_t yyscanner ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + yy_size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int pplex \ + (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); + +#define YY_DECL int pplex \ + (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* Line comment */ + + yylval = yylval_param; + + yylloc = yylloc_param; + + if ( !yyg->yy_init ) + { + yyg->yy_init = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yyg->yy_start ) + yyg->yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + ppensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + pp_load_buffer_state(yyscanner ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yyg->yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yyg->yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yyg->yy_start; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 84 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_current_state != 83 ); + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yyg->yy_hold_char; + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + +case 1: +YY_RULE_SETUP + + YY_BREAK +/* Block comment */ +/* Line breaks are just counted - not returned. */ +/* The comment is replaced by a single space. */ +case 2: +YY_RULE_SETUP +{ BEGIN(COMMENT); } + YY_BREAK +case 3: +YY_RULE_SETUP + + YY_BREAK +case 4: +YY_RULE_SETUP + + YY_BREAK +case 5: +/* rule 5 can match eol */ +YY_RULE_SETUP +{ ++yylineno; } + YY_BREAK +case 6: +YY_RULE_SETUP +{ + yyextra->leadingSpace = true; + BEGIN(INITIAL); +} + YY_BREAK +case 7: +YY_RULE_SETUP +{ + // # is only valid at start of line for preprocessor directives. + yylval->assign(1, yytext[0]); + return yyextra->lineStart ? pp::Token::PP_HASH : pp::Token::PP_OTHER; +} + YY_BREAK +case 8: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::IDENTIFIER; +} + YY_BREAK +case 9: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::CONST_INT; +} + YY_BREAK +case 10: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::CONST_FLOAT; +} + YY_BREAK +/* Anything that starts with a {DIGIT} or .{DIGIT} must be a number. */ +/* Rule to catch all invalid integers and floats. */ +case 11: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::PP_NUMBER; +} + YY_BREAK +case 12: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_INC; +} + YY_BREAK +case 13: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_DEC; +} + YY_BREAK +case 14: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_LEFT; +} + YY_BREAK +case 15: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_RIGHT; +} + YY_BREAK +case 16: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_LE; +} + YY_BREAK +case 17: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_GE; +} + YY_BREAK +case 18: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_EQ; +} + YY_BREAK +case 19: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_NE; +} + YY_BREAK +case 20: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_AND; +} + YY_BREAK +case 21: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_XOR; +} + YY_BREAK +case 22: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_OR; +} + YY_BREAK +case 23: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_ADD_ASSIGN; +} + YY_BREAK +case 24: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_SUB_ASSIGN; +} + YY_BREAK +case 25: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_MUL_ASSIGN; +} + YY_BREAK +case 26: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_DIV_ASSIGN; +} + YY_BREAK +case 27: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_MOD_ASSIGN; +} + YY_BREAK +case 28: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_LEFT_ASSIGN; +} + YY_BREAK +case 29: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_RIGHT_ASSIGN; +} + YY_BREAK +case 30: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_AND_ASSIGN; +} + YY_BREAK +case 31: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_XOR_ASSIGN; +} + YY_BREAK +case 32: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_OR_ASSIGN; +} + YY_BREAK +case 33: +YY_RULE_SETUP +{ + yylval->assign(1, yytext[0]); + return yytext[0]; +} + YY_BREAK +case 34: +YY_RULE_SETUP +{ yyextra->leadingSpace = true; } + YY_BREAK +case 35: +/* rule 35 can match eol */ +YY_RULE_SETUP +{ + ++yylineno; + yylval->assign(1, '\n'); + return '\n'; +} + YY_BREAK +case 36: +YY_RULE_SETUP +{ + yylval->assign(1, yytext[0]); + return pp::Token::PP_OTHER; +} + YY_BREAK +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(COMMENT): +{ + // YY_USER_ACTION is not invoked for handling EOF. + // Set the location for EOF token manually. + pp::Input* input = &yyextra->input; + pp::Input::Location* scanLoc = &yyextra->scanLoc; + int sIndexMax = std::max(0, input->count() - 1); + if (scanLoc->sIndex != sIndexMax) + { + // We can only reach here if there are empty strings at the + // end of the input. + scanLoc->sIndex = sIndexMax; scanLoc->cIndex = 0; + yyfileno = sIndexMax; yylineno = 1; + } + yylloc->file = yyfileno; + yylloc->line = yylineno; + yylval->clear(); + + if (YY_START == COMMENT) + { + yyextra->diagnostics->report(pp::Diagnostics::EOF_IN_COMMENT, + pp::SourceLocation(yyfileno, yylineno), + ""); + } + yyterminate(); +} + YY_BREAK +case 37: +YY_RULE_SETUP +ECHO; + YY_BREAK + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yyg->yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * pplex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); + + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yyg->yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_END_OF_FILE: + { + yyg->yy_did_buffer_switch_on_eof = 0; + + if ( ppwrap(yyscanner ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = + yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yyg->yy_c_buf_p = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of pplex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = yyg->yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; + + else + { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) (yyg->yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + yy_size_t new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + pprealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + yyg->yy_n_chars, num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + if ( yyg->yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + pprestart(yyin ,yyscanner); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) pprealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + yyg->yy_n_chars += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (yyscan_t yyscanner) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_current_state = yyg->yy_start; + + for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 84 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) +{ + register int yy_is_jam; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ + register char *yy_cp = yyg->yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 84 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 83); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (yyscan_t yyscanner) +#else + static int input (yyscan_t yyscanner) +#endif + +{ + int c; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + *yyg->yy_c_buf_p = yyg->yy_hold_char; + + if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + /* This was really a NUL. */ + *yyg->yy_c_buf_p = '\0'; + + else + { /* need more input */ + yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr; + ++yyg->yy_c_buf_p; + + switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + pprestart(yyin ,yyscanner); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( ppwrap(yyscanner ) ) + return 0; + + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(yyscanner); +#else + return input(yyscanner); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = yyg->yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ + *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ + yyg->yy_hold_char = *++yyg->yy_c_buf_p; + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * @param yyscanner The scanner object. + * @note This function does not reset the start condition to @c INITIAL . + */ + void pprestart (FILE * input_file , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! YY_CURRENT_BUFFER ){ + ppensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + pp_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); + pp_load_buffer_state(yyscanner ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * @param yyscanner The scanner object. + */ + void pp_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* TODO. We should be able to replace this entire function body + * with + * pppop_buffer_state(); + * pppush_buffer_state(new_buffer); + */ + ppensure_buffer_stack (yyscanner); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + pp_load_buffer_state(yyscanner ); + + /* We don't actually know whether we did this switch during + * EOF (ppwrap()) processing, but the only time this flag + * is looked at is after ppwrap() is called, so it's safe + * to go ahead and always set it. + */ + yyg->yy_did_buffer_switch_on_eof = 1; +} + +static void pp_load_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + yyg->yy_hold_char = *yyg->yy_c_buf_p; +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * @param yyscanner The scanner object. + * @return the allocated buffer state. + */ + YY_BUFFER_STATE pp_create_buffer (FILE * file, int size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) ppalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in pp_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) ppalloc(b->yy_buf_size + 2 ,yyscanner ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in pp_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + pp_init_buffer(b,file ,yyscanner); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with pp_create_buffer() + * @param yyscanner The scanner object. + */ + void pp_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + ppfree((void *) b->yy_ch_buf ,yyscanner ); + + ppfree((void *) b ,yyscanner ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a pprestart() or at EOF. + */ + static void pp_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) + +{ + int oerrno = errno; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + pp_flush_buffer(b ,yyscanner); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then pp_init_buffer was _probably_ + * called from pprestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * @param yyscanner The scanner object. + */ + void pp_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + pp_load_buffer_state(yyscanner ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * @param yyscanner The scanner object. + */ +void pppush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (new_buffer == NULL) + return; + + ppensure_buffer_stack(yyscanner); + + /* This block is copied from pp_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + yyg->yy_buffer_stack_top++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from pp_switch_to_buffer. */ + pp_load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * @param yyscanner The scanner object. + */ +void pppop_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (!YY_CURRENT_BUFFER) + return; + + pp_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); + YY_CURRENT_BUFFER_LVALUE = NULL; + if (yyg->yy_buffer_stack_top > 0) + --yyg->yy_buffer_stack_top; + + if (YY_CURRENT_BUFFER) { + pp_load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void ppensure_buffer_stack (yyscan_t yyscanner) +{ + yy_size_t num_to_alloc; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (!yyg->yy_buffer_stack) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + yyg->yy_buffer_stack = (struct yy_buffer_state**)ppalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in ppensure_buffer_stack()" ); + + memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + yyg->yy_buffer_stack_max = num_to_alloc; + yyg->yy_buffer_stack_top = 0; + return; + } + + if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = yyg->yy_buffer_stack_max + grow_size; + yyg->yy_buffer_stack = (struct yy_buffer_state**)pprealloc + (yyg->yy_buffer_stack, + num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in ppensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); + yyg->yy_buffer_stack_max = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE pp_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) ppalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in pp_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + pp_switch_to_buffer(b ,yyscanner ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to pplex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * pp_scan_bytes() instead. + */ +YY_BUFFER_STATE pp_scan_string (yyconst char * yystr , yyscan_t yyscanner) +{ + + return pp_scan_bytes(yystr,strlen(yystr) ,yyscanner); +} + +/** Setup the input buffer state to scan the given bytes. The next call to pplex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE pp_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n, i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) ppalloc(n ,yyscanner ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in pp_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = pp_scan_buffer(buf,n ,yyscanner); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in pp_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = yyg->yy_hold_char; \ + yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ + yyg->yy_hold_char = *yyg->yy_c_buf_p; \ + *yyg->yy_c_buf_p = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the user-defined data for this scanner. + * @param yyscanner The scanner object. + */ +YY_EXTRA_TYPE ppget_extra (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyextra; +} + +/** Get the current line number. + * @param yyscanner The scanner object. + */ +int ppget_lineno (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yylineno; +} + +/** Get the current column number. + * @param yyscanner The scanner object. + */ +int ppget_column (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yycolumn; +} + +/** Get the input stream. + * @param yyscanner The scanner object. + */ +FILE *ppget_in (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyin; +} + +/** Get the output stream. + * @param yyscanner The scanner object. + */ +FILE *ppget_out (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyout; +} + +/** Get the length of the current token. + * @param yyscanner The scanner object. + */ +yy_size_t ppget_leng (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyleng; +} + +/** Get the current token. + * @param yyscanner The scanner object. + */ + +char *ppget_text (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yytext; +} + +/** Set the user-defined data. This data is never touched by the scanner. + * @param user_defined The data to be associated with this scanner. + * @param yyscanner The scanner object. + */ +void ppset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyextra = user_defined ; +} + +/** Set the current line number. + * @param line_number + * @param yyscanner The scanner object. + */ +void ppset_lineno (int line_number , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* lineno is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "ppset_lineno called with no buffer" , yyscanner); + + yylineno = line_number; +} + +/** Set the current column. + * @param line_number + * @param yyscanner The scanner object. + */ +void ppset_column (int column_no , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* column is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "ppset_column called with no buffer" , yyscanner); + + yycolumn = column_no; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * @param yyscanner The scanner object. + * @see pp_switch_to_buffer + */ +void ppset_in (FILE * in_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyin = in_str ; +} + +void ppset_out (FILE * out_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyout = out_str ; +} + +int ppget_debug (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yy_flex_debug; +} + +void ppset_debug (int bdebug , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yy_flex_debug = bdebug ; +} + +/* Accessor methods for yylval and yylloc */ + +YYSTYPE * ppget_lval (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yylval; +} + +void ppset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yylval = yylval_param; +} + +YYLTYPE *ppget_lloc (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yylloc; +} + +void ppset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yylloc = yylloc_param; +} + +/* User-visible API */ + +/* pplex_init is special because it creates the scanner itself, so it is + * the ONLY reentrant function that doesn't take the scanner as the last argument. + * That's why we explicitly handle the declaration, instead of using our macros. + */ + +int pplex_init(yyscan_t* ptr_yy_globals) + +{ + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) ppalloc ( sizeof( struct yyguts_t ), NULL ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + return yy_init_globals ( *ptr_yy_globals ); +} + +/* pplex_init_extra has the same functionality as pplex_init, but follows the + * convention of taking the scanner as the last argument. Note however, that + * this is a *pointer* to a scanner, as it will be allocated by this call (and + * is the reason, too, why this function also must handle its own declaration). + * The user defined value in the first argument will be available to ppalloc in + * the yyextra field. + */ + +int pplex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) + +{ + struct yyguts_t dummy_yyguts; + + ppset_extra (yy_user_defined, &dummy_yyguts); + + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) ppalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in + yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + ppset_extra (yy_user_defined, *ptr_yy_globals); + + return yy_init_globals ( *ptr_yy_globals ); +} + +static int yy_init_globals (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from pplex_destroy(), so don't allocate here. + */ + + yyg->yy_buffer_stack = 0; + yyg->yy_buffer_stack_top = 0; + yyg->yy_buffer_stack_max = 0; + yyg->yy_c_buf_p = (char *) 0; + yyg->yy_init = 0; + yyg->yy_start = 0; + + yyg->yy_start_stack_ptr = 0; + yyg->yy_start_stack_depth = 0; + yyg->yy_start_stack = NULL; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * pplex_init() + */ + return 0; +} + +/* pplex_destroy is for both reentrant and non-reentrant scanners. */ +int pplex_destroy (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + pp_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); + YY_CURRENT_BUFFER_LVALUE = NULL; + pppop_buffer_state(yyscanner); + } + + /* Destroy the stack itself. */ + ppfree(yyg->yy_buffer_stack ,yyscanner); + yyg->yy_buffer_stack = NULL; + + /* Destroy the start condition stack. */ + ppfree(yyg->yy_start_stack ,yyscanner ); + yyg->yy_start_stack = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * pplex() is called, initialization will occur. */ + yy_init_globals( yyscanner); + + /* Destroy the main struct (reentrant only). */ + ppfree ( yyscanner , yyscanner ); + yyscanner = NULL; + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *ppalloc (yy_size_t size , yyscan_t yyscanner) +{ + return (void *) malloc( size ); +} + +void *pprealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void ppfree (void * ptr , yyscan_t yyscanner) +{ + free( (char *) ptr ); /* see pprealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +namespace pp { + +Tokenizer::Tokenizer(Diagnostics* diagnostics) : mHandle(0) +{ + mContext.diagnostics = diagnostics; +} + +Tokenizer::~Tokenizer() +{ + destroyScanner(); +} + +bool Tokenizer::init(int count, const char* const string[], const int length[]) +{ + if (count < 0) return false; + if ((count > 0) && (string == 0)) return false; + + mContext.input = Input(count, string, length); + return initScanner(); +} + +void Tokenizer::setFileNumber(int file) +{ + // We use column number as file number. + // See macro yyfileno. + ppset_column(file,mHandle); +} + +void Tokenizer::setLineNumber(int line) +{ + ppset_lineno(line,mHandle); +} + +void Tokenizer::lex(Token* token) +{ + token->type = pplex(&token->value,&token->location,mHandle); + token->flags = 0; + + token->setAtStartOfLine(mContext.lineStart); + mContext.lineStart = token->type == '\n'; + + token->setHasLeadingSpace(mContext.leadingSpace); + mContext.leadingSpace = false; +} + +bool Tokenizer::initScanner() +{ + if ((mHandle == NULL) && pplex_init_extra(&mContext,&mHandle)) + return false; + + pprestart(0,mHandle); + return true; +} + +void Tokenizer::destroyScanner() +{ + if (mHandle == NULL) + return; + + pplex_destroy(mHandle); + mHandle = NULL; +} + +} // namespace pp + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Tokenizer.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Tokenizer.h new file mode 100644 index 000000000..b64a28897 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Tokenizer.h @@ -0,0 +1,57 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_PREPROCESSOR_TOKENIZER_H_ +#define COMPILER_PREPROCESSOR_TOKENIZER_H_ + +#include "Input.h" +#include "Lexer.h" +#include "pp_utils.h" + +namespace pp +{ + +class Diagnostics; + +class Tokenizer : public Lexer +{ + public: + struct Context + { + Diagnostics* diagnostics; + + Input input; + // The location where yytext points to. Token location should track + // scanLoc instead of Input::mReadLoc because they may not be the same + // if text is buffered up in the scanner input buffer. + Input::Location scanLoc; + + bool leadingSpace; + bool lineStart; + }; + + Tokenizer(Diagnostics* diagnostics); + ~Tokenizer(); + + bool init(int count, const char* const string[], const int length[]); + + void setFileNumber(int file); + void setLineNumber(int line); + + virtual void lex(Token* token); + + private: + PP_DISALLOW_COPY_AND_ASSIGN(Tokenizer); + bool initScanner(); + void destroyScanner(); + + void* mHandle; // Scanner handle. + Context mContext; // Scanner extra. +}; + +} // namespace pp +#endif // COMPILER_PREPROCESSOR_TOKENIZER_H_ + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Tokenizer.l b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Tokenizer.l new file mode 100644 index 000000000..401c7325b --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Tokenizer.l @@ -0,0 +1,329 @@ +/* +// +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +This file contains the Lex specification for GLSL ES preprocessor. +Based on Microsoft Visual Studio 2010 Preprocessor Grammar: +http://msdn.microsoft.com/en-us/library/2scxys89.aspx + +IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. +*/ + +%top{ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// This file is auto-generated by generate_parser.sh. DO NOT EDIT! +} + +%{ +#include "Tokenizer.h" + +#include "Diagnostics.h" +#include "Token.h" + +#if defined(__GNUC__) +// Triggered by the auto-generated yy_fatal_error function. +#pragma GCC diagnostic ignored "-Wmissing-noreturn" +#endif + +typedef std::string YYSTYPE; +typedef pp::SourceLocation YYLTYPE; + +// Use the unused yycolumn variable to track file (string) number. +#define yyfileno yycolumn + +#define YY_USER_INIT \ + do { \ + yyfileno = 0; \ + yylineno = 1; \ + yyextra->leadingSpace = false; \ + yyextra->lineStart = true; \ + } while(0); + +#define YY_USER_ACTION \ + do \ + { \ + pp::Input* input = &yyextra->input; \ + pp::Input::Location* scanLoc = &yyextra->scanLoc; \ + while ((scanLoc->sIndex < input->count()) && \ + (scanLoc->cIndex >= input->length(scanLoc->sIndex))) \ + { \ + scanLoc->cIndex -= input->length(scanLoc->sIndex++); \ + ++yyfileno; yylineno = 1; \ + } \ + yylloc->file = yyfileno; \ + yylloc->line = yylineno; \ + scanLoc->cIndex += yyleng; \ + } while(0); + +#define YY_INPUT(buf, result, maxSize) \ + result = yyextra->input.read(buf, maxSize); + +%} + +%option noyywrap nounput never-interactive +%option reentrant bison-bridge bison-locations +%option prefix="pp" +%option extra-type="pp::Tokenizer::Context*" +%x COMMENT + +NEWLINE \n|\r|\r\n +IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]* +PUNCTUATOR [][<>(){}.+-/*%^|&~=!:;,?] + +DECIMAL_CONSTANT [1-9][0-9]* +OCTAL_CONSTANT 0[0-7]* +HEXADECIMAL_CONSTANT 0[xX][0-9a-fA-F]+ + +DIGIT [0-9] +EXPONENT_PART [eE][+-]?{DIGIT}+ +FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") + +%% + + /* Line comment */ +"//"[^\r\n]* + + /* Block comment */ + /* Line breaks are just counted - not returned. */ + /* The comment is replaced by a single space. */ +"/*" { BEGIN(COMMENT); } +<COMMENT>[^*\r\n]+ +<COMMENT>"*" +<COMMENT>{NEWLINE} { ++yylineno; } +<COMMENT>"*/" { + yyextra->leadingSpace = true; + BEGIN(INITIAL); +} + +# { + // # is only valid at start of line for preprocessor directives. + yylval->assign(1, yytext[0]); + return yyextra->lineStart ? pp::Token::PP_HASH : pp::Token::PP_OTHER; +} + +{IDENTIFIER} { + yylval->assign(yytext, yyleng); + return pp::Token::IDENTIFIER; +} + +{DECIMAL_CONSTANT}|{OCTAL_CONSTANT}|{HEXADECIMAL_CONSTANT} { + yylval->assign(yytext, yyleng); + return pp::Token::CONST_INT; +} + +({DIGIT}+{EXPONENT_PART})|({FRACTIONAL_CONSTANT}{EXPONENT_PART}?) { + yylval->assign(yytext, yyleng); + return pp::Token::CONST_FLOAT; +} + + /* Anything that starts with a {DIGIT} or .{DIGIT} must be a number. */ + /* Rule to catch all invalid integers and floats. */ +({DIGIT}+[_a-zA-Z0-9.]*)|("."{DIGIT}+[_a-zA-Z0-9.]*) { + yylval->assign(yytext, yyleng); + return pp::Token::PP_NUMBER; +} + +"++" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_INC; +} +"--" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_DEC; +} +"<<" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_LEFT; +} +">>" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_RIGHT; +} +"<=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_LE; +} +">=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_GE; +} +"==" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_EQ; +} +"!=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_NE; +} +"&&" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_AND; +} +"^^" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_XOR; +} +"||" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_OR; +} +"+=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_ADD_ASSIGN; +} +"-=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_SUB_ASSIGN; +} +"*=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_MUL_ASSIGN; +} +"/=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_DIV_ASSIGN; +} +"%=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_MOD_ASSIGN; +} +"<<=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_LEFT_ASSIGN; +} +">>=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_RIGHT_ASSIGN; +} +"&=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_AND_ASSIGN; +} +"^=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_XOR_ASSIGN; +} +"|=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_OR_ASSIGN; +} + +{PUNCTUATOR} { + yylval->assign(1, yytext[0]); + return yytext[0]; +} + +[ \t\v\f]+ { yyextra->leadingSpace = true; } + +{NEWLINE} { + ++yylineno; + yylval->assign(1, '\n'); + return '\n'; +} + +. { + yylval->assign(1, yytext[0]); + return pp::Token::PP_OTHER; +} + +<*><<EOF>> { + // YY_USER_ACTION is not invoked for handling EOF. + // Set the location for EOF token manually. + pp::Input* input = &yyextra->input; + pp::Input::Location* scanLoc = &yyextra->scanLoc; + int sIndexMax = std::max(0, input->count() - 1); + if (scanLoc->sIndex != sIndexMax) + { + // We can only reach here if there are empty strings at the + // end of the input. + scanLoc->sIndex = sIndexMax; scanLoc->cIndex = 0; + yyfileno = sIndexMax; yylineno = 1; + } + yylloc->file = yyfileno; + yylloc->line = yylineno; + yylval->clear(); + + if (YY_START == COMMENT) + { + yyextra->diagnostics->report(pp::Diagnostics::EOF_IN_COMMENT, + pp::SourceLocation(yyfileno, yylineno), + ""); + } + yyterminate(); +} + +%% + +namespace pp { + +Tokenizer::Tokenizer(Diagnostics* diagnostics) : mHandle(0) +{ + mContext.diagnostics = diagnostics; +} + +Tokenizer::~Tokenizer() +{ + destroyScanner(); +} + +bool Tokenizer::init(int count, const char* const string[], const int length[]) +{ + if (count < 0) return false; + if ((count > 0) && (string == 0)) return false; + + mContext.input = Input(count, string, length); + return initScanner(); +} + +void Tokenizer::setFileNumber(int file) +{ + // We use column number as file number. + // See macro yyfileno. + yyset_column(file, mHandle); +} + +void Tokenizer::setLineNumber(int line) +{ + yyset_lineno(line, mHandle); +} + +void Tokenizer::lex(Token* token) +{ + token->type = yylex(&token->value, &token->location, mHandle); + token->flags = 0; + + token->setAtStartOfLine(mContext.lineStart); + mContext.lineStart = token->type == '\n'; + + token->setHasLeadingSpace(mContext.leadingSpace); + mContext.leadingSpace = false; +} + +bool Tokenizer::initScanner() +{ + if ((mHandle == NULL) && yylex_init_extra(&mContext, &mHandle)) + return false; + + yyrestart(0, mHandle); + return true; +} + +void Tokenizer::destroyScanner() +{ + if (mHandle == NULL) + return; + + yylex_destroy(mHandle); + mHandle = NULL; +} + +} // namespace pp + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/generate_parser.sh b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/generate_parser.sh index 5b32f71ac..e9c70b13b 100755 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/generate_parser.sh +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/generate_parser.sh @@ -1,27 +1,26 @@ #!/bin/bash -# Copyright (c) 2010 The ANGLE Project Authors. All rights reserved. +# Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -# Generates GLSL ES preprocessor - pp_lex.cpp, pp_tab.h, and pp_tab.cpp +# Generates various components of GLSL ES preprocessor. run_flex() { -input_file=$script_dir/$1.l -output_source=$script_dir/$1_lex.cpp +input_file=$script_dir/$1 +output_source=$script_dir/$2 flex --noline --nounistd --outfile=$output_source $input_file } run_bison() { -input_file=$script_dir/$1.y -output_header=$script_dir/$1_tab.h -output_source=$script_dir/$1_tab.cpp -bison --no-lines --skeleton=yacc.c --defines=$output_header --output=$output_source $input_file +input_file=$script_dir/$1 +output_source=$script_dir/$2 +bison --no-lines --skeleton=yacc.c --output=$output_source $input_file } script_dir=$(dirname $0) # Generate preprocessor -run_flex pp -run_bison pp +run_flex Tokenizer.l Tokenizer.cpp +run_bison ExpressionParser.y ExpressionParser.cpp diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/new_file.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/new_file.cpp new file mode 100644 index 000000000..0aa5fd849 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/new_file.cpp @@ -0,0 +1 @@ + Some new code that uses tabs
\ No newline at end of file diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/new_file2.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/new_file2.cpp new file mode 100644 index 000000000..d0e16df77 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/new_file2.cpp @@ -0,0 +1 @@ +some other file diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp.l b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp.l deleted file mode 100644 index 627ca04b2..000000000 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp.l +++ /dev/null @@ -1,181 +0,0 @@ -/* -// -// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -This file contains the Lex specification for GLSL ES preprocessor. -Based on Microsoft Visual Studio 2010 Preprocessor Grammar: -http://msdn.microsoft.com/en-us/library/2scxys89.aspx - -IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. -*/ - -%top{ -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// This file is auto-generated by generate_parser.sh. DO NOT EDIT! -} - -%{ -#include "compiler/debug.h" -#include "Context.h" -#include "pp_tab.h" - -#define YY_USER_ACTION \ - do { \ - yylloc->first_line = yylineno; \ - yylloc->first_column = yycolumn + 1; \ - yycolumn += yyleng; \ - } while(0); - -#define YY_INPUT(buf, result, maxSize) \ - result = yyextra->readInput(buf, maxSize); - -static std::string* extractMacroName(const char* str, int len); -%} - -%option noyywrap nounput never-interactive -%option yylineno reentrant bison-bridge bison-locations -%option stack -%option prefix="pp" -%option extra-type="pp::Context*" - -HSPACE [ \t] -HASH ^{HSPACE}*#{HSPACE}* -IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]* -PUNCTUATOR [][<>(){}.+-/*%^|&~=!:;,?] - -DECIMAL_CONSTANT [1-9][0-9]* -OCTAL_CONSTANT 0[0-7]* -HEXADECIMAL_CONSTANT 0[xX][0-9a-fA-F]+ - -DIGIT [0-9] -EXPONENT_PART [eE][+-]?{DIGIT}+ -FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") - -%% - -{HASH} { return HASH; } - -{HASH}define{HSPACE}+{IDENTIFIER}/[ \t\n] { - yylval->sval = extractMacroName(yytext, yyleng); - return HASH_DEFINE_OBJ; -} -{HASH}define{HSPACE}+{IDENTIFIER}/"(" { - yylval->sval = extractMacroName(yytext, yyleng); - return HASH_DEFINE_FUNC; -} -{HASH}undef{HSPACE}+ { return HASH_UNDEF; } - -{HASH}if { return HASH_IF; } -{HASH}ifdef { return HASH_IFDEF; } -{HASH}ifndef { return HASH_IFNDEF; } -{HASH}else { return HASH_ELSE; } -{HASH}elif { return HASH_ELIF; } -{HASH}endif { return HASH_ENDIF; } -"defined" { return DEFINED; } - -{HASH}error { return HASH_ERROR; } -{HASH}pragma { return HASH_PRAGMA; } -{HASH}extension { return HASH_EXTENSION; } -{HASH}version { return HASH_VERSION; } -{HASH}line { return HASH_LINE; } - -{IDENTIFIER} { - yylval->sval = new std::string(yytext, yyleng); - return IDENTIFIER; -} - -{DECIMAL_CONSTANT}|{OCTAL_CONSTANT}|{HEXADECIMAL_CONSTANT} { - yylval->sval = new std::string(yytext, yyleng); - return INT_CONSTANT; -} - -({DIGIT}+{EXPONENT_PART})|({FRACTIONAL_CONSTANT}{EXPONENT_PART}?) { - yylval->sval = new std::string(yytext, yyleng); - return FLOAT_CONSTANT; -} - -{PUNCTUATOR} { return yytext[0]; } - -[ \t\v\f]+ { /* Ignore whitespace */ } - -\n { - ++yylineno; yycolumn = 0; - return yytext[0]; -} - -<*><<EOF>> { yyterminate(); } - -%% - -std::string* extractMacroName(const char* str, int len) -{ - // The input string is of the form {HASH}define{HSPACE}+{IDENTIFIER} - // We just need to find the last HSPACE. - ASSERT(str && (len > 8)); // strlen("#define ") == 8; - - std::string* name = NULL; - for (int i = len - 1; i >= 0; --i) - { - if ((str[i] == ' ') || (str[i] == '\t')) - { - name = new std::string(str + i + 1, len - i - 1); - break; - } - } - ASSERT(name); - return name; -} - -namespace pp { - -int Context::readInput(char* buf, int maxSize) -{ - int nread = YY_NULL; - while (!mInput->eof() && - (mInput->error() == pp::Input::kErrorNone) && - (nread == YY_NULL)) - { - int line = 0, file = 0; - pp::Token::decodeLocation(yyget_lineno(mLexer), &line, &file); - file = mInput->stringIndex(); - yyset_lineno(pp::Token::encodeLocation(line, file), mLexer); - - nread = mInput->read(buf, maxSize); - - if (mInput->error() == pp::Input::kErrorUnexpectedEOF) - { - // TODO(alokp): Report error. - } - } - return nread; -} - -bool Context::initLexer() -{ - ASSERT(mLexer == NULL); - - if (yylex_init_extra(this, &mLexer)) - return false; - - yyrestart(0, mLexer); - return true; -} - -void Context::destroyLexer() -{ - ASSERT(mLexer); - - yylex_destroy(mLexer); - mLexer = NULL; -} - -} // namespace pp - diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp.y b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp.y deleted file mode 100644 index 55193abfc..000000000 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp.y +++ /dev/null @@ -1,225 +0,0 @@ -/* -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -This file contains the Yacc grammar for GLSL ES preprocessor. -Based on Microsoft Visual Studio 2010 Preprocessor Grammar: -http://msdn.microsoft.com/en-us/library/2scxys89.aspx - -IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_glsl_parser.sh, -WHICH GENERATES THE GLSL ES PARSER. -*/ - -%{ -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT! - -#include "Context.h" - -#define YYLEX_PARAM context->lexer() -#define YYDEBUG 1 -%} - -%pure-parser -%name-prefix="pp" -%locations -%parse-param {pp::Context* context} - -%union { - int ival; - std::string* sval; - pp::Token* tval; - pp::TokenVector* tlist; -} - -%{ -extern int yylex(YYSTYPE* lvalp, YYLTYPE* llocp, void* lexer); -static void yyerror(YYLTYPE* llocp, - pp::Context* context, - const char* reason); - -static void pushConditionalBlock(pp::Context* context, bool condition); -static void popConditionalBlock(pp::Context* context); -%} - -%token HASH HASH_UNDEF -%token HASH_IF HASH_IFDEF HASH_IFNDEF HASH_ELSE HASH_ELIF HASH_ENDIF DEFINED -%token HASH_ERROR HASH_PRAGMA HASH_EXTENSION HASH_VERSION HASH_LINE -%token <sval> HASH_DEFINE_OBJ HASH_DEFINE_FUNC -%token <sval> INT_CONSTANT FLOAT_CONSTANT IDENTIFIER -%type <ival> operator -%type <tval> conditional_token token -%type <tlist> parameter_list replacement_list conditional_list token_list -%% - -input - : /* empty */ - | input line -; - -line - : text_line - | control_line -; - -text_line - : '\n' - | token_list '\n' { - // TODO(alokp): Expand macros. - pp::TokenVector* out = context->output(); - out->insert(out->end(), $1->begin(), $1->end()); - delete $1; - } -; - -control_line - : HASH '\n' - | HASH_DEFINE_OBJ replacement_list '\n' { - context->defineMacro(@1.first_line, pp::Macro::kTypeObj, $1, NULL, $2); - } - | HASH_DEFINE_FUNC '(' parameter_list ')' replacement_list '\n' { - context->defineMacro(@1.first_line, pp::Macro::kTypeFunc, $1, $3, $5); - } - | HASH_UNDEF IDENTIFIER '\n' { - context->undefineMacro($2); - } - | HASH_IF conditional_list '\n' { - pushConditionalBlock(context, $2 ? true : false); - } - | HASH_IFDEF IDENTIFIER '\n' { - pushConditionalBlock(context, context->isMacroDefined($2)); - } - | HASH_IFNDEF IDENTIFIER '\n' { - pushConditionalBlock(context, !context->isMacroDefined($2)); - } - | HASH_ELIF conditional_list '\n' { - } - | HASH_ELSE '\n' { - } - | HASH_ENDIF '\n' { - popConditionalBlock(context); - } - | HASH_ERROR '\n' - | HASH_PRAGMA '\n' - | HASH_EXTENSION '\n' - | HASH_VERSION '\n' - | HASH_LINE '\n' -; - -replacement_list - : /* empty */ { $$ = NULL; } - | token_list - -parameter_list - : /* empty */ { $$ = NULL; } - | IDENTIFIER { - $$ = new pp::TokenVector; - $$->push_back(new pp::Token(@1.first_line, IDENTIFIER, $1)); - } - | parameter_list ',' IDENTIFIER { - $$ = $1; - $$->push_back(new pp::Token(@3.first_line, IDENTIFIER, $3)); - } - -conditional_list - : conditional_token { - $$ = new pp::TokenVector; - $$->push_back($1); - } - | conditional_list conditional_token { - $$ = $1; - $$->push_back($2); - } -; - -token_list - : token { - $$ = new pp::TokenVector; - $$->push_back($1); - } - | token_list token { - $$ = $1; - $$->push_back($2); - } -; - -conditional_token - : DEFINED IDENTIFIER { - } - | DEFINED '(' IDENTIFIER ')' { - } - | token -; - -token - : operator { - $$ = new pp::Token(@1.first_line, $1, NULL); - } - | INT_CONSTANT { - $$ = new pp::Token(@1.first_line, INT_CONSTANT, $1); - } - | FLOAT_CONSTANT { - $$ = new pp::Token(@1.first_line, FLOAT_CONSTANT, $1); - } - | IDENTIFIER { - $$ = new pp::Token(@1.first_line, IDENTIFIER, $1); - } -; - -operator - : '[' { $$ = '['; } - | ']' { $$ = ']'; } - | '<' { $$ = '<'; } - | '>' { $$ = '>'; } - | '(' { $$ = '('; } - | ')' { $$ = ')'; } - | '{' { $$ = '{'; } - | '}' { $$ = '}'; } - | '.' { $$ = '.'; } - | '+' { $$ = '+'; } - | '-' { $$ = '-'; } - | '/' { $$ = '/'; } - | '*' { $$ = '*'; } - | '%' { $$ = '%'; } - | '^' { $$ = '^'; } - | '|' { $$ = '|'; } - | '&' { $$ = '&'; } - | '~' { $$ = '~'; } - | '=' { $$ = '='; } - | '!' { $$ = '!'; } - | ':' { $$ = ':'; } - | ';' { $$ = ';'; } - | ',' { $$ = ','; } - | '?' { $$ = '?'; } -; - -%% - -void yyerror(YYLTYPE* llocp, pp::Context* context, const char* reason) -{ -} - -void pushConditionalBlock(pp::Context* context, bool condition) -{ -} - -void popConditionalBlock(pp::Context* context) -{ -} - -namespace pp { -bool Context::parse() -{ - yydebug = 1; - return yyparse(this) == 0 ? true : false; -} -} // namespace pp - diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_lex.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_lex.cpp deleted file mode 100644 index 717e7ccd0..000000000 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_lex.cpp +++ /dev/null @@ -1,2268 +0,0 @@ -#line 16 "compiler/preprocessor/new/pp.l" -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// This file is auto-generated by generate_parser.sh. DO NOT EDIT! - - - -#line 13 "compiler/preprocessor/new/pp_lex.cpp" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include <inttypes.h> -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* An opaque pointer. */ -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -/* For convenience, these vars (plus the bison vars far below) - are macros in the reentrant scanner. */ -#define yyin yyg->yyin_r -#define yyout yyg->yyout_r -#define yyextra yyg->yyextra_r -#define yyleng yyg->yyleng_r -#define yytext yyg->yytext_r -#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) -#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) -#define yy_flex_debug yyg->yy_flex_debug_r - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yyg->yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yyg->yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE pprestart(yyin ,yyscanner ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires - * access to the local variable yy_act. Since yyless() is a macro, it would break - * existing scanners that call yyless() from OUTSIDE pplex. - * One obvious solution it to make yy_act a global. I tried that, and saw - * a 5% performance hit in a non-yylineno scanner, because yy_act is - * normally declared as a register variable-- so it is not worth it. - */ - #define YY_LESS_LINENO(n) \ - do { \ - int yyl;\ - for ( yyl = n; yyl < yyleng; ++yyl )\ - if ( yytext[yyl] == '\n' )\ - --yylineno;\ - }while(0) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = yyg->yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via pprestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ - ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] - -void pprestart (FILE *input_file ,yyscan_t yyscanner ); -void pp_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE pp_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void pp_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void pp_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void pppush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void pppop_buffer_state (yyscan_t yyscanner ); - -static void ppensure_buffer_stack (yyscan_t yyscanner ); -static void pp_load_buffer_state (yyscan_t yyscanner ); -static void pp_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); - -#define YY_FLUSH_BUFFER pp_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) - -YY_BUFFER_STATE pp_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE pp_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE pp_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); - -void *ppalloc (yy_size_t ,yyscan_t yyscanner ); -void *pprealloc (void *,yy_size_t ,yyscan_t yyscanner ); -void ppfree (void * ,yyscan_t yyscanner ); - -#define yy_new_buffer pp_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - ppensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - ppensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -#define ppwrap(n) 1 -#define YY_SKIP_YYWRAP - -typedef unsigned char YY_CHAR; - -typedef int yy_state_type; - -#define yytext_ptr yytext_r - -static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); -static int yy_get_next_buffer (yyscan_t yyscanner ); -static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yyg->yytext_ptr = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ - yyg->yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yyg->yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 23 -#define YY_END_OF_BUFFER 24 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[105] = - { 0, - 0, 0, 24, 23, 21, 22, 20, 20, 18, 18, - 17, 17, 21, 1, 21, 19, 19, 18, 0, 0, - 0, 18, 17, 17, 21, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 19, 18, 17, 0, - 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, - 19, 17, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 17, 0, 9, 8, 0, 0, - 0, 0, 0, 16, 0, 0, 0, 17, 0, 10, - 12, 0, 6, 0, 0, 0, 0, 11, 0, 0, - 7, 13, 4, 0, 0, 0, 15, 0, 0, 2, - - 3, 0, 14, 0 - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 5, 1, 6, 1, 5, 5, 1, 7, - 5, 5, 8, 5, 8, 9, 5, 10, 11, 11, - 11, 11, 11, 11, 11, 12, 12, 5, 5, 5, - 5, 5, 5, 1, 13, 13, 13, 13, 14, 13, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 16, 15, 15, - 5, 1, 5, 5, 15, 1, 17, 13, 13, 18, - - 19, 20, 21, 15, 22, 15, 15, 23, 24, 25, - 26, 27, 15, 28, 29, 30, 31, 32, 15, 33, - 15, 15, 5, 5, 5, 5, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int32_t yy_meta[34] = - { 0, - 1, 2, 3, 1, 1, 1, 3, 1, 1, 4, - 4, 4, 5, 6, 7, 7, 5, 5, 6, 5, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7 - } ; - -static yyconst flex_int16_t yy_base[111] = - { 0, - 0, 18, 184, 185, 11, 185, 185, 21, 28, 53, - 0, 164, 39, 71, 12, 32, 34, 1, 39, 44, - 0, 0, 0, 162, 64, 0, 0, 162, 46, 160, - 157, 150, 152, 157, 70, 47, 65, 0, 153, 154, - 62, 155, 144, 141, 67, 145, 152, 150, 139, 76, - 85, 141, 143, 144, 144, 140, 135, 141, 140, 140, - 138, 135, 136, 125, 134, 127, 185, 185, 131, 122, - 124, 128, 128, 185, 122, 125, 122, 125, 123, 185, - 185, 112, 185, 120, 113, 127, 97, 0, 107, 86, - 185, 185, 105, 76, 81, 34, 185, 97, 10, 185, - - 185, 103, 185, 185, 110, 114, 118, 121, 126, 132 - } ; - -static yyconst flex_int16_t yy_def[111] = - { 0, - 105, 105, 104, 104, 104, 104, 104, 104, 104, 104, - 106, 106, 104, 104, 104, 107, 107, 9, 18, 104, - 108, 10, 106, 106, 104, 14, 14, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 108, 106, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 106, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 106, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 106, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 106, 104, 104, - 104, 104, 104, 104, 109, 104, 104, 110, 104, 104, - - 104, 110, 104, 0, 104, 104, 104, 104, 104, 104 - } ; - -static yyconst flex_int16_t yy_nxt[219] = - { 0, - 4, 5, 6, 5, 7, 4, 7, 7, 8, 9, - 10, 10, 15, 15, 15, 15, 104, 12, 4, 13, - 6, 5, 7, 14, 7, 7, 8, 9, 10, 10, - 16, 16, 16, 104, 103, 12, 17, 18, 18, 19, - 25, 20, 15, 21, 26, 35, 20, 35, 19, 19, - 35, 36, 35, 37, 37, 37, 37, 37, 37, 99, - 21, 17, 22, 22, 22, 25, 20, 15, 41, 26, - 42, 20, 27, 43, 37, 37, 37, 50, 44, 51, - 51, 51, 95, 54, 59, 51, 51, 51, 28, 29, - 55, 60, 30, 31, 51, 51, 51, 32, 100, 100, - - 97, 33, 34, 101, 100, 100, 93, 96, 95, 101, - 11, 11, 11, 11, 11, 11, 11, 23, 23, 23, - 23, 16, 94, 16, 38, 38, 38, 98, 93, 92, - 98, 98, 98, 102, 102, 102, 102, 102, 102, 91, - 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, - 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, - 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, - 58, 57, 56, 53, 52, 49, 48, 47, 46, 45, - 40, 39, 24, 104, 3, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104 - } ; - -static yyconst flex_int16_t yy_chk[219] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 5, 15, 5, 15, 18, 1, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 8, 8, 8, 18, 99, 2, 9, 9, 9, 9, - 13, 9, 13, 9, 13, 16, 9, 17, 19, 19, - 16, 20, 17, 20, 20, 20, 36, 36, 36, 96, - 9, 10, 10, 10, 10, 25, 10, 25, 29, 25, - 29, 10, 14, 29, 37, 37, 37, 35, 29, 35, - 35, 35, 95, 41, 45, 50, 50, 50, 14, 14, - 41, 45, 14, 14, 51, 51, 51, 14, 98, 98, - - 94, 14, 14, 98, 102, 102, 93, 90, 89, 102, - 105, 105, 105, 105, 105, 105, 105, 106, 106, 106, - 106, 107, 87, 107, 108, 108, 108, 109, 86, 85, - 109, 109, 109, 110, 110, 110, 110, 110, 110, 84, - 82, 79, 78, 77, 76, 75, 73, 72, 71, 70, - 69, 66, 65, 64, 63, 62, 61, 60, 59, 58, - 57, 56, 55, 54, 53, 52, 49, 48, 47, 46, - 44, 43, 42, 40, 39, 34, 33, 32, 31, 30, - 28, 24, 12, 3, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104 - } ; - -/* Table of booleans, true if rule could match eol. */ -static yyconst flex_int32_t yy_rule_can_match_eol[24] = - { 0, -0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, }; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -/* -// -// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -This file contains the Lex specification for GLSL ES preprocessor. -Based on Microsoft Visual Studio 2010 Preprocessor Grammar: -http://msdn.microsoft.com/en-us/library/2scxys89.aspx - -IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. -*/ - -#include "compiler/debug.h" -#include "Context.h" -#include "pp_tab.h" - -#define YY_USER_ACTION \ - do { \ - yylloc->first_line = yylineno; \ - yylloc->first_column = yycolumn + 1; \ - yycolumn += yyleng; \ - } while(0); - -#define YY_INPUT(buf, result, maxSize) \ - result = yyextra->readInput(buf, maxSize); - -static std::string* extractMacroName(const char* str, int len); - -#define INITIAL 0 - -#define YY_EXTRA_TYPE pp::Context* - -/* Holds the entire state of the reentrant scanner. */ -struct yyguts_t - { - - /* User-defined. Not touched by flex. */ - YY_EXTRA_TYPE yyextra_r; - - /* The rest are the same as the globals declared in the non-reentrant scanner. */ - FILE *yyin_r, *yyout_r; - size_t yy_buffer_stack_top; /**< index of top of stack. */ - size_t yy_buffer_stack_max; /**< capacity of stack. */ - YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ - char yy_hold_char; - int yy_n_chars; - int yyleng_r; - char *yy_c_buf_p; - int yy_init; - int yy_start; - int yy_did_buffer_switch_on_eof; - int yy_start_stack_ptr; - int yy_start_stack_depth; - int *yy_start_stack; - yy_state_type yy_last_accepting_state; - char* yy_last_accepting_cpos; - - int yylineno_r; - int yy_flex_debug_r; - - char *yytext_r; - int yy_more_flag; - int yy_more_len; - - YYSTYPE * yylval_r; - - YYLTYPE * yylloc_r; - - }; /* end struct yyguts_t */ - -static int yy_init_globals (yyscan_t yyscanner ); - - /* This must go here because YYSTYPE and YYLTYPE are included - * from bison output in section 1.*/ - # define yylval yyg->yylval_r - - # define yylloc yyg->yylloc_r - -int pplex_init (yyscan_t* scanner); - -int pplex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int pplex_destroy (yyscan_t yyscanner ); - -int ppget_debug (yyscan_t yyscanner ); - -void ppset_debug (int debug_flag ,yyscan_t yyscanner ); - -YY_EXTRA_TYPE ppget_extra (yyscan_t yyscanner ); - -void ppset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); - -FILE *ppget_in (yyscan_t yyscanner ); - -void ppset_in (FILE * in_str ,yyscan_t yyscanner ); - -FILE *ppget_out (yyscan_t yyscanner ); - -void ppset_out (FILE * out_str ,yyscan_t yyscanner ); - -int ppget_leng (yyscan_t yyscanner ); - -char *ppget_text (yyscan_t yyscanner ); - -int ppget_lineno (yyscan_t yyscanner ); - -void ppset_lineno (int line_number ,yyscan_t yyscanner ); - -YYSTYPE * ppget_lval (yyscan_t yyscanner ); - -void ppset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); - - YYLTYPE *ppget_lloc (yyscan_t yyscanner ); - - void ppset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int ppwrap (yyscan_t yyscanner ); -#else -extern int ppwrap (yyscan_t yyscanner ); -#endif -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (yyscan_t yyscanner ); -#else -static int input (yyscan_t yyscanner ); -#endif - -#endif - - static void yy_push_state (int new_state ,yyscan_t yyscanner); - - static void yy_pop_state (yyscan_t yyscanner ); - - static int yy_top_state (yyscan_t yyscanner ); - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO fwrite( yytext, yyleng, 1, yyout ) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - int n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int pplex \ - (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); - -#define YY_DECL int pplex \ - (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - if ( yyleng > 0 ) \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ - (yytext[yyleng - 1] == '\n'); \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yylval = yylval_param; - - yylloc = yylloc_param; - - if ( !yyg->yy_init ) - { - yyg->yy_init = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yyg->yy_start ) - yyg->yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - ppensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - pp_load_buffer_state(yyscanner ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yyg->yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yyg->yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yyg->yy_start; - yy_current_state += YY_AT_BOL(); -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 105 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_current_state != 104 ); - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - - YY_DO_BEFORE_ACTION; - - if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) - { - int yyl; - for ( yyl = 0; yyl < yyleng; ++yyl ) - if ( yytext[yyl] == '\n' ) - - do{ yylineno++; - yycolumn=0; - }while(0) -; - } - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yyg->yy_hold_char; - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; - -case 1: -YY_RULE_SETUP -{ return HASH; } - YY_BREAK -case 2: -/* rule 2 can match eol */ -*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ -yyg->yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -{ - yylval->sval = extractMacroName(yytext, yyleng); - return HASH_DEFINE_OBJ; -} - YY_BREAK -case 3: -*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ -yyg->yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -{ - yylval->sval = extractMacroName(yytext, yyleng); - return HASH_DEFINE_FUNC; -} - YY_BREAK -case 4: -YY_RULE_SETUP -{ return HASH_UNDEF; } - YY_BREAK -case 5: -YY_RULE_SETUP -{ return HASH_IF; } - YY_BREAK -case 6: -YY_RULE_SETUP -{ return HASH_IFDEF; } - YY_BREAK -case 7: -YY_RULE_SETUP -{ return HASH_IFNDEF; } - YY_BREAK -case 8: -YY_RULE_SETUP -{ return HASH_ELSE; } - YY_BREAK -case 9: -YY_RULE_SETUP -{ return HASH_ELIF; } - YY_BREAK -case 10: -YY_RULE_SETUP -{ return HASH_ENDIF; } - YY_BREAK -case 11: -YY_RULE_SETUP -{ return DEFINED; } - YY_BREAK -case 12: -YY_RULE_SETUP -{ return HASH_ERROR; } - YY_BREAK -case 13: -YY_RULE_SETUP -{ return HASH_PRAGMA; } - YY_BREAK -case 14: -YY_RULE_SETUP -{ return HASH_EXTENSION; } - YY_BREAK -case 15: -YY_RULE_SETUP -{ return HASH_VERSION; } - YY_BREAK -case 16: -YY_RULE_SETUP -{ return HASH_LINE; } - YY_BREAK -case 17: -YY_RULE_SETUP -{ - yylval->sval = new std::string(yytext, yyleng); - return IDENTIFIER; -} - YY_BREAK -case 18: -YY_RULE_SETUP -{ - yylval->sval = new std::string(yytext, yyleng); - return INT_CONSTANT; -} - YY_BREAK -case 19: -YY_RULE_SETUP -{ - yylval->sval = new std::string(yytext, yyleng); - return FLOAT_CONSTANT; -} - YY_BREAK -case 20: -YY_RULE_SETUP -{ return yytext[0]; } - YY_BREAK -case 21: -YY_RULE_SETUP -{ /* Ignore whitespace */ } - YY_BREAK -case 22: -/* rule 22 can match eol */ -YY_RULE_SETUP -{ - ++yylineno; yycolumn = 0; - return yytext[0]; -} - YY_BREAK -case YY_STATE_EOF(INITIAL): -{ yyterminate(); } - YY_BREAK -case 23: -YY_RULE_SETUP -ECHO; - YY_BREAK - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yyg->yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * pplex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); - - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yyg->yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_END_OF_FILE: - { - yyg->yy_did_buffer_switch_on_eof = 0; - - if ( ppwrap(yyscanner ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = - yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yyg->yy_c_buf_p = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of pplex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = yyg->yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; - - else - { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - - int yy_c_buf_p_offset = - (int) (yyg->yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - pprealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, (size_t) num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - if ( yyg->yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - pprestart(yyin ,yyscanner); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) pprealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - yyg->yy_n_chars += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (yyscan_t yyscanner) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_current_state = yyg->yy_start; - yy_current_state += YY_AT_BOL(); - - for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 105 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) -{ - register int yy_is_jam; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ - register char *yy_cp = yyg->yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 105 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 104); - - return yy_is_jam ? 0 : yy_current_state; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (yyscan_t yyscanner) -#else - static int input (yyscan_t yyscanner) -#endif - -{ - int c; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - *yyg->yy_c_buf_p = yyg->yy_hold_char; - - if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - /* This was really a NUL. */ - *yyg->yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; - ++yyg->yy_c_buf_p; - - switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - pprestart(yyin ,yyscanner); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( ppwrap(yyscanner ) ) - return EOF; - - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(yyscanner); -#else - return input(yyscanner); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = yyg->yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ - *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ - yyg->yy_hold_char = *++yyg->yy_c_buf_p; - - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); - if ( YY_CURRENT_BUFFER_LVALUE->yy_at_bol ) - - do{ yylineno++; - yycolumn=0; - }while(0) -; - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * @param yyscanner The scanner object. - * @note This function does not reset the start condition to @c INITIAL . - */ - void pprestart (FILE * input_file , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! YY_CURRENT_BUFFER ){ - ppensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - pp_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); - pp_load_buffer_state(yyscanner ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * @param yyscanner The scanner object. - */ - void pp_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* TODO. We should be able to replace this entire function body - * with - * pppop_buffer_state(); - * pppush_buffer_state(new_buffer); - */ - ppensure_buffer_stack (yyscanner); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - pp_load_buffer_state(yyscanner ); - - /* We don't actually know whether we did this switch during - * EOF (ppwrap()) processing, but the only time this flag - * is looked at is after ppwrap() is called, so it's safe - * to go ahead and always set it. - */ - yyg->yy_did_buffer_switch_on_eof = 1; -} - -static void pp_load_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - yyg->yy_hold_char = *yyg->yy_c_buf_p; -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * @param yyscanner The scanner object. - * @return the allocated buffer state. - */ - YY_BUFFER_STATE pp_create_buffer (FILE * file, int size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) ppalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in pp_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) ppalloc(b->yy_buf_size + 2 ,yyscanner ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in pp_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - pp_init_buffer(b,file ,yyscanner); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with pp_create_buffer() - * @param yyscanner The scanner object. - */ - void pp_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - ppfree((void *) b->yy_ch_buf ,yyscanner ); - - ppfree((void *) b ,yyscanner ); -} - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a pprestart() or at EOF. - */ - static void pp_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) - -{ - int oerrno = errno; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - pp_flush_buffer(b ,yyscanner); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then pp_init_buffer was _probably_ - * called from pprestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * @param yyscanner The scanner object. - */ - void pp_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - pp_load_buffer_state(yyscanner ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * @param yyscanner The scanner object. - */ -void pppush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (new_buffer == NULL) - return; - - ppensure_buffer_stack(yyscanner); - - /* This block is copied from pp_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - yyg->yy_buffer_stack_top++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from pp_switch_to_buffer. */ - pp_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * @param yyscanner The scanner object. - */ -void pppop_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (!YY_CURRENT_BUFFER) - return; - - pp_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); - YY_CURRENT_BUFFER_LVALUE = NULL; - if (yyg->yy_buffer_stack_top > 0) - --yyg->yy_buffer_stack_top; - - if (YY_CURRENT_BUFFER) { - pp_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void ppensure_buffer_stack (yyscan_t yyscanner) -{ - int num_to_alloc; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (!yyg->yy_buffer_stack) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - yyg->yy_buffer_stack = (struct yy_buffer_state**)ppalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in ppensure_buffer_stack()" ); - - memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - yyg->yy_buffer_stack_max = num_to_alloc; - yyg->yy_buffer_stack_top = 0; - return; - } - - if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = yyg->yy_buffer_stack_max + grow_size; - yyg->yy_buffer_stack = (struct yy_buffer_state**)pprealloc - (yyg->yy_buffer_stack, - num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in ppensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); - yyg->yy_buffer_stack_max = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE pp_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) ppalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in pp_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - pp_switch_to_buffer(b ,yyscanner ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to pplex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * pp_scan_bytes() instead. - */ -YY_BUFFER_STATE pp_scan_string (yyconst char * yystr , yyscan_t yyscanner) -{ - - return pp_scan_bytes(yystr,strlen(yystr) ,yyscanner); -} - -/** Setup the input buffer state to scan the given bytes. The next call to pplex() will - * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE pp_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) ppalloc(n ,yyscanner ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in pp_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = pp_scan_buffer(buf,n ,yyscanner); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in pp_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - - static void yy_push_state (int new_state , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( yyg->yy_start_stack_ptr >= yyg->yy_start_stack_depth ) - { - yy_size_t new_size; - - yyg->yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yyg->yy_start_stack_depth * sizeof( int ); - - if ( ! yyg->yy_start_stack ) - yyg->yy_start_stack = (int *) ppalloc(new_size ,yyscanner ); - - else - yyg->yy_start_stack = (int *) pprealloc((void *) yyg->yy_start_stack,new_size ,yyscanner ); - - if ( ! yyg->yy_start_stack ) - YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); - } - - yyg->yy_start_stack[yyg->yy_start_stack_ptr++] = YY_START; - - BEGIN(new_state); -} - - static void yy_pop_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( --yyg->yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); - - BEGIN(yyg->yy_start_stack[yyg->yy_start_stack_ptr]); -} - - static int yy_top_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyg->yy_start_stack[yyg->yy_start_stack_ptr - 1]; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = yyg->yy_hold_char; \ - yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ - yyg->yy_hold_char = *yyg->yy_c_buf_p; \ - *yyg->yy_c_buf_p = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the user-defined data for this scanner. - * @param yyscanner The scanner object. - */ -YY_EXTRA_TYPE ppget_extra (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyextra; -} - -/** Get the current line number. - * @param yyscanner The scanner object. - */ -int ppget_lineno (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yylineno; -} - -/** Get the current column number. - * @param yyscanner The scanner object. - */ -int ppget_column (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yycolumn; -} - -/** Get the input stream. - * @param yyscanner The scanner object. - */ -FILE *ppget_in (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyin; -} - -/** Get the output stream. - * @param yyscanner The scanner object. - */ -FILE *ppget_out (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyout; -} - -/** Get the length of the current token. - * @param yyscanner The scanner object. - */ -int ppget_leng (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyleng; -} - -/** Get the current token. - * @param yyscanner The scanner object. - */ - -char *ppget_text (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yytext; -} - -/** Set the user-defined data. This data is never touched by the scanner. - * @param user_defined The data to be associated with this scanner. - * @param yyscanner The scanner object. - */ -void ppset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyextra = user_defined ; -} - -/** Set the current line number. - * @param line_number - * @param yyscanner The scanner object. - */ -void ppset_lineno (int line_number , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* lineno is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "ppset_lineno called with no buffer" , yyscanner); - - yylineno = line_number; -} - -/** Set the current column. - * @param line_number - * @param yyscanner The scanner object. - */ -void ppset_column (int column_no , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* column is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "ppset_column called with no buffer" , yyscanner); - - yycolumn = column_no; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * @param yyscanner The scanner object. - * @see pp_switch_to_buffer - */ -void ppset_in (FILE * in_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyin = in_str ; -} - -void ppset_out (FILE * out_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyout = out_str ; -} - -int ppget_debug (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yy_flex_debug; -} - -void ppset_debug (int bdebug , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yy_flex_debug = bdebug ; -} - -/* Accessor methods for yylval and yylloc */ - -YYSTYPE * ppget_lval (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylval; -} - -void ppset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylval = yylval_param; -} - -YYLTYPE *ppget_lloc (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylloc; -} - -void ppset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylloc = yylloc_param; -} - -/* User-visible API */ - -/* pplex_init is special because it creates the scanner itself, so it is - * the ONLY reentrant function that doesn't take the scanner as the last argument. - * That's why we explicitly handle the declaration, instead of using our macros. - */ - -int pplex_init(yyscan_t* ptr_yy_globals) - -{ - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) ppalloc ( sizeof( struct yyguts_t ), NULL ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - return yy_init_globals ( *ptr_yy_globals ); -} - -/* pplex_init_extra has the same functionality as pplex_init, but follows the - * convention of taking the scanner as the last argument. Note however, that - * this is a *pointer* to a scanner, as it will be allocated by this call (and - * is the reason, too, why this function also must handle its own declaration). - * The user defined value in the first argument will be available to ppalloc in - * the yyextra field. - */ - -int pplex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) - -{ - struct yyguts_t dummy_yyguts; - - ppset_extra (yy_user_defined, &dummy_yyguts); - - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) ppalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in - yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - ppset_extra (yy_user_defined, *ptr_yy_globals); - - return yy_init_globals ( *ptr_yy_globals ); -} - -static int yy_init_globals (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from pplex_destroy(), so don't allocate here. - */ - - yyg->yy_buffer_stack = 0; - yyg->yy_buffer_stack_top = 0; - yyg->yy_buffer_stack_max = 0; - yyg->yy_c_buf_p = (char *) 0; - yyg->yy_init = 0; - yyg->yy_start = 0; - - yyg->yy_start_stack_ptr = 0; - yyg->yy_start_stack_depth = 0; - yyg->yy_start_stack = NULL; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = (FILE *) 0; - yyout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * pplex_init() - */ - return 0; -} - -/* pplex_destroy is for both reentrant and non-reentrant scanners. */ -int pplex_destroy (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - pp_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); - YY_CURRENT_BUFFER_LVALUE = NULL; - pppop_buffer_state(yyscanner); - } - - /* Destroy the stack itself. */ - ppfree(yyg->yy_buffer_stack ,yyscanner); - yyg->yy_buffer_stack = NULL; - - /* Destroy the start condition stack. */ - ppfree(yyg->yy_start_stack ,yyscanner ); - yyg->yy_start_stack = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * pplex() is called, initialization will occur. */ - yy_init_globals( yyscanner); - - /* Destroy the main struct (reentrant only). */ - ppfree ( yyscanner , yyscanner ); - yyscanner = NULL; - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *ppalloc (yy_size_t size , yyscan_t yyscanner) -{ - return (void *) malloc( size ); -} - -void *pprealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void ppfree (void * ptr , yyscan_t yyscanner) -{ - free( (char *) ptr ); /* see pprealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -std::string* extractMacroName(const char* str, int len) -{ - // The input string is of the form {HASH}define{HSPACE}+{IDENTIFIER} - // We just need to find the last HSPACE. - ASSERT(str && (len > 8)); // strlen("#define ") == 8; - - std::string* name = NULL; - for (int i = len - 1; i >= 0; --i) - { - if ((str[i] == ' ') || (str[i] == '\t')) - { - name = new std::string(str + i + 1, len - i - 1); - break; - } - } - ASSERT(name); - return name; -} - -namespace pp { - -int Context::readInput(char* buf, int maxSize) -{ - int nread = YY_NULL; - while (!mInput->eof() && - (mInput->error() == pp::Input::kErrorNone) && - (nread == YY_NULL)) - { - int line = 0, file = 0; - pp::Token::decodeLocation(ppget_lineno(mLexer), &line, &file); - file = mInput->stringIndex(); - ppset_lineno(pp::Token::encodeLocation(line, file),mLexer); - - nread = mInput->read(buf, maxSize); - - if (mInput->error() == pp::Input::kErrorUnexpectedEOF) - { - // TODO(alokp): Report error. - } - } - return nread; -} - -bool Context::initLexer() -{ - ASSERT(mLexer == NULL); - - if (pplex_init_extra(this,&mLexer)) - return false; - - pprestart(0,mLexer); - return true; -} - -void Context::destroyLexer() -{ - ASSERT(mLexer); - - pplex_destroy(mLexer); - mLexer = NULL; -} - -} // namespace pp - diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_tab.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_tab.h deleted file mode 100644 index 11ef80681..000000000 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_tab.h +++ /dev/null @@ -1,119 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.3. */ - -/* Skeleton interface for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - HASH = 258, - HASH_UNDEF = 259, - HASH_IF = 260, - HASH_IFDEF = 261, - HASH_IFNDEF = 262, - HASH_ELSE = 263, - HASH_ELIF = 264, - HASH_ENDIF = 265, - DEFINED = 266, - HASH_ERROR = 267, - HASH_PRAGMA = 268, - HASH_EXTENSION = 269, - HASH_VERSION = 270, - HASH_LINE = 271, - HASH_DEFINE_OBJ = 272, - HASH_DEFINE_FUNC = 273, - INT_CONSTANT = 274, - FLOAT_CONSTANT = 275, - IDENTIFIER = 276 - }; -#endif -/* Tokens. */ -#define HASH 258 -#define HASH_UNDEF 259 -#define HASH_IF 260 -#define HASH_IFDEF 261 -#define HASH_IFNDEF 262 -#define HASH_ELSE 263 -#define HASH_ELIF 264 -#define HASH_ENDIF 265 -#define DEFINED 266 -#define HASH_ERROR 267 -#define HASH_PRAGMA 268 -#define HASH_EXTENSION 269 -#define HASH_VERSION 270 -#define HASH_LINE 271 -#define HASH_DEFINE_OBJ 272 -#define HASH_DEFINE_FUNC 273 -#define INT_CONSTANT 274 -#define FLOAT_CONSTANT 275 -#define IDENTIFIER 276 - - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE - -{ - int ival; - std::string* sval; - pp::Token* tval; - pp::TokenVector* tlist; -} -/* Line 1489 of yacc.c. */ - - YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_utils.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_utils.h new file mode 100644 index 000000000..17164ea8b --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_utils.h @@ -0,0 +1,18 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// pp_utils.h: Common preprocessor utilities + +#ifndef COMPILER_PREPROCESSOR_PPUTILS_H_ +#define COMPILER_PREPROCESSOR_PPUTILS_H_ + +// A macro to disallow the copy constructor and operator= functions +// This must be used in the private: declarations for a class. +#define PP_DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) + +#endif // COMPILER_PREPROCESSOR_PPUTILS_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/preprocessor.vcproj b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/preprocessor.vcproj new file mode 100644 index 000000000..36a9759ad --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/preprocessor.vcproj @@ -0,0 +1,393 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="preprocessor" + ProjectGUID="{FBE32DF3-0FB0-4F2F-A424-2C21BD7BC325}" + RootNamespace="preprocessor" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + DebugInformationFormat="4" + DisableSpecificWarnings="4100;4127;4244;4702" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + DebugInformationFormat="3" + DisableSpecificWarnings="4100;4127;4244" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + DebugInformationFormat="3" + DisableSpecificWarnings="4100;4127;4244;4267;4702" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="4" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + DebugInformationFormat="3" + DisableSpecificWarnings="4100;4127;4244;4267" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\Diagnostics.cpp" + > + </File> + <File + RelativePath=".\DirectiveHandler.cpp" + > + </File> + <File + RelativePath=".\DirectiveParser.cpp" + > + </File> + <File + RelativePath=".\ExpressionParser.cpp" + > + </File> + <File + RelativePath=".\Input.cpp" + > + </File> + <File + RelativePath=".\Lexer.cpp" + > + </File> + <File + RelativePath=".\Macro.cpp" + > + </File> + <File + RelativePath=".\MacroExpander.cpp" + > + </File> + <File + RelativePath=".\Preprocessor.cpp" + > + </File> + <File + RelativePath=".\Token.cpp" + > + </File> + <File + RelativePath=".\Tokenizer.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\Diagnostics.h" + > + </File> + <File + RelativePath=".\DirectiveHandler.h" + > + </File> + <File + RelativePath=".\DirectiveParser.h" + > + </File> + <File + RelativePath=".\ExpressionParser.h" + > + </File> + <File + RelativePath=".\Input.h" + > + </File> + <File + RelativePath=".\Lexer.h" + > + </File> + <File + RelativePath=".\Macro.h" + > + </File> + <File + RelativePath=".\MacroExpander.h" + > + </File> + <File + RelativePath=".\pp_utils.h" + > + </File> + <File + RelativePath=".\Preprocessor.h" + > + </File> + <File + RelativePath=".\SourceLocation.h" + > + </File> + <File + RelativePath=".\Token.h" + > + </File> + <File + RelativePath=".\Tokenizer.h" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/stl_utils.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/stl_utils.h deleted file mode 100644 index 0d1ce5048..000000000 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/stl_utils.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// stl_utils.h: Common STL utilities. - -#ifndef COMMON_STLUTILS_H_ -#define COMMON_STLUTILS_H_ - -namespace pp -{ - -struct Delete -{ - template<class T> - void operator() (T x) { delete x; } -}; - -struct DeleteSecond -{ - template<class A, class B> - void operator() (std::pair<A, B>& x) { delete x.second; } -}; - -} // namespace pp -#endif // COMMON_STLUTILS_H_ - diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/token_type.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/token_type.h deleted file mode 100644 index 343a94190..000000000 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/token_type.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_PREPROCESSOR_TOKEN_TYPE_H_ -#define COMPILER_PREPROCESSOR_TOKEN_TYPE_H_ - -#include "pp_tab.h" - -#endif // COMPILER_PREPROCESSOR_TOKEN_TYPE_H_ - diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/preprocess.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/preprocess.h index 88d196ffe..15056da2c 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/preprocess.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/preprocess.h @@ -47,5 +47,4 @@ extern CPPStruct *cpp; int InitCPPStruct(void); int InitScanner(CPPStruct *cpp); int InitAtomTable(AtomTable *atable, int htsize); -int ScanFromString(const char *s); char* GetStringOfAtom(AtomTable *atable, int atom); diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c index 60b66bd29..fde853c1e 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c @@ -66,6 +66,8 @@ typedef struct StringInputSrc { char *p; } StringInputSrc; +static int ScanFromString(const char *s); + static int eof_scan(InputSrc *is, yystypepp * yylvalpp) { return EOF; @@ -73,7 +75,7 @@ static int eof_scan(InputSrc *is, yystypepp * yylvalpp) static void noop(InputSrc *in, int ch, yystypepp * yylvalpp) {} -static InputSrc eof_inputsrc = { 0, &eof_scan, &eof_scan, &noop }; +static InputSrc eof_inputsrc = { 0, &eof_scan, &eof_scan, &noop, 0, 0 }; static int byte_scan(InputSrc *, yystypepp * yylvalpp); @@ -126,6 +128,16 @@ int FreeScanner(void) return (FreeCPP()); } +int InitScannerInput(CPPStruct *cpp, int count, const char* const string[], const int length[]) +{ + cpp->PaWhichStr = 0; + cpp->PaArgv = string; + cpp->PaArgc = count; + cpp->PaStrLen = length; + ScanFromString(string[0]); + return 0; +} + /* * str_getch() * takes care of reading from multiple strings. diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.h index 233d1dc16..b67c1d644 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.h @@ -69,9 +69,9 @@ typedef struct InputSrc { } InputSrc; int InitScanner(CPPStruct *cpp); // Intialise the cpp scanner. -int ScanFromString(const char *); // Start scanning the input from the string mentioned. +int InitScannerInput(CPPStruct *cpp, int count, const char* const string[], const int length[]); int check_EOF(int); // check if we hit a EOF abruptly -void CPPErrorToInfoLog(char *); // sticking the msg,line into the Shader's.Info.log +void CPPErrorToInfoLog(const char *); // sticking the msg,line into the Shader's.Info.log void SetLineNumber(int); void SetStringNumber(int); void IncLineNumber(void); diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/symbols.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/symbols.h index c19f79c97..e7d0b075f 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/symbols.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/symbols.h @@ -105,7 +105,6 @@ Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind); Symbol *AddSymbol(SourceLoc *loc, Scope *fScope, int atom, symbolkind kind); Symbol *LookUpLocalSymbol(Scope *fScope, int atom); Symbol *LookUpSymbol(Scope *fScope, int atom); -void CPPErrorToInfoLog(char *); #endif // !defined(__SYMBOLS_H) diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.c b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.c index d658c12a4..b94c05ebd 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.c +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.c @@ -50,6 +50,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <string.h> #include <ctype.h> +#include "common/angleutils.h" #include "compiler/debug.h" #include "compiler/preprocessor/slglobals.h" #include "compiler/util.h" @@ -265,6 +266,8 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp) char string_val[MAX_STRING_LEN + 1]; int ltoken, len; char ch; + int base, accum; + char ch_val; ltoken = lReadByte(pTok); if (ltoken >= 0) { @@ -315,18 +318,41 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp) break; case CPP_INTCONSTANT: len = 0; + accum = 0; ch = lReadByte(pTok); - while ((ch >= '0' && ch <= '9')) - { - if (len < MAX_SYMBOL_NAME_LEN) { + if (ch == '0') { + symbol_name[len++] = ch; + ch = lReadByte(pTok); + if (ch == 'x' || ch == 'X') { symbol_name[len++] = ch; + base = 16; ch = lReadByte(pTok); + } else { + base = 8; } + } else { + base = 10; + } + + while (len < MAX_SYMBOL_NAME_LEN) + { + ch_val = -1; + if (isdigit(ch)) + ch_val = ch - '0'; + else if (isxdigit(ch)) + ch_val = tolower(ch) - 'a' + 10; + + if (ch_val < 0 || ch_val >= base) + break; + + symbol_name[len++] = ch; + accum = accum * base + ch_val; + ch = lReadByte(pTok); } symbol_name[len] = '\0'; assert(ch == '\0'); - strcpy(yylvalpp->symbol_name,symbol_name); - yylvalpp->sc_int=atoi(yylvalpp->symbol_name); + strcpy(yylvalpp->symbol_name, symbol_name); + yylvalpp->sc_int = accum; break; case '(': yylvalpp->sc_int = lReadByte(pTok); @@ -414,10 +440,10 @@ void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) { switch (token) { case CPP_IDENTIFIER: case CPP_TYPEIDENTIFIER: - sprintf(str, "%s ", GetAtomString(atable, yylvalpp->sc_ident)); + snprintf(str, sizeof(str), "%s ", GetAtomString(atable, yylvalpp->sc_ident)); break; case CPP_STRCONSTANT: - sprintf(str, "\"%s\"", GetAtomString(atable, yylvalpp->sc_ident)); + snprintf(str, sizeof(str), "\"%s\"", GetAtomString(atable, yylvalpp->sc_ident)); break; case CPP_FLOATCONSTANT: //printf("%g9.6 ", yylvalpp->sc_fval); @@ -427,9 +453,9 @@ void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) { break; default: if (token >= 127) - sprintf(str, "%s ", GetAtomString(atable, token)); + snprintf(str, sizeof(str), "%s ", GetAtomString(atable, token)); else - sprintf(str, "%c", token); + snprintf(str, sizeof(str), "%c", token); break; } CPPDebugLogMsg(str); diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.h index 8766df9e4..dbf4a2ccf 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.h @@ -48,6 +48,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #if !defined(__TOKENS_H) #define __TOKENS_H 1 +#include <stdio.h> #include "compiler/preprocessor/parser.h" #define EOF_SY (-1) diff --git a/Source/ThirdParty/ANGLE/src/compiler/timing/RestrictFragmentShaderTiming.cpp b/Source/ThirdParty/ANGLE/src/compiler/timing/RestrictFragmentShaderTiming.cpp new file mode 100644 index 000000000..538b731b8 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/timing/RestrictFragmentShaderTiming.cpp @@ -0,0 +1,127 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/InfoSink.h" +#include "compiler/ParseHelper.h" +#include "compiler/depgraph/DependencyGraphOutput.h" +#include "compiler/timing/RestrictFragmentShaderTiming.h" + +RestrictFragmentShaderTiming::RestrictFragmentShaderTiming(TInfoSinkBase& sink) + : mSink(sink) + , mNumErrors(0) +{ + // Sampling ops found only in fragment shaders. + mSamplingOps.insert("texture2D(s21;vf2;f1;"); + mSamplingOps.insert("texture2DProj(s21;vf3;f1;"); + mSamplingOps.insert("texture2DProj(s21;vf4;f1;"); + mSamplingOps.insert("textureCube(sC1;vf3;f1;"); + // Sampling ops found in both vertex and fragment shaders. + mSamplingOps.insert("texture2D(s21;vf2;"); + mSamplingOps.insert("texture2DProj(s21;vf3;"); + mSamplingOps.insert("texture2DProj(s21;vf4;"); + mSamplingOps.insert("textureCube(sC1;vf3;"); + // Sampling ops provided by OES_EGL_image_external. + mSamplingOps.insert("texture2D(1;vf2;"); + mSamplingOps.insert("texture2DProj(1;vf3;"); + mSamplingOps.insert("texture2DProj(1;vf4;"); + // Sampling ops provided by ARB_texture_rectangle. + mSamplingOps.insert("texture2DRect(1;vf2;"); + mSamplingOps.insert("texture2DRectProj(1;vf3;"); + mSamplingOps.insert("texture2DRectProj(1;vf4;"); +} + +// FIXME(mvujovic): We do not know if the execution time of built-in operations like sin, pow, etc. +// can vary based on the value of the input arguments. If so, we should restrict those as well. +void RestrictFragmentShaderTiming::enforceRestrictions(const TDependencyGraph& graph) +{ + mNumErrors = 0; + + // FIXME(mvujovic): The dependency graph does not support user defined function calls right now, + // so we generate errors for them. + validateUserDefinedFunctionCallUsage(graph); + + // Starting from each sampler, traverse the dependency graph and generate an error each time we + // hit a node where sampler dependent values are not allowed. + for (TGraphSymbolVector::const_iterator iter = graph.beginSamplerSymbols(); + iter != graph.endSamplerSymbols(); + ++iter) + { + TGraphSymbol* samplerSymbol = *iter; + clearVisited(); + samplerSymbol->traverse(this); + } +} + +void RestrictFragmentShaderTiming::validateUserDefinedFunctionCallUsage(const TDependencyGraph& graph) +{ + for (TFunctionCallVector::const_iterator iter = graph.beginUserDefinedFunctionCalls(); + iter != graph.endUserDefinedFunctionCalls(); + ++iter) + { + TGraphFunctionCall* functionCall = *iter; + beginError(functionCall->getIntermFunctionCall()); + mSink << "A call to a user defined function is not permitted.\n"; + } +} + +void RestrictFragmentShaderTiming::beginError(const TIntermNode* node) +{ + ++mNumErrors; + mSink.prefix(EPrefixError); + mSink.location(node->getLine()); +} + +bool RestrictFragmentShaderTiming::isSamplingOp(const TIntermAggregate* intermFunctionCall) const +{ + return !intermFunctionCall->isUserDefined() && + mSamplingOps.find(intermFunctionCall->getName()) != mSamplingOps.end(); +} + +void RestrictFragmentShaderTiming::visitArgument(TGraphArgument* parameter) +{ + // Texture cache access time might leak sensitive information. + // Thus, we restrict sampler dependent values from affecting the coordinate or LOD bias of a + // sampling operation. + if (isSamplingOp(parameter->getIntermFunctionCall())) { + switch (parameter->getArgumentNumber()) { + case 1: + // Second argument (coord) + beginError(parameter->getIntermFunctionCall()); + mSink << "An expression dependent on a sampler is not permitted to be the" + << " coordinate argument of a sampling operation.\n"; + break; + case 2: + // Third argument (bias) + beginError(parameter->getIntermFunctionCall()); + mSink << "An expression dependent on a sampler is not permitted to be the" + << " bias argument of a sampling operation.\n"; + break; + default: + // First argument (sampler) + break; + } + } +} + +void RestrictFragmentShaderTiming::visitSelection(TGraphSelection* selection) +{ + beginError(selection->getIntermSelection()); + mSink << "An expression dependent on a sampler is not permitted in a conditional statement.\n"; +} + +void RestrictFragmentShaderTiming::visitLoop(TGraphLoop* loop) +{ + beginError(loop->getIntermLoop()); + mSink << "An expression dependent on a sampler is not permitted in a loop condition.\n"; +} + +void RestrictFragmentShaderTiming::visitLogicalOp(TGraphLogicalOp* logicalOp) +{ + beginError(logicalOp->getIntermLogicalOp()); + mSink << "An expression dependent on a sampler is not permitted on the left hand side of a logical " + << logicalOp->getOpString() + << " operator.\n"; +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/timing/RestrictFragmentShaderTiming.h b/Source/ThirdParty/ANGLE/src/compiler/timing/RestrictFragmentShaderTiming.h new file mode 100644 index 000000000..899165ca2 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/timing/RestrictFragmentShaderTiming.h @@ -0,0 +1,40 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_TIMING_RESTRICT_FRAGMENT_SHADER_TIMING_H_ +#define COMPILER_TIMING_RESTRICT_FRAGMENT_SHADER_TIMING_H_ + +#include "GLSLANG/ShaderLang.h" + +#include "compiler/intermediate.h" +#include "compiler/depgraph/DependencyGraph.h" + +class TInfoSinkBase; + +class RestrictFragmentShaderTiming : TDependencyGraphTraverser { +public: + RestrictFragmentShaderTiming(TInfoSinkBase& sink); + void enforceRestrictions(const TDependencyGraph& graph); + int numErrors() const { return mNumErrors; } + + virtual void visitArgument(TGraphArgument* parameter); + virtual void visitSelection(TGraphSelection* selection); + virtual void visitLoop(TGraphLoop* loop); + virtual void visitLogicalOp(TGraphLogicalOp* logicalOp); + +private: + void beginError(const TIntermNode* node); + void validateUserDefinedFunctionCallUsage(const TDependencyGraph& graph); + bool isSamplingOp(const TIntermAggregate* intermFunctionCall) const; + + TInfoSinkBase& mSink; + int mNumErrors; + + typedef std::set<TString> StringSet; + StringSet mSamplingOps; +}; + +#endif // COMPILER_TIMING_RESTRICT_FRAGMENT_SHADER_TIMING_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/timing/RestrictVertexShaderTiming.cpp b/Source/ThirdParty/ANGLE/src/compiler/timing/RestrictVertexShaderTiming.cpp new file mode 100644 index 000000000..524c6cf53 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/timing/RestrictVertexShaderTiming.cpp @@ -0,0 +1,17 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/timing/RestrictVertexShaderTiming.h" + +void RestrictVertexShaderTiming::visitSymbol(TIntermSymbol* node) +{ + if (IsSampler(node->getBasicType())) { + ++mNumErrors; + mSink.prefix(EPrefixError); + mSink.location(node->getLine()); + mSink << "Samplers are not permitted in vertex shaders.\n"; + } +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/timing/RestrictVertexShaderTiming.h b/Source/ThirdParty/ANGLE/src/compiler/timing/RestrictVertexShaderTiming.h new file mode 100644 index 000000000..19a05fa68 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/timing/RestrictVertexShaderTiming.h @@ -0,0 +1,33 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_TIMING_RESTRICT_VERTEX_SHADER_TIMING_H_ +#define COMPILER_TIMING_RESTRICT_VERTEX_SHADER_TIMING_H_ + +#include "GLSLANG/ShaderLang.h" + +#include "compiler/intermediate.h" +#include "compiler/InfoSink.h" + +class TInfoSinkBase; + +class RestrictVertexShaderTiming : public TIntermTraverser { +public: + RestrictVertexShaderTiming(TInfoSinkBase& sink) + : TIntermTraverser(true, false, false) + , mSink(sink) + , mNumErrors(0) {} + + void enforceRestrictions(TIntermNode* root) { root->traverse(this); } + int numErrors() { return mNumErrors; } + + virtual void visitSymbol(TIntermSymbol*); +private: + TInfoSinkBase& mSink; + int mNumErrors; +}; + +#endif // COMPILER_TIMING_RESTRICT_VERTEX_SHADER_TIMING_H_ diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp b/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp index 6a5cfd36e..0cc0b93fb 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp +++ b/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp @@ -992,6 +992,22 @@ bool Display::getDXT5TextureSupport() return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5)); } +// we use INTZ for depth textures in Direct3D9 +// we also want NULL texture support to ensure the we can make depth-only FBOs +// see http://aras-p.info/texts/D3D9GPUHacks.html +bool Display::getDepthTextureSupport() const +{ + D3DDISPLAYMODE currentDisplayMode; + mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); + + bool intz = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, + D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, D3DFMT_INTZ)); + bool null = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, + D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL)); + + return intz && null; +} + bool Display::getFloat32TextureSupport(bool *filtering, bool *renderable) { D3DDISPLAYMODE currentDisplayMode; @@ -1081,7 +1097,7 @@ D3DPOOL Display::getBufferPool(DWORD usage) const return D3DPOOL_DEFAULT; } -D3DPOOL Display::getTexturePool(bool renderable) const +D3DPOOL Display::getTexturePool(DWORD usage) const { if (mD3d9Ex != NULL) { @@ -1089,7 +1105,7 @@ D3DPOOL Display::getTexturePool(bool renderable) const } else { - if (!renderable) + if (!(usage & (D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_RENDERTARGET))) { return D3DPOOL_MANAGED; } diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Display.h b/Source/ThirdParty/ANGLE/src/libEGL/Display.h index 5028431a8..4f7dbd010 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/Display.h +++ b/Source/ThirdParty/ANGLE/src/libEGL/Display.h @@ -78,10 +78,11 @@ class Display virtual bool getLuminanceAlphaTextureSupport(); virtual bool getVertexTextureSupport() const; virtual bool getNonPower2TextureSupport() const; + virtual bool getDepthTextureSupport() const; virtual bool getOcclusionQuerySupport() const; virtual bool getInstancingSupport() const; virtual D3DPOOL getBufferPool(DWORD usage) const; - virtual D3DPOOL getTexturePool(bool renderable) const; + virtual D3DPOOL getTexturePool(DWORD usage) const; virtual void notifyDeviceLost(); bool isDeviceLost(); diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp b/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp index 07ad3cf0f..899b7791e 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp +++ b/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp @@ -43,6 +43,7 @@ Surface::Surface(Display *display, const Config *config, HWND window, EGLint pos : mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported) { mSwapChain = NULL; + mBackBuffer = NULL; mDepthStencil = NULL; mRenderTarget = NULL; mOffscreenTexture = NULL; @@ -64,6 +65,7 @@ Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGL : mDisplay(display), mWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE) { mSwapChain = NULL; + mBackBuffer = NULL; mDepthStencil = NULL; mRenderTarget = NULL; mOffscreenTexture = NULL; @@ -121,6 +123,12 @@ void Surface::release() mSwapChain = NULL; } + if (mBackBuffer) + { + mBackBuffer->Release(); + mBackBuffer = NULL; + } + if (mDepthStencil) { mDepthStencil->Release(); @@ -144,6 +152,8 @@ void Surface::release() mTexture->releaseTexImage(); mTexture = NULL; } + + mShareHandle = NULL; } bool Surface::resetSwapChain() @@ -174,57 +184,13 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) return false; } - IDirect3DSurface9* preservedRenderTarget = NULL; - if (mPostSubBufferSupported && mRenderTarget) - { - preservedRenderTarget = mRenderTarget; - preservedRenderTarget->AddRef(); - } - // Evict all non-render target textures to system memory and release all resources // before reallocating them to free up as much video memory as possible. device->EvictManagedResources(); - release(); D3DPRESENT_PARAMETERS presentParameters = {0}; HRESULT result; - bool useFlipEx = (getComparableOSVersion() >= versionWindows7) && mDisplay->isD3d9ExDevice(); - - // FlipEx causes unseemly stretching when resizing windows AND when one - // draws outside of the WM_PAINT callback. While this is seldom a problem in - // single process applications, it is particuarly noticeable in multiprocess - // applications. Therefore, if the creator process of our window is not in - // the current process, disable use of FlipEx. - DWORD windowPID; - GetWindowThreadProcessId(mWindow, &windowPID); - if (windowPID != GetCurrentProcessId()) - { - useFlipEx = false; - } - - // Various hardware does not support D3DSWAPEFFECT_FLIPEX when either the - // device format or back buffer format is not 32-bit. - HDC deviceContext = GetDC(0); - int deviceFormatBits = GetDeviceCaps(deviceContext, BITSPIXEL); - ReleaseDC(0, deviceContext); - if (mConfig->mBufferSize != 32 || deviceFormatBits != 32) - { - useFlipEx = false; - } - - // D3DSWAPEFFECT_FLIPEX is always VSYNCed - if (mSwapInterval == 0) - { - useFlipEx = false; - } - - // D3DSWAPEFFECT_FLIPEX does not preserve the back buffer. - if (mPostSubBufferSupported) - { - useFlipEx = false; - } - presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat; // We set BackBufferCount = 1 even when we use D3DSWAPEFFECT_FLIPEX. // We do this because DirectX docs are a bit vague whether to set this to 1 @@ -239,41 +205,50 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented presentParameters.PresentationInterval = mPresentInterval; - // Use flipEx on Win7 or greater. - if(useFlipEx) - presentParameters.SwapEffect = D3DSWAPEFFECT_FLIPEX; - else - presentParameters.SwapEffect = mPostSubBufferSupported ? D3DSWAPEFFECT_COPY : D3DSWAPEFFECT_DISCARD; + presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; presentParameters.Windowed = TRUE; presentParameters.BackBufferWidth = backbufferWidth; presentParameters.BackBufferHeight = backbufferHeight; - if (mWindow) + // Release specific resources to free up memory for the new render target, while the + // old render target still exists for the purpose of preserving its contents. + if (mSwapChain) { - result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain); - } else { - HANDLE *pShareHandle = NULL; - if (mDisplay->shareHandleSupported()) { - pShareHandle = &mShareHandle; - } + mSwapChain->Release(); + mSwapChain = NULL; + } - result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET, - presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle); + if (mBackBuffer) + { + mBackBuffer->Release(); + mBackBuffer = NULL; } - if (FAILED(result)) + if (mOffscreenTexture) { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST); + mOffscreenTexture->Release(); + mOffscreenTexture = NULL; + } - ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); - release(); + if (mDepthStencil) + { + mDepthStencil->Release(); + mDepthStencil = NULL; + } - - if (preservedRenderTarget) - { - preservedRenderTarget->Release(); - preservedRenderTarget = NULL; - } + mShareHandle = NULL; + HANDLE *pShareHandle = NULL; + if (!mWindow && mDisplay->shareHandleSupported()) + { + pShareHandle = &mShareHandle; + } + + result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET, + presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle); + if (FAILED(result)) + { + ERR("Could not create offscreen texture: %08lX", result); + release(); if(isDeviceLostError(result)) { @@ -286,20 +261,12 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) } } - if (mWindow) - { - mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mRenderTarget); - if (!preservedRenderTarget) - { - InvalidateRect(mWindow, NULL, FALSE); - } - } - else - { - mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget); - } + IDirect3DSurface9 *oldRenderTarget = mRenderTarget; + + result = mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget); + ASSERT(SUCCEEDED(result)); - if (preservedRenderTarget) + if (oldRenderTarget) { RECT rect = { @@ -318,10 +285,37 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) } mDisplay->endScene(); - device->StretchRect(preservedRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE); - preservedRenderTarget->Release(); - preservedRenderTarget = NULL; + result = device->StretchRect(oldRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE); + ASSERT(SUCCEEDED(result)); + + oldRenderTarget->Release(); + } + + if (mWindow) + { + result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST); + + ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); + release(); + + if(isDeviceLostError(result)) + { + mDisplay->notifyDeviceLost(); + return false; + } + else + { + return error(EGL_BAD_ALLOC, false); + } + } + + result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer); + ASSERT(SUCCEEDED(result)); } if (mConfig->mDepthStencilFormat != D3DFMT_UNKNOWN) @@ -329,21 +323,137 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType, presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL); + + ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result); + release(); + + if(isDeviceLostError(result)) + { + mDisplay->notifyDeviceLost(); + return false; + } + else + { + return error(EGL_BAD_ALLOC, false); + } + } } - if (FAILED(result)) + mWidth = presentParameters.BackBufferWidth; + mHeight = presentParameters.BackBufferHeight; + + mPresentIntervalDirty = false; + return true; +} + +bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) +{ + if (!mSwapChain) { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL); + return true; + } - ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result); - release(); + if (x + width > mWidth) + { + width = mWidth - x; + } + + if (y + height > mHeight) + { + height = mHeight - y; + } + + if (width == 0 || height == 0) + { + return true; + } + + IDirect3DDevice9 *device = mDisplay->getDevice(); + + // Disable all pipeline operations + device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); + device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + device->SetRenderState(D3DRS_STENCILENABLE, FALSE); + device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); + device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED); + device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE); + device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + device->SetPixelShader(NULL); + device->SetVertexShader(NULL); + + device->SetRenderTarget(0, mBackBuffer); + device->SetDepthStencilSurface(NULL); + + device->SetTexture(0, mOffscreenTexture); + device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); + + D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f}; + device->SetViewport(&viewport); + + float x1 = x - 0.5f; + float y1 = (mHeight - y - height) - 0.5f; + float x2 = (x + width) - 0.5f; + float y2 = (mHeight - y) - 0.5f; + + float u1 = x / float(mWidth); + float v1 = y / float(mHeight); + float u2 = (x + width) / float(mWidth); + float v2 = (y + height) / float(mHeight); + + float quad[4][6] = {{x1, y1, 0.0f, 1.0f, u1, v2}, + {x2, y1, 0.0f, 1.0f, u2, v2}, + {x2, y2, 0.0f, 1.0f, u2, v1}, + {x1, y2, 0.0f, 1.0f, u1, v1}}; // x, y, z, rhw, u, v + + mDisplay->startScene(); + device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float)); + mDisplay->endScene(); + + device->SetTexture(0, NULL); + + RECT rect = + { + x, mHeight - y - height, + x + width, mHeight - y + }; + + HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0); + + gl::Context *context = static_cast<gl::Context*>(glGetCurrentContext()); + if (context) + { + context->markAllStateDirty(); + } + + if (isDeviceLostError(result)) + { + mDisplay->notifyDeviceLost(); + return false; + } + + if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR) + { return error(EGL_BAD_ALLOC, false); } - mWidth = presentParameters.BackBufferWidth; - mHeight = presentParameters.BackBufferHeight; + ASSERT(SUCCEEDED(result)); + + checkForOutOfDateSwapChain(); - mPresentIntervalDirty = false; return true; } @@ -467,87 +577,18 @@ DWORD Surface::convertInterval(EGLint interval) bool Surface::swap() { - if (mSwapChain) - { - mDisplay->endScene(); - - HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, 0); - - if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) - { - return error(EGL_BAD_ALLOC, false); - } - - if (isDeviceLostError(result)) - { - mDisplay->notifyDeviceLost(); - return false; - } - - ASSERT(SUCCEEDED(result)); - - checkForOutOfDateSwapChain(); - } - - return true; + return swapRect(0, 0, mWidth, mHeight); } bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) { - if (x < 0 || y < 0 || width < 0 || height < 0) - { - return error(EGL_BAD_PARAMETER, false); - } - if (!mPostSubBufferSupported) { // Spec is not clear about how this should be handled. return true; } - - if (mSwapChain) - { - mDisplay->endScene(); - - RECT rect = - { - x, mHeight - y - height, - x + width, mHeight - y - }; - - if (rect.right > mWidth) - { - rect.right = mWidth; - } - - if (rect.bottom > mHeight) - { - rect.bottom = mHeight; - } - - if (rect.left == rect.right || rect.top == rect.bottom) - { - return true; - } - - HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0); - - if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR) - { - return error(EGL_BAD_ALLOC, false); - } - - if (result == D3DERR_DEVICELOST || result == D3DERR_DEVICEHUNG || result == D3DERR_DEVICEREMOVED) - { - return error(EGL_CONTEXT_LOST, false); - } - - ASSERT(SUCCEEDED(result)); - - checkForOutOfDateSwapChain(); - } - - return true; + + return swapRect(x, y, width, height); } EGLint Surface::getWidth() const @@ -565,6 +606,8 @@ EGLint Surface::isPostSubBufferSupported() const return mPostSubBufferSupported; } +// Increments refcount on surface. +// caller must Release() the returned surface IDirect3DSurface9 *Surface::getRenderTarget() { if (mRenderTarget) @@ -575,6 +618,8 @@ IDirect3DSurface9 *Surface::getRenderTarget() return mRenderTarget; } +// Increments refcount on surface. +// caller must Release() the returned surface IDirect3DSurface9 *Surface::getDepthStencil() { if (mDepthStencil) diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Surface.h b/Source/ThirdParty/ANGLE/src/libEGL/Surface.h index 35260de56..40bd7028a 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/Surface.h +++ b/Source/ThirdParty/ANGLE/src/libEGL/Surface.h @@ -69,6 +69,7 @@ private: Display *const mDisplay; IDirect3DSwapChain9 *mSwapChain; + IDirect3DSurface9 *mBackBuffer; IDirect3DSurface9 *mDepthStencil; IDirect3DSurface9* mRenderTarget; IDirect3DTexture9* mOffscreenTexture; @@ -78,6 +79,7 @@ private: void subclassWindow(); void unsubclassWindow(); bool resetSwapChain(int backbufferWidth, int backbufferHeight); + bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height); static DWORD convertInterval(EGLint interval); const HWND mWindow; // Window that the surface is created for. diff --git a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp index 4b7f9e1fc..5089d2c75 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp @@ -1108,6 +1108,11 @@ EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLi try { + if (x < 0 || y < 0 || width < 0 || height < 0) + { + return error(EGL_BAD_PARAMETER, EGL_FALSE); + } + egl::Display *display = static_cast<egl::Display*>(dpy); egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Context.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Context.cpp index 66cd5c08c..6ec607715 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Context.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Context.cpp @@ -22,6 +22,7 @@ #include "libGLESv2/Fence.h" #include "libGLESv2/FrameBuffer.h" #include "libGLESv2/Program.h" +#include "libGLESv2/ProgramBinary.h" #include "libGLESv2/Query.h" #include "libGLESv2/RenderBuffer.h" #include "libGLESv2/Shader.h" @@ -310,6 +311,7 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface) mSupportsFloat16Textures = mDisplay->getFloat16TextureSupport(&mSupportsFloat16LinearFilter, &mSupportsFloat16RenderableTextures); mSupportsLuminanceTextures = mDisplay->getLuminanceTextureSupport(); mSupportsLuminanceAlphaTextures = mDisplay->getLuminanceAlphaTextureSupport(); + mSupportsDepthTextures = mDisplay->getDepthTextureSupport(); mSupports32bitIndices = mDeviceCaps.MaxVertexIndex >= (1 << 16); @@ -405,6 +407,11 @@ void Context::markAllStateDirty() mCachedCurrentProgram = NULL; } +void Context::markDxUniformsDirty() +{ + mDxUniformsDirty = true; +} + void Context::markContextLost() { if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT) @@ -1646,6 +1653,12 @@ bool Context::getIntegerv(GLenum pname, GLint *params) case GL_RESET_NOTIFICATION_STRATEGY_EXT: *params = mResetStrategy; break; + case GL_NUM_PROGRAM_BINARY_FORMATS_OES: + *params = 1; + break; + case GL_PROGRAM_BINARY_FORMATS_OES: + *params = GL_PROGRAM_BINARY_ANGLE; + break; default: return false; } @@ -1737,6 +1750,8 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu case GL_TEXTURE_BINDING_2D: case GL_TEXTURE_BINDING_CUBE_MAP: case GL_RESET_NOTIFICATION_STRATEGY_EXT: + case GL_NUM_PROGRAM_BINARY_FORMATS_OES: + case GL_PROGRAM_BINARY_FORMATS_OES: { *type = GL_INT; *numParams = 1; @@ -1835,13 +1850,31 @@ bool Context::applyRenderTarget(bool ignoreViewport) return error(GL_INVALID_FRAMEBUFFER_OPERATION, false); } + // if there is no color attachment we must synthesize a NULL colorattachment + // to keep the D3D runtime happy. This should only be possible if depth texturing. + Renderbuffer *renderbufferObject = NULL; + if (framebufferObject->getColorbufferType() != GL_NONE) + { + renderbufferObject = framebufferObject->getColorbuffer(); + } + else + { + renderbufferObject = framebufferObject->getNullColorbuffer(); + } + if (!renderbufferObject) + { + ERR("unable to locate renderbuffer for FBO."); + return false; + } + bool renderTargetChanged = false; - unsigned int renderTargetSerial = framebufferObject->getRenderTargetSerial(); + unsigned int renderTargetSerial = renderbufferObject->getSerial(); if (renderTargetSerial != mAppliedRenderTargetSerial) { - IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget(); + IDirect3DSurface9 *renderTarget = renderbufferObject->getRenderTarget(); if (!renderTarget) { + ERR("render target pointer unexpectedly null."); return false; // Context must be lost } mDevice->SetRenderTarget(0, renderTarget); @@ -1856,25 +1889,27 @@ bool Context::applyRenderTarget(bool ignoreViewport) unsigned int stencilbufferSerial = 0; if (framebufferObject->getDepthbufferType() != GL_NONE) { - depthStencil = framebufferObject->getDepthbuffer()->getDepthStencil(); + Renderbuffer *depthbuffer = framebufferObject->getDepthbuffer(); + depthStencil = depthbuffer->getDepthStencil(); if (!depthStencil) { ERR("Depth stencil pointer unexpectedly null."); return false; } - depthbufferSerial = framebufferObject->getDepthbuffer()->getSerial(); + depthbufferSerial = depthbuffer->getSerial(); } else if (framebufferObject->getStencilbufferType() != GL_NONE) { - depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil(); + Renderbuffer *stencilbuffer = framebufferObject->getStencilbuffer(); + depthStencil = stencilbuffer->getDepthStencil(); if (!depthStencil) { ERR("Depth stencil pointer unexpectedly null."); return false; } - stencilbufferSerial = framebufferObject->getStencilbuffer()->getSerial(); + stencilbufferSerial = stencilbuffer->getSerial(); } if (depthbufferSerial != mAppliedDepthbufferSerial || @@ -1887,9 +1922,14 @@ bool Context::applyRenderTarget(bool ignoreViewport) mDepthStencilInitialized = true; } + if (depthStencil) + { + depthStencil->Release(); + } + if (!mRenderTargetDescInitialized || renderTargetChanged) { - IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget(); + IDirect3DSurface9 *renderTarget = renderbufferObject->getRenderTarget(); if (!renderTarget) { return false; // Context must be lost @@ -1915,11 +1955,10 @@ bool Context::applyRenderTarget(bool ignoreViewport) } else { - RECT rect = transformPixelRect(mState.viewportX, mState.viewportY, mState.viewportWidth, mState.viewportHeight, mRenderTargetDesc.Height); - viewport.X = clamp(rect.left, 0L, static_cast<LONG>(mRenderTargetDesc.Width)); - viewport.Y = clamp(rect.top, 0L, static_cast<LONG>(mRenderTargetDesc.Height)); - viewport.Width = clamp(rect.right - rect.left, 0L, static_cast<LONG>(mRenderTargetDesc.Width) - static_cast<LONG>(viewport.X)); - viewport.Height = clamp(rect.bottom - rect.top, 0L, static_cast<LONG>(mRenderTargetDesc.Height) - static_cast<LONG>(viewport.Y)); + viewport.X = clamp(mState.viewportX, 0L, static_cast<LONG>(mRenderTargetDesc.Width)); + viewport.Y = clamp(mState.viewportY, 0L, static_cast<LONG>(mRenderTargetDesc.Height)); + viewport.Width = clamp(mState.viewportWidth, 0L, static_cast<LONG>(mRenderTargetDesc.Width) - static_cast<LONG>(viewport.X)); + viewport.Height = clamp(mState.viewportHeight, 0L, static_cast<LONG>(mRenderTargetDesc.Height) - static_cast<LONG>(viewport.Y)); viewport.MinZ = zNear; viewport.MaxZ = zFar; } @@ -1941,11 +1980,11 @@ bool Context::applyRenderTarget(bool ignoreViewport) { if (mState.scissorTest) { - RECT rect = transformPixelRect(mState.scissorX, mState.scissorY, mState.scissorWidth, mState.scissorHeight, mRenderTargetDesc.Height); - rect.left = clamp(rect.left, 0L, static_cast<LONG>(mRenderTargetDesc.Width)); - rect.top = clamp(rect.top, 0L, static_cast<LONG>(mRenderTargetDesc.Height)); - rect.right = clamp(rect.right, 0L, static_cast<LONG>(mRenderTargetDesc.Width)); - rect.bottom = clamp(rect.bottom, 0L, static_cast<LONG>(mRenderTargetDesc.Height)); + RECT rect; + rect.left = clamp(mState.scissorX, 0L, static_cast<LONG>(mRenderTargetDesc.Width)); + rect.top = clamp(mState.scissorY, 0L, static_cast<LONG>(mRenderTargetDesc.Height)); + rect.right = clamp(mState.scissorX + mState.scissorWidth, 0L, static_cast<LONG>(mRenderTargetDesc.Width)); + rect.bottom = clamp(mState.scissorY + mState.scissorHeight, 0L, static_cast<LONG>(mRenderTargetDesc.Height)); mDevice->SetScissorRect(&rect); mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); } @@ -1960,26 +1999,26 @@ bool Context::applyRenderTarget(bool ignoreViewport) if (mState.currentProgram && mDxUniformsDirty) { Program *programObject = getCurrentProgram(); + ProgramBinary *programBinary = programObject->getProgramBinary(); - GLint halfPixelSize = programObject->getDxHalfPixelSizeLocation(); + GLint halfPixelSize = programBinary->getDxHalfPixelSizeLocation(); GLfloat xy[2] = {1.0f / viewport.Width, -1.0f / viewport.Height}; - programObject->setUniform2fv(halfPixelSize, 1, xy); + programBinary->setUniform2fv(halfPixelSize, 1, xy); - // These values are used for computing gl_FragCoord in Program::linkVaryings(). The approach depends on Shader Model 3.0 support. - GLint coord = programObject->getDxCoordLocation(); - float h = mSupportsShaderModel3 ? mRenderTargetDesc.Height : mState.viewportHeight / 2.0f; - GLfloat whxy[4] = {mState.viewportWidth / 2.0f, h, + // These values are used for computing gl_FragCoord in Program::linkVaryings(). + GLint coord = programBinary->getDxCoordLocation(); + GLfloat whxy[4] = {mState.viewportWidth / 2.0f, mState.viewportHeight / 2.0f, (float)mState.viewportX + mState.viewportWidth / 2.0f, (float)mState.viewportY + mState.viewportHeight / 2.0f}; - programObject->setUniform4fv(coord, 1, whxy); + programBinary->setUniform4fv(coord, 1, whxy); - GLint depth = programObject->getDxDepthLocation(); + GLint depth = programBinary->getDxDepthLocation(); GLfloat dz[2] = {(zFar - zNear) / 2.0f, (zNear + zFar) / 2.0f}; - programObject->setUniform2fv(depth, 1, dz); + programBinary->setUniform2fv(depth, 1, dz); - GLint depthRange = programObject->getDxDepthRangeLocation(); + GLint depthRange = programBinary->getDxDepthRangeLocation(); GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear}; - programObject->setUniform3fv(depthRange, 1, nearFarDiff); + programBinary->setUniform3fv(depthRange, 1, nearFarDiff); mDxUniformsDirty = false; } @@ -1990,18 +2029,17 @@ bool Context::applyRenderTarget(bool ignoreViewport) void Context::applyState(GLenum drawMode) { Program *programObject = getCurrentProgram(); + ProgramBinary *programBinary = programObject->getProgramBinary(); Framebuffer *framebufferObject = getDrawFramebuffer(); - GLenum adjustedFrontFace = adjustWinding(mState.frontFace); - - GLint frontCCW = programObject->getDxFrontCCWLocation(); - GLint ccw = (adjustedFrontFace == GL_CCW); - programObject->setUniform1iv(frontCCW, 1, &ccw); + GLint frontCCW = programBinary->getDxFrontCCWLocation(); + GLint ccw = (mState.frontFace == GL_CCW); + programBinary->setUniform1iv(frontCCW, 1, &ccw); - GLint pointsOrLines = programObject->getDxPointsOrLinesLocation(); + GLint pointsOrLines = programBinary->getDxPointsOrLinesLocation(); GLint alwaysFront = !isTriangleMode(drawMode); - programObject->setUniform1iv(pointsOrLines, 1, &alwaysFront); + programBinary->setUniform1iv(pointsOrLines, 1, &alwaysFront); D3DADAPTER_IDENTIFIER9 *identifier = mDisplay->getAdapterIdentifier(); bool zeroColorMaskAllowed = identifier->VendorId != 0x1002; @@ -2015,7 +2053,7 @@ void Context::applyState(GLenum drawMode) { if (mState.cullFace) { - mDevice->SetRenderState(D3DRS_CULLMODE, es2dx::ConvertCullMode(mState.cullMode, adjustedFrontFace)); + mDevice->SetRenderState(D3DRS_CULLMODE, es2dx::ConvertCullMode(mState.cullMode, mState.frontFace)); } else { @@ -2115,32 +2153,32 @@ void Context::applyState(GLenum drawMode) gl::Renderbuffer *stencilbuffer = framebufferObject->getStencilbuffer(); GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1; - mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilWritemask); - mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, + mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilWritemask); + mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, es2dx::ConvertComparison(mState.stencilFunc)); - mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); - mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilMask); + mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); + mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilMask); - mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, + mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, es2dx::ConvertStencilOp(mState.stencilFail)); - mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, + mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, es2dx::ConvertStencilOp(mState.stencilPassDepthFail)); - mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, + mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, es2dx::ConvertStencilOp(mState.stencilPassDepthPass)); - mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilBackWritemask); - mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, + mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilBackWritemask); + mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, es2dx::ConvertComparison(mState.stencilBackFunc)); - mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); - mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilBackMask); + mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); + mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilBackMask); - mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, + mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, es2dx::ConvertStencilOp(mState.stencilBackFail)); - mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, + mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, es2dx::ConvertStencilOp(mState.stencilBackPassDepthFail)); - mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, + mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, es2dx::ConvertStencilOp(mState.stencilBackPassDepthPass)); } else @@ -2280,18 +2318,20 @@ GLenum Context::applyIndexBuffer(const GLvoid *indices, GLsizei count, GLenum mo void Context::applyShaders() { Program *programObject = getCurrentProgram(); + ProgramBinary *programBinary = programObject->getProgramBinary(); + if (programObject->getSerial() != mAppliedProgramSerial) { - IDirect3DVertexShader9 *vertexShader = programObject->getVertexShader(); - IDirect3DPixelShader9 *pixelShader = programObject->getPixelShader(); + IDirect3DVertexShader9 *vertexShader = programBinary->getVertexShader(); + IDirect3DPixelShader9 *pixelShader = programBinary->getPixelShader(); mDevice->SetPixelShader(pixelShader); mDevice->SetVertexShader(vertexShader); - programObject->dirtyAllUniforms(); + programBinary->dirtyAllUniforms(); mAppliedProgramSerial = programObject->getSerial(); } - programObject->applyUniforms(); + programBinary->applyUniforms(); } // Applies the textures and sampler states to the Direct3D 9 device @@ -2311,30 +2351,32 @@ void Context::applyTextures() void Context::applyTextures(SamplerType type) { Program *programObject = getCurrentProgram(); + ProgramBinary *programBinary = programObject->getProgramBinary(); int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; // Range of Direct3D 9 samplers of given sampler type unsigned int *appliedTextureSerial = (type == SAMPLER_PIXEL) ? mAppliedTextureSerialPS : mAppliedTextureSerialVS; int d3dSamplerOffset = (type == SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; - int samplerRange = programObject->getUsedSamplerRange(type); + int samplerRange = programBinary->getUsedSamplerRange(type); for (int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) { - int textureUnit = programObject->getSamplerMapping(type, samplerIndex); // OpenGL texture image unit index + int textureUnit = programBinary->getSamplerMapping(type, samplerIndex); // OpenGL texture image unit index int d3dSampler = samplerIndex + d3dSamplerOffset; if (textureUnit != -1) { - TextureType textureType = programObject->getSamplerTextureType(type, samplerIndex); + TextureType textureType = programBinary->getSamplerTextureType(type, samplerIndex); Texture *texture = getSamplerTexture(textureUnit, textureType); + unsigned int texSerial = texture->getTextureSerial(); - if (appliedTextureSerial[samplerIndex] != texture->getTextureSerial() || texture->hasDirtyParameters() || texture->hasDirtyImages()) + if (appliedTextureSerial[samplerIndex] != texSerial || texture->hasDirtyParameters() || texture->hasDirtyImages()) { IDirect3DBaseTexture9 *d3dTexture = texture->getTexture(); if (d3dTexture) { - if (appliedTextureSerial[samplerIndex] != texture->getTextureSerial() || texture->hasDirtyParameters()) + if (appliedTextureSerial[samplerIndex] != texSerial || texture->hasDirtyParameters()) { GLenum wrapS = texture->getWrapS(); GLenum wrapT = texture->getWrapT(); @@ -2351,7 +2393,7 @@ void Context::applyTextures(SamplerType type) mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter); } - if (appliedTextureSerial[samplerIndex] != texture->getTextureSerial() || texture->hasDirtyImages()) + if (appliedTextureSerial[samplerIndex] != texSerial || texture->hasDirtyImages()) { mDevice->SetTexture(d3dSampler, d3dTexture); } @@ -2361,7 +2403,7 @@ void Context::applyTextures(SamplerType type) mDevice->SetTexture(d3dSampler, getIncompleteTexture(textureType)->getTexture()); } - appliedTextureSerial[samplerIndex] = texture->getTextureSerial(); + appliedTextureSerial[samplerIndex] = texSerial; texture->resetDirty(); } } @@ -2429,7 +2471,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, HRESULT result; IDirect3DSurface9 *systemSurface = NULL; - bool directToPixels = getPackReverseRowOrder() && getPackAlignment() <= 4 && mDisplay->isD3d9ExDevice() && + bool directToPixels = !getPackReverseRowOrder() && getPackAlignment() <= 4 && mDisplay->isD3d9ExDevice() && x == 0 && y == 0 && UINT(width) == desc.Width && UINT(height) == desc.Height && desc.Format == D3DFMT_A8R8G8B8 && format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE; if (directToPixels) @@ -2451,6 +2493,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + renderTarget->Release(); return error(GL_OUT_OF_MEMORY); } } @@ -2481,13 +2524,13 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, return; } - D3DLOCKED_RECT lock; - RECT rect = transformPixelRect(x, y, width, height, desc.Height); - rect.left = clamp(rect.left, 0L, static_cast<LONG>(desc.Width)); - rect.top = clamp(rect.top, 0L, static_cast<LONG>(desc.Height)); - rect.right = clamp(rect.right, 0L, static_cast<LONG>(desc.Width)); - rect.bottom = clamp(rect.bottom, 0L, static_cast<LONG>(desc.Height)); + RECT rect; + rect.left = clamp(x, 0L, static_cast<LONG>(desc.Width)); + rect.top = clamp(y, 0L, static_cast<LONG>(desc.Height)); + rect.right = clamp(x + width, 0L, static_cast<LONG>(desc.Width)); + rect.bottom = clamp(y + height, 0L, static_cast<LONG>(desc.Height)); + D3DLOCKED_RECT lock; result = systemSurface->LockRect(&lock, &rect, D3DLOCK_READONLY); if (FAILED(result)) @@ -2505,13 +2548,13 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, int inputPitch; if (getPackReverseRowOrder()) { - source = (unsigned char*)lock.pBits; - inputPitch = lock.Pitch; + source = ((unsigned char*)lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1); + inputPitch = -lock.Pitch; } else { - source = ((unsigned char*)lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1); - inputPitch = -lock.Pitch; + source = (unsigned char*)lock.pBits; + inputPitch = lock.Pitch; } for (int j = 0; j < rect.bottom - rect.top; j++) @@ -2738,6 +2781,7 @@ void Context::clear(GLbitfield mask) D3DSURFACE_DESC desc; depthStencil->GetDesc(&desc); + depthStencil->Release(); unsigned int stencilSize = dx2es::GetStencilSize(desc.Format); stencilUnmasked = (0x1 << stencilSize) - 1; @@ -2952,7 +2996,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan applyShaders(); applyTextures(); - if (!getCurrentProgram()->validateSamplers(false)) + if (!getCurrentProgram()->getProgramBinary()->validateSamplers(NULL)) { return error(GL_INVALID_OPERATION); } @@ -3042,7 +3086,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid applyShaders(); applyTextures(); - if (!getCurrentProgram()->validateSamplers(false)) + if (!getCurrentProgram()->getProgramBinary()->validateSamplers(false)) { return error(GL_INVALID_OPERATION); } @@ -3452,6 +3496,11 @@ bool Context::supportsLuminanceAlphaTextures() const return mSupportsLuminanceAlphaTextures; } +bool Context::supportsDepthTextures() const +{ + return mSupportsDepthTextures; +} + bool Context::supports32bitIndices() const { return mSupports32bitIndices; @@ -3677,6 +3726,7 @@ void Context::initExtensionString() } mExtensionString += "GL_OES_packed_depth_stencil "; + //mExtensionString += "GL_OES_get_program_binary "; mExtensionString += "GL_OES_rgb8_rgba8 "; mExtensionString += "GL_OES_standard_derivatives "; @@ -3720,6 +3770,11 @@ void Context::initExtensionString() mExtensionString += "GL_EXT_texture_storage "; // ANGLE-specific extensions + if (supportsDepthTextures()) + { + mExtensionString += "GL_ANGLE_depth_texture "; + } + mExtensionString += "GL_ANGLE_framebuffer_blit "; if (getMaxSupportedSamples() != 0) { @@ -3820,17 +3875,17 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 if (srcY0 < srcY1) { - sourceRect.top = readBufferHeight - srcY1; - destRect.top = drawBufferHeight - dstY1; - sourceRect.bottom = readBufferHeight - srcY0; - destRect.bottom = drawBufferHeight - dstY0; + sourceRect.bottom = srcY1; + destRect.bottom = dstY1; + sourceRect.top = srcY0; + destRect.top = dstY0; } else { - sourceRect.top = readBufferHeight - srcY0; - destRect.top = drawBufferHeight - dstY0; - sourceRect.bottom = readBufferHeight - srcY1; - destRect.bottom = drawBufferHeight - dstY1; + sourceRect.bottom = srcY0; + destRect.bottom = dstY0; + sourceRect.top = srcY1; + destRect.top = dstY1; } RECT sourceScissoredRect = sourceRect; @@ -4043,7 +4098,13 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 if (blitDepthStencil) { - HRESULT result = mDevice->StretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, D3DTEXF_NONE); + IDirect3DSurface9* readDepthStencil = readFramebuffer->getDepthStencil(); + IDirect3DSurface9* drawDepthStencil = drawFramebuffer->getDepthStencil(); + + HRESULT result = mDevice->StretchRect(readDepthStencil, NULL, drawDepthStencil, NULL, D3DTEXF_NONE); + + readDepthStencil->Release(); + drawDepthStencil->Release(); if (FAILED(result)) { @@ -4115,6 +4176,8 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS + 1]; D3DVERTEXELEMENT9 *element = &elements[0]; + ProgramBinary *programBinary = program->getProgramBinary(); + for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) { if (attributes[i].active) @@ -4170,7 +4233,7 @@ GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Transl element->Type = attributes[i].type; element->Method = D3DDECLMETHOD_DEFAULT; element->Usage = D3DDECLUSAGE_TEXCOORD; - element->UsageIndex = program->getSemanticIndex(i); + element->UsageIndex = programBinary->getSemanticIndex(i); element++; } } diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Context.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Context.h index 8dccf0f9a..4d47ce7e9 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Context.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Context.h @@ -251,7 +251,7 @@ class VertexDeclarationCache private: UINT mMaxLru; - enum { NUM_VERTEX_DECL_CACHE_ENTRIES = 16 }; + enum { NUM_VERTEX_DECL_CACHE_ENTRIES = 32 }; struct VBData { @@ -281,7 +281,8 @@ class Context void makeCurrent(egl::Display *display, egl::Surface *surface); - void markAllStateDirty(); + virtual void markAllStateDirty(); + void markDxUniformsDirty(); virtual void markContextLost(); bool isContextLost(); @@ -495,6 +496,7 @@ class Context bool supportsFloat16RenderableTextures() const; bool supportsLuminanceTextures() const; bool supportsLuminanceAlphaTextures() const; + bool supportsDepthTextures() const; bool supports32bitIndices() const; bool supportsNonPower2Texture() const; bool supportsInstancing() const; @@ -617,6 +619,7 @@ class Context bool mSupportsFloat16RenderableTextures; bool mSupportsLuminanceTextures; bool mSupportsLuminanceAlphaTextures; + bool mSupportsDepthTextures; bool mSupports32bitIndices; int mNumCompressedTextureFormats; diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.cpp index 730fffc75..76d428340 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -29,6 +29,7 @@ Framebuffer::~Framebuffer() mColorbufferPointer.set(NULL); mDepthbufferPointer.set(NULL); mStencilbufferPointer.set(NULL); + mNullColorbufferPointer.set(NULL); } Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const @@ -128,6 +129,8 @@ unsigned int Framebuffer::getRenderTargetSerial() return 0; } +// Increments refcount on surface. +// caller must Release() the returned surface IDirect3DSurface9 *Framebuffer::getRenderTarget() { Renderbuffer *colorbuffer = mColorbufferPointer.get(); @@ -140,6 +143,8 @@ IDirect3DSurface9 *Framebuffer::getRenderTarget() return NULL; } +// Increments refcount on surface. +// caller must Release() the returned surface IDirect3DSurface9 *Framebuffer::getDepthStencil() { Renderbuffer *depthstencilbuffer = mDepthbufferPointer.get(); @@ -196,6 +201,30 @@ Renderbuffer *Framebuffer::getStencilbuffer() return mStencilbufferPointer.get(); } +Renderbuffer *Framebuffer::getNullColorbuffer() +{ + Renderbuffer *nullbuffer = mNullColorbufferPointer.get(); + Renderbuffer *depthbuffer = getDepthbuffer(); + + if (!depthbuffer) + { + ERR("Unexpected null depthbuffer for depth-only FBO."); + return NULL; + } + + GLsizei width = depthbuffer->getWidth(); + GLsizei height = depthbuffer->getHeight(); + + if (!nullbuffer || + width != nullbuffer->getWidth() || height != nullbuffer->getHeight()) + { + nullbuffer = new Renderbuffer(0, new Colorbuffer(width, height, GL_NONE, 0)); + mNullColorbufferPointer.set(nullbuffer); + } + + return nullbuffer; +} + GLenum Framebuffer::getColorbufferType() { return mColorbufferType; @@ -243,9 +272,11 @@ bool Framebuffer::hasStencil() GLenum Framebuffer::completeness() { + gl::Context *context = gl::getContext(); int width = 0; int height = 0; int samples = -1; + bool missingAttachment = true; if (mColorbufferType != GL_NONE) { @@ -270,31 +301,38 @@ GLenum Framebuffer::completeness() } else if (IsInternalTextureTarget(mColorbufferType)) { - if (IsCompressed(colorbuffer->getInternalFormat())) + GLenum internalformat = colorbuffer->getInternalFormat(); + D3DFORMAT d3dformat = colorbuffer->getD3DFormat(); + + if (IsCompressed(internalformat) || + internalformat == GL_ALPHA || + internalformat == GL_LUMINANCE || + internalformat == GL_LUMINANCE_ALPHA) { return GL_FRAMEBUFFER_UNSUPPORTED; } - if ((dx2es::IsFloat32Format(colorbuffer->getD3DFormat()) && !getContext()->supportsFloat32RenderableTextures()) || - (dx2es::IsFloat16Format(colorbuffer->getD3DFormat()) && !getContext()->supportsFloat16RenderableTextures())) + if ((dx2es::IsFloat32Format(d3dformat) && !context->supportsFloat32RenderableTextures()) || + (dx2es::IsFloat16Format(d3dformat) && !context->supportsFloat16RenderableTextures())) { return GL_FRAMEBUFFER_UNSUPPORTED; } - if (colorbuffer->getInternalFormat() == GL_LUMINANCE || colorbuffer->getInternalFormat() == GL_LUMINANCE_ALPHA) + if (dx2es::IsDepthTextureFormat(d3dformat) || dx2es::IsStencilTextureFormat(d3dformat)) { - return GL_FRAMEBUFFER_UNSUPPORTED; + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } } - else UNREACHABLE(); + else + { + UNREACHABLE(); + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + } width = colorbuffer->getWidth(); height = colorbuffer->getHeight(); samples = colorbuffer->getSamples(); - } - else - { - return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; + missingAttachment = false; } Renderbuffer *depthbuffer = NULL; @@ -302,11 +340,6 @@ GLenum Framebuffer::completeness() if (mDepthbufferType != GL_NONE) { - if (mDepthbufferType != GL_RENDERBUFFER) - { - return GL_FRAMEBUFFER_UNSUPPORTED; // Requires GL_OES_depth_texture - } - depthbuffer = getDepthbuffer(); if (!depthbuffer) @@ -319,19 +352,44 @@ GLenum Framebuffer::completeness() return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - if (width == 0) + if (mDepthbufferType == GL_RENDERBUFFER) { - width = depthbuffer->getWidth(); - height = depthbuffer->getHeight(); + if (!gl::IsDepthRenderable(depthbuffer->getInternalFormat())) + { + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + } } - else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight()) + else if (IsInternalTextureTarget(mDepthbufferType)) { - return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; + D3DFORMAT d3dformat = depthbuffer->getD3DFormat(); + + // depth texture attachments require OES/ANGLE_depth_texture + if (!context->supportsDepthTextures()) + { + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + } + + if (!dx2es::IsDepthTextureFormat(d3dformat)) + { + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + } + } + else + { + UNREACHABLE(); + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - if (samples == -1) + if (missingAttachment) { + width = depthbuffer->getWidth(); + height = depthbuffer->getHeight(); samples = depthbuffer->getSamples(); + missingAttachment = false; + } + else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight()) + { + return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; } else if (samples != depthbuffer->getSamples()) { @@ -341,11 +399,6 @@ GLenum Framebuffer::completeness() if (mStencilbufferType != GL_NONE) { - if (mStencilbufferType != GL_RENDERBUFFER) - { - return GL_FRAMEBUFFER_UNSUPPORTED; - } - stencilbuffer = getStencilbuffer(); if (!stencilbuffer) @@ -358,19 +411,45 @@ GLenum Framebuffer::completeness() return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - if (width == 0) + if (mStencilbufferType == GL_RENDERBUFFER) { - width = stencilbuffer->getWidth(); - height = stencilbuffer->getHeight(); + if (!gl::IsStencilRenderable(stencilbuffer->getInternalFormat())) + { + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + } } - else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight()) + else if (IsInternalTextureTarget(mStencilbufferType)) { - return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; + D3DFORMAT d3dformat = stencilbuffer->getD3DFormat(); + + // texture stencil attachments come along as part + // of OES_packed_depth_stencil + OES/ANGLE_depth_texture + if (!context->supportsDepthTextures()) + { + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + } + + if (!dx2es::IsStencilTextureFormat(d3dformat)) + { + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + } + } + else + { + UNREACHABLE(); + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - if (samples == -1) + if (missingAttachment) { + width = stencilbuffer->getWidth(); + height = stencilbuffer->getHeight(); samples = stencilbuffer->getSamples(); + missingAttachment = false; + } + else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight()) + { + return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; } else if (samples != stencilbuffer->getSamples()) { @@ -378,14 +457,17 @@ GLenum Framebuffer::completeness() } } - if (mDepthbufferType == GL_RENDERBUFFER && mStencilbufferType == GL_RENDERBUFFER) + // if we have both a depth and stencil buffer, they must refer to the same object + // since we only support packed_depth_stencil and not separate depth and stencil + if (depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer)) { - if (depthbuffer->getInternalFormat() != GL_DEPTH24_STENCIL8_OES || - stencilbuffer->getInternalFormat() != GL_DEPTH24_STENCIL8_OES || - depthbuffer->getSerial() != stencilbuffer->getSerial()) - { - return GL_FRAMEBUFFER_UNSUPPORTED; - } + return GL_FRAMEBUFFER_UNSUPPORTED; + } + + // we need to have at least one attachment to be complete + if (missingAttachment) + { + return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; } return GL_FRAMEBUFFER_COMPLETE; diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.h index b73f9a0df..14d9c2a74 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.h @@ -49,6 +49,7 @@ class Framebuffer Renderbuffer *getColorbuffer(); Renderbuffer *getDepthbuffer(); Renderbuffer *getStencilbuffer(); + Renderbuffer *getNullColorbuffer(); GLenum getColorbufferType(); GLenum getDepthbufferType(); @@ -73,6 +74,8 @@ class Framebuffer GLenum mStencilbufferType; BindingPointer<Renderbuffer> mStencilbufferPointer; + BindingPointer<Renderbuffer> mNullColorbufferPointer; + private: DISALLOW_COPY_AND_ASSIGN(Framebuffer); diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp index a5e38bf1b..f28a9d811 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp @@ -8,6 +8,7 @@ // and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28. #include "libGLESv2/Program.h" +#include "libGLESv2/ProgramBinary.h" #include "common/debug.h" @@ -17,1616 +18,225 @@ #include <string> -#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) -#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3 -#endif - namespace gl { -unsigned int Program::mCurrentSerial = 1; -const char *fakepath = "C:\\fakepath"; - -std::string str(int i) -{ - char buffer[20]; - sprintf(buffer, "%d", i); - return buffer; -} - -Uniform::Uniform(GLenum type, const std::string &_name, unsigned int arraySize) - : type(type), _name(_name), name(Program::undecorateUniform(_name)), arraySize(arraySize) -{ - int bytes = UniformInternalSize(type) * arraySize; - data = new unsigned char[bytes]; - memset(data, 0, bytes); - dirty = true; -} - -Uniform::~Uniform() -{ - delete[] data; -} - -bool Uniform::isArray() -{ - return _name.compare(0, 3, "ar_") == 0; -} - -UniformLocation::UniformLocation(const std::string &_name, unsigned int element, unsigned int index) - : name(Program::undecorateUniform(_name)), element(element), index(index) -{ -} - -Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle), mSerial(issueSerial()) -{ - mDevice = getDevice(); - mFragmentShader = NULL; - mVertexShader = NULL; - - mPixelExecutable = NULL; - mVertexExecutable = NULL; - mConstantTablePS = NULL; - mConstantTableVS = NULL; - - mInfoLog = NULL; - mValidated = false; - - unlink(); - - mDeleteStatus = false; - - mRefCount = 0; -} - -Program::~Program() -{ - unlink(true); - - if (mVertexShader != NULL) - { - mVertexShader->release(); - } - - if (mFragmentShader != NULL) - { - mFragmentShader->release(); - } -} - -bool Program::attachShader(Shader *shader) -{ - if (shader->getType() == GL_VERTEX_SHADER) - { - if (mVertexShader) - { - return false; - } - - mVertexShader = (VertexShader*)shader; - mVertexShader->addRef(); - } - else if (shader->getType() == GL_FRAGMENT_SHADER) - { - if (mFragmentShader) - { - return false; - } - - mFragmentShader = (FragmentShader*)shader; - mFragmentShader->addRef(); - } - else UNREACHABLE(); +const char * const g_fakepath = "C:\\fakepath"; - return true; -} - -bool Program::detachShader(Shader *shader) -{ - if (shader->getType() == GL_VERTEX_SHADER) - { - if (mVertexShader != shader) - { - return false; - } - - mVertexShader->release(); - mVertexShader = NULL; - } - else if (shader->getType() == GL_FRAGMENT_SHADER) - { - if (mFragmentShader != shader) - { - return false; - } - - mFragmentShader->release(); - mFragmentShader = NULL; - } - else UNREACHABLE(); - - return true; -} - -int Program::getAttachedShadersCount() const -{ - return (mVertexShader ? 1 : 0) + (mFragmentShader ? 1 : 0); -} +unsigned int Program::mCurrentSerial = 1; -IDirect3DPixelShader9 *Program::getPixelShader() +AttributeBindings::AttributeBindings() { - return mPixelExecutable; } -IDirect3DVertexShader9 *Program::getVertexShader() +AttributeBindings::~AttributeBindings() { - return mVertexExecutable; } -void Program::bindAttributeLocation(GLuint index, const char *name) +InfoLog::InfoLog() : mInfoLog(NULL) { - if (index < MAX_VERTEX_ATTRIBS) - { - for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) - { - mAttributeBinding[i].erase(name); - } - - mAttributeBinding[index].insert(name); - } } -GLuint Program::getAttributeLocation(const char *name) +InfoLog::~InfoLog() { - if (name) - { - for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++) - { - if (mLinkedAttribute[index].name == std::string(name)) - { - return index; - } - } - } - - return -1; + delete[] mInfoLog; } -int Program::getSemanticIndex(int attributeIndex) -{ - ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS); - - return mSemanticIndex[attributeIndex]; -} -// Returns one more than the highest sampler index used. -GLint Program::getUsedSamplerRange(SamplerType type) +int InfoLog::getLength() const { - switch (type) + if (!mInfoLog) { - case SAMPLER_PIXEL: - return mUsedPixelSamplerRange; - case SAMPLER_VERTEX: - return mUsedVertexSamplerRange; - default: - UNREACHABLE(); return 0; } -} - -// Returns the index of the texture image unit (0-19) corresponding to a Direct3D 9 sampler -// index (0-15 for the pixel shader and 0-3 for the vertex shader). -GLint Program::getSamplerMapping(SamplerType type, unsigned int samplerIndex) -{ - GLint logicalTextureUnit = -1; - - switch (type) - { - case SAMPLER_PIXEL: - ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0])); - - if (mSamplersPS[samplerIndex].active) - { - logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit; - } - break; - case SAMPLER_VERTEX: - ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0])); - - if (mSamplersVS[samplerIndex].active) - { - logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit; - } - break; - default: UNREACHABLE(); - } - - if (logicalTextureUnit >= 0 && logicalTextureUnit < (GLint)getContext()->getMaximumCombinedTextureImageUnits()) - { - return logicalTextureUnit; - } - - return -1; -} - -// Returns the texture type for a given Direct3D 9 sampler type and -// index (0-15 for the pixel shader and 0-3 for the vertex shader). -TextureType Program::getSamplerTextureType(SamplerType type, unsigned int samplerIndex) -{ - switch (type) - { - case SAMPLER_PIXEL: - ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0])); - ASSERT(mSamplersPS[samplerIndex].active); - return mSamplersPS[samplerIndex].textureType; - case SAMPLER_VERTEX: - ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0])); - ASSERT(mSamplersVS[samplerIndex].active); - return mSamplersVS[samplerIndex].textureType; - default: UNREACHABLE(); - } - - return TEXTURE_2D; -} - -GLint Program::getUniformLocation(std::string name) -{ - unsigned int subscript = 0; - - // Strip any trailing array operator and retrieve the subscript - size_t open = name.find_last_of('['); - size_t close = name.find_last_of(']'); - if (open != std::string::npos && close == name.length() - 1) - { - subscript = atoi(name.substr(open + 1).c_str()); - name.erase(open); - } - - unsigned int numUniforms = mUniformIndex.size(); - for (unsigned int location = 0; location < numUniforms; location++) - { - if (mUniformIndex[location].name == name && - mUniformIndex[location].element == subscript) - { - return location; - } - } - - return -1; -} - -bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) -{ - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; - - if (targetUniform->type == GL_FLOAT) - { - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); - - GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; - - for (int i = 0; i < count; i++) - { - target[0] = v[0]; - target[1] = 0; - target[2] = 0; - target[3] = 0; - target += 4; - v += 1; - } - } - else if (targetUniform->type == GL_BOOL) - { - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); - GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element; - - for (int i = 0; i < count; ++i) - { - if (v[i] == 0.0f) - { - boolParams[i] = GL_FALSE; - } - else - { - boolParams[i] = GL_TRUE; - } - } - } else { - return false; + return strlen(mInfoLog) + 1; } - - return true; } -bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) +void InfoLog::getLog(GLsizei bufSize, GLsizei *length, char *infoLog) { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; + int index = 0; - if (targetUniform->type == GL_FLOAT_VEC2) + if (bufSize > 0) { - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); - - GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; - - for (int i = 0; i < count; i++) + if (mInfoLog) { - target[0] = v[0]; - target[1] = v[1]; - target[2] = 0; - target[3] = 0; - target += 4; - v += 2; + index = std::min(bufSize - 1, (int)strlen(mInfoLog)); + memcpy(infoLog, mInfoLog, index); } - } - else if (targetUniform->type == GL_BOOL_VEC2) - { - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); - - GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 2; - for (int i = 0; i < count * 2; ++i) - { - if (v[i] == 0.0f) - { - boolParams[i] = GL_FALSE; - } - else - { - boolParams[i] = GL_TRUE; - } - } - } - else - { - return false; - } - - return true; -} - -bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) -{ - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; - - if (targetUniform->type == GL_FLOAT_VEC3) - { - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); - - GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; - - for (int i = 0; i < count; i++) - { - target[0] = v[0]; - target[1] = v[1]; - target[2] = v[2]; - target[3] = 0; - target += 4; - v += 3; - } + infoLog[index] = '\0'; } - else if (targetUniform->type == GL_BOOL_VEC3) - { - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - count = std::min(arraySize - (int)mUniformIndex[location].element, count); - GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 3; - - for (int i = 0; i < count * 3; ++i) - { - if (v[i] == 0.0f) - { - boolParams[i] = GL_FALSE; - } - else - { - boolParams[i] = GL_TRUE; - } - } - } - else + if (length) { - return false; + *length = index; } - - return true; } -bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) +// append a santized message to the program info log. +// The D3D compiler includes a fake file path in some of the warning or error +// messages, so lets remove all occurrences of this fake file path from the log. +void InfoLog::appendSanitized(const char *message) { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; - - if (targetUniform->type == GL_FLOAT_VEC4) - { - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); + std::string msg(message); - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 4, - v, 4 * sizeof(GLfloat) * count); - } - else if (targetUniform->type == GL_BOOL_VEC4) + size_t found; + do { - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); - GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 4; - - for (int i = 0; i < count * 4; ++i) + found = msg.find(g_fakepath); + if (found != std::string::npos) { - if (v[i] == 0.0f) - { - boolParams[i] = GL_FALSE; - } - else - { - boolParams[i] = GL_TRUE; - } + msg.erase(found, strlen(g_fakepath)); } } - else - { - return false; - } + while (found != std::string::npos); - return true; + append("%s\n", msg.c_str()); } -template<typename T, int targetWidth, int targetHeight, int srcWidth, int srcHeight> -void transposeMatrix(T *target, const GLfloat *value) +void InfoLog::append(const char *format, ...) { - int copyWidth = std::min(targetWidth, srcWidth); - int copyHeight = std::min(targetHeight, srcHeight); - - for (int x = 0; x < copyWidth; x++) - { - for (int y = 0; y < copyHeight; y++) - { - target[x * targetWidth + y] = (T)value[y * srcWidth + x]; - } - } - // clear unfilled right side - for (int y = 0; y < copyHeight; y++) - { - for (int x = srcWidth; x < targetWidth; x++) - { - target[y * targetWidth + x] = (T)0; - } - } - // clear unfilled bottom. - for (int y = srcHeight; y < targetHeight; y++) - { - for (int x = 0; x < targetWidth; x++) - { - target[y * targetWidth + x] = (T)0; - } - } -} - -bool Program::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) -{ - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; - - if (targetUniform->type != GL_FLOAT_MAT2) + if (!format) { - return false; + return; } - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); + char info[1024]; - GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8; - for (int i = 0; i < count; i++) - { - transposeMatrix<GLfloat,4,2,2,2>(target, value); - target += 8; - value += 4; - } + va_list vararg; + va_start(vararg, format); + vsnprintf(info, sizeof(info), format, vararg); + va_end(vararg); - return true; -} + size_t infoLength = strlen(info); -bool Program::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) -{ - if (location < 0 || location >= (int)mUniformIndex.size()) + if (!mInfoLog) { - return false; + mInfoLog = new char[infoLength + 1]; + strcpy(mInfoLog, info); } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; - - if (targetUniform->type != GL_FLOAT_MAT3) + else { - return false; - } - - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); + size_t logLength = strlen(mInfoLog); + char *newLog = new char[logLength + infoLength + 1]; + strcpy(newLog, mInfoLog); + strcpy(newLog + logLength, info); - GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12; - for (int i = 0; i < count; i++) - { - transposeMatrix<GLfloat,4,3,3,3>(target, value); - target += 12; - value += 9; + delete[] mInfoLog; + mInfoLog = newLog; } - - return true; } - -bool Program::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) +void InfoLog::reset() { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; - - if (targetUniform->type != GL_FLOAT_MAT4) - { - return false; - } - - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); - - GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 16); - for (int i = 0; i < count; i++) + if (mInfoLog) { - transposeMatrix<GLfloat,4,4,4,4>(target, value); - target += 16; - value += 16; + delete [] mInfoLog; + mInfoLog = NULL; } - - return true; } -bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v) +Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle), mSerial(issueSerial()) { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; - - if (targetUniform->type == GL_INT || - targetUniform->type == GL_SAMPLER_2D || - targetUniform->type == GL_SAMPLER_CUBE) - { - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); - - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLint), - v, sizeof(GLint) * count); - } - else if (targetUniform->type == GL_BOOL) - { - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); - GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element; - - for (int i = 0; i < count; ++i) - { - if (v[i] == 0) - { - boolParams[i] = GL_FALSE; - } - else - { - boolParams[i] = GL_TRUE; - } - } - } - else - { - return false; - } - - return true; + mFragmentShader = NULL; + mVertexShader = NULL; + mProgramBinary = NULL; + mDeleteStatus = false; + mRefCount = 0; } -bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v) +Program::~Program() { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; + unlink(true); - if (targetUniform->type == GL_INT_VEC2) + if (mVertexShader != NULL) { - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); - - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLint) * 2, - v, 2 * sizeof(GLint) * count); + mVertexShader->release(); } - else if (targetUniform->type == GL_BOOL_VEC2) - { - int arraySize = targetUniform->arraySize; - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); - GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 2; - - for (int i = 0; i < count * 2; ++i) - { - if (v[i] == 0) - { - boolParams[i] = GL_FALSE; - } - else - { - boolParams[i] = GL_TRUE; - } - } - } - else + if (mFragmentShader != NULL) { - return false; + mFragmentShader->release(); } - - return true; } -bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v) +bool Program::attachShader(Shader *shader) { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; - - if (targetUniform->type == GL_INT_VEC3) - { - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); - - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLint) * 3, - v, 3 * sizeof(GLint) * count); - } - else if (targetUniform->type == GL_BOOL_VEC3) + if (shader->getType() == GL_VERTEX_SHADER) { - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); - GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 3; - - for (int i = 0; i < count * 3; ++i) + if (mVertexShader) { - if (v[i] == 0) - { - boolParams[i] = GL_FALSE; - } - else - { - boolParams[i] = GL_TRUE; - } + return false; } - } - else - { - return false; - } - return true; -} - -bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v) -{ - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - targetUniform->dirty = true; - - if (targetUniform->type == GL_INT_VEC4) - { - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); - - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLint) * 4, - v, 4 * sizeof(GLint) * count); + mVertexShader = (VertexShader*)shader; + mVertexShader->addRef(); } - else if (targetUniform->type == GL_BOOL_VEC4) + else if (shader->getType() == GL_FRAGMENT_SHADER) { - int arraySize = targetUniform->arraySize; - - if (arraySize == 1 && count > 1) - return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION - - count = std::min(arraySize - (int)mUniformIndex[location].element, count); - GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 4; - - for (int i = 0; i < count * 4; ++i) + if (mFragmentShader) { - if (v[i] == 0) - { - boolParams[i] = GL_FALSE; - } - else - { - boolParams[i] = GL_TRUE; - } + return false; } + + mFragmentShader = (FragmentShader*)shader; + mFragmentShader->addRef(); } - else - { - return false; - } + else UNREACHABLE(); return true; } -bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params) +bool Program::detachShader(Shader *shader) { - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - // sized queries -- ensure the provided buffer is large enough - if (bufSize) + if (shader->getType() == GL_VERTEX_SHADER) { - int requiredBytes = UniformExternalSize(targetUniform->type); - if (*bufSize < requiredBytes) + if (mVertexShader != shader) { return false; } - } - switch (targetUniform->type) - { - case GL_FLOAT_MAT2: - transposeMatrix<GLfloat,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8); - break; - case GL_FLOAT_MAT3: - transposeMatrix<GLfloat,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12); - break; - case GL_FLOAT_MAT4: - transposeMatrix<GLfloat,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16); - break; - default: - { - unsigned int count = UniformExternalComponentCount(targetUniform->type); - unsigned int internalCount = UniformInternalComponentCount(targetUniform->type); - - switch (UniformComponentType(targetUniform->type)) - { - case GL_BOOL: - { - GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * internalCount; - - for (unsigned int i = 0; i < count; ++i) - { - params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f; - } - } - break; - case GL_FLOAT: - memcpy(params, targetUniform->data + mUniformIndex[location].element * internalCount * sizeof(GLfloat), - count * sizeof(GLfloat)); - break; - case GL_INT: - { - GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * internalCount; - - for (unsigned int i = 0; i < count; ++i) - { - params[i] = (float)intParams[i]; - } - } - break; - default: UNREACHABLE(); - } - } - } - - return true; -} - -bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params) -{ - if (location < 0 || location >= (int)mUniformIndex.size()) - { - return false; + mVertexShader->release(); + mVertexShader = NULL; } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - // sized queries -- ensure the provided buffer is large enough - if (bufSize) + else if (shader->getType() == GL_FRAGMENT_SHADER) { - int requiredBytes = UniformExternalSize(targetUniform->type); - if (*bufSize < requiredBytes) + if (mFragmentShader != shader) { return false; } - } - switch (targetUniform->type) - { - case GL_FLOAT_MAT2: - { - transposeMatrix<GLint,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8); - } - break; - case GL_FLOAT_MAT3: - { - transposeMatrix<GLint,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12); - } - break; - case GL_FLOAT_MAT4: - { - transposeMatrix<GLint,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16); - } - break; - default: - { - unsigned int count = UniformExternalComponentCount(targetUniform->type); - unsigned int internalCount = UniformInternalComponentCount(targetUniform->type); - - switch (UniformComponentType(targetUniform->type)) - { - case GL_BOOL: - { - GLboolean *boolParams = targetUniform->data + mUniformIndex[location].element * internalCount; - - for (unsigned int i = 0; i < count; ++i) - { - params[i] = (GLint)boolParams[i]; - } - } - break; - case GL_FLOAT: - { - GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * internalCount; - - for (unsigned int i = 0; i < count; ++i) - { - params[i] = (GLint)floatParams[i]; - } - } - break; - case GL_INT: - memcpy(params, targetUniform->data + mUniformIndex[location].element * internalCount * sizeof(GLint), - count * sizeof(GLint)); - break; - default: UNREACHABLE(); - } - } + mFragmentShader->release(); + mFragmentShader = NULL; } + else UNREACHABLE(); return true; } -void Program::dirtyAllUniforms() -{ - unsigned int numUniforms = mUniforms.size(); - for (unsigned int index = 0; index < numUniforms; index++) - { - mUniforms[index]->dirty = true; - } -} - -// Applies all the uniforms set for this program object to the Direct3D 9 device -void Program::applyUniforms() -{ - for (std::vector<Uniform*>::iterator ub = mUniforms.begin(), ue = mUniforms.end(); ub != ue; ++ub) { - Uniform *targetUniform = *ub; - - if (targetUniform->dirty) - { - int arraySize = targetUniform->arraySize; - GLfloat *f = (GLfloat*)targetUniform->data; - GLint *i = (GLint*)targetUniform->data; - GLboolean *b = (GLboolean*)targetUniform->data; - - switch (targetUniform->type) - { - case GL_BOOL: applyUniformnbv(targetUniform, arraySize, 1, b); break; - case GL_BOOL_VEC2: applyUniformnbv(targetUniform, arraySize, 2, b); break; - case GL_BOOL_VEC3: applyUniformnbv(targetUniform, arraySize, 3, b); break; - case GL_BOOL_VEC4: applyUniformnbv(targetUniform, arraySize, 4, b); break; - case GL_FLOAT: - case GL_FLOAT_VEC2: - case GL_FLOAT_VEC3: - case GL_FLOAT_VEC4: - case GL_FLOAT_MAT2: - case GL_FLOAT_MAT3: - case GL_FLOAT_MAT4: applyUniformnfv(targetUniform, f); break; - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: - case GL_INT: applyUniform1iv(targetUniform, arraySize, i); break; - case GL_INT_VEC2: applyUniform2iv(targetUniform, arraySize, i); break; - case GL_INT_VEC3: applyUniform3iv(targetUniform, arraySize, i); break; - case GL_INT_VEC4: applyUniform4iv(targetUniform, arraySize, i); break; - default: - UNREACHABLE(); - } - - targetUniform->dirty = false; - } - } -} - -// Compiles the HLSL code of the attached shaders into executable binaries -ID3D10Blob *Program::compileToBinary(const char *hlsl, const char *profile, ID3DXConstantTable **constantTable) +int Program::getAttachedShadersCount() const { - if (!hlsl) - { - return NULL; - } - - DWORD result; - UINT flags = 0; - std::string sourceText; - if (perfActive()) - { - flags |= D3DCOMPILE_DEBUG; -#ifdef NDEBUG - flags |= ANGLE_COMPILE_OPTIMIZATION_LEVEL; -#else - flags |= D3DCOMPILE_SKIP_OPTIMIZATION; -#endif - - std::string sourcePath = getTempPath(); - sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(hlsl); - writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); - } - else - { - flags |= ANGLE_COMPILE_OPTIMIZATION_LEVEL; - sourceText = hlsl; - } - - ID3D10Blob *binary = NULL; - ID3D10Blob *errorMessage = NULL; - result = D3DCompile(hlsl, strlen(hlsl), fakepath, NULL, NULL, "main", profile, flags, 0, &binary, &errorMessage); - - if (errorMessage) - { - const char *message = (const char*)errorMessage->GetBufferPointer(); - - appendToInfoLogSanitized(message); - TRACE("\n%s", hlsl); - TRACE("\n%s", message); - - errorMessage->Release(); - errorMessage = NULL; - } - - if (FAILED(result)) - { - if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) - { - error(GL_OUT_OF_MEMORY); - } - - return NULL; - } - - result = D3DXGetShaderConstantTable(static_cast<const DWORD*>(binary->GetBufferPointer()), constantTable); - - if (FAILED(result)) - { - if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) - { - error(GL_OUT_OF_MEMORY); - } - - binary->Release(); - - return NULL; - } - - return binary; + return (mVertexShader ? 1 : 0) + (mFragmentShader ? 1 : 0); } -// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111 -// Returns the number of used varying registers, or -1 if unsuccesful -int Program::packVaryings(const Varying *packing[][4]) +void AttributeBindings::bindAttributeLocation(GLuint index, const char *name) { - Context *context = getContext(); - const int maxVaryingVectors = context->getMaximumVaryingVectors(); - - for (VaryingList::iterator varying = mFragmentShader->mVaryings.begin(); varying != mFragmentShader->mVaryings.end(); varying++) + if (index < MAX_VERTEX_ATTRIBS) { - int n = VariableRowCount(varying->type) * varying->size; - int m = VariableColumnCount(varying->type); - bool success = false; - - if (m == 2 || m == 3 || m == 4) - { - for (int r = 0; r <= maxVaryingVectors - n && !success; r++) - { - bool available = true; - - for (int y = 0; y < n && available; y++) - { - for (int x = 0; x < m && available; x++) - { - if (packing[r + y][x]) - { - available = false; - } - } - } - - if (available) - { - varying->reg = r; - varying->col = 0; - - for (int y = 0; y < n; y++) - { - for (int x = 0; x < m; x++) - { - packing[r + y][x] = &*varying; - } - } - - success = true; - } - } - - if (!success && m == 2) - { - for (int r = maxVaryingVectors - n; r >= 0 && !success; r--) - { - bool available = true; - - for (int y = 0; y < n && available; y++) - { - for (int x = 2; x < 4 && available; x++) - { - if (packing[r + y][x]) - { - available = false; - } - } - } - - if (available) - { - varying->reg = r; - varying->col = 2; - - for (int y = 0; y < n; y++) - { - for (int x = 2; x < 4; x++) - { - packing[r + y][x] = &*varying; - } - } - - success = true; - } - } - } - } - else if (m == 1) - { - int space[4] = {0}; - - for (int y = 0; y < maxVaryingVectors; y++) - { - for (int x = 0; x < 4; x++) - { - space[x] += packing[y][x] ? 0 : 1; - } - } - - int column = 0; - - for (int x = 0; x < 4; x++) - { - if (space[x] >= n && space[x] < space[column]) - { - column = x; - } - } - - if (space[column] >= n) - { - for (int r = 0; r < maxVaryingVectors; r++) - { - if (!packing[r][column]) - { - varying->reg = r; - - for (int y = r; y < r + n; y++) - { - packing[y][column] = &*varying; - } - - break; - } - } - - varying->col = column; - - success = true; - } - } - else UNREACHABLE(); - - if (!success) + for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) { - appendToInfoLog("Could not pack varying %s", varying->name.c_str()); - - return -1; + mAttributeBinding[i].erase(name); } - } - // Return the number of used registers - int registers = 0; - - for (int r = 0; r < maxVaryingVectors; r++) - { - if (packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3]) - { - registers++; - } + mAttributeBinding[index].insert(name); } - - return registers; } -bool Program::linkVaryings() +void Program::bindAttributeLocation(GLuint index, const char *name) { - if (mPixelHLSL.empty() || mVertexHLSL.empty()) - { - return false; - } - - // Reset the varying register assignments - for (VaryingList::iterator fragVar = mFragmentShader->mVaryings.begin(); fragVar != mFragmentShader->mVaryings.end(); fragVar++) - { - fragVar->reg = -1; - fragVar->col = -1; - } - - for (VaryingList::iterator vtxVar = mVertexShader->mVaryings.begin(); vtxVar != mVertexShader->mVaryings.end(); vtxVar++) - { - vtxVar->reg = -1; - vtxVar->col = -1; - } - - // Map the varyings to the register file - const Varying *packing[MAX_VARYING_VECTORS_SM3][4] = {NULL}; - int registers = packVaryings(packing); - - if (registers < 0) - { - return false; - } - - // Write the HLSL input/output declarations - Context *context = getContext(); - const bool sm3 = context->supportsShaderModel3(); - const int maxVaryingVectors = context->getMaximumVaryingVectors(); - - if (registers == maxVaryingVectors && mFragmentShader->mUsesFragCoord) - { - appendToInfoLog("No varying registers left to support gl_FragCoord"); - - return false; - } - - for (VaryingList::iterator input = mFragmentShader->mVaryings.begin(); input != mFragmentShader->mVaryings.end(); input++) - { - bool matched = false; - - for (VaryingList::iterator output = mVertexShader->mVaryings.begin(); output != mVertexShader->mVaryings.end(); output++) - { - if (output->name == input->name) - { - if (output->type != input->type || output->size != input->size) - { - appendToInfoLog("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str()); - - return false; - } - - output->reg = input->reg; - output->col = input->col; - - matched = true; - break; - } - } - - if (!matched) - { - appendToInfoLog("Fragment varying %s does not match any vertex varying", input->name.c_str()); - - return false; - } - } - - std::string varyingSemantic = (sm3 ? "COLOR" : "TEXCOORD"); - - mVertexHLSL += "struct VS_INPUT\n" - "{\n"; - - int semanticIndex = 0; - for (AttributeArray::iterator attribute = mVertexShader->mAttributes.begin(); attribute != mVertexShader->mAttributes.end(); attribute++) - { - switch (attribute->type) - { - case GL_FLOAT: mVertexHLSL += " float "; break; - case GL_FLOAT_VEC2: mVertexHLSL += " float2 "; break; - case GL_FLOAT_VEC3: mVertexHLSL += " float3 "; break; - case GL_FLOAT_VEC4: mVertexHLSL += " float4 "; break; - case GL_FLOAT_MAT2: mVertexHLSL += " float2x2 "; break; - case GL_FLOAT_MAT3: mVertexHLSL += " float3x3 "; break; - case GL_FLOAT_MAT4: mVertexHLSL += " float4x4 "; break; - default: UNREACHABLE(); - } - - mVertexHLSL += decorateAttribute(attribute->name) + " : TEXCOORD" + str(semanticIndex) + ";\n"; - - semanticIndex += VariableRowCount(attribute->type); - } - - mVertexHLSL += "};\n" - "\n" - "struct VS_OUTPUT\n" - "{\n" - " float4 gl_Position : POSITION;\n"; - - for (int r = 0; r < registers; r++) - { - int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1)); - - mVertexHLSL += " float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n"; - } - - if (mFragmentShader->mUsesFragCoord) - { - mVertexHLSL += " float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n"; - } - - if (mVertexShader->mUsesPointSize && sm3) - { - mVertexHLSL += " float gl_PointSize : PSIZE;\n"; - } - - mVertexHLSL += "};\n" - "\n" - "VS_OUTPUT main(VS_INPUT input)\n" - "{\n"; - - for (AttributeArray::iterator attribute = mVertexShader->mAttributes.begin(); attribute != mVertexShader->mAttributes.end(); attribute++) - { - mVertexHLSL += " " + decorateAttribute(attribute->name) + " = "; - - if (VariableRowCount(attribute->type) > 1) // Matrix - { - mVertexHLSL += "transpose"; - } - - mVertexHLSL += "(input." + decorateAttribute(attribute->name) + ");\n"; - } - - mVertexHLSL += "\n" - " gl_main();\n" - "\n" - " VS_OUTPUT output;\n" - " output.gl_Position.x = gl_Position.x - dx_HalfPixelSize.x * gl_Position.w;\n" - " output.gl_Position.y = gl_Position.y - dx_HalfPixelSize.y * gl_Position.w;\n" - " output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n" - " output.gl_Position.w = gl_Position.w;\n"; - - if (mVertexShader->mUsesPointSize && sm3) - { - mVertexHLSL += " output.gl_PointSize = clamp(gl_PointSize, 1.0, " + str((int)ALIASED_POINT_SIZE_RANGE_MAX_SM3) + ");\n"; - } - - if (mFragmentShader->mUsesFragCoord) - { - mVertexHLSL += " output.gl_FragCoord = gl_Position;\n"; - } - - for (VaryingList::iterator varying = mVertexShader->mVaryings.begin(); varying != mVertexShader->mVaryings.end(); varying++) - { - if (varying->reg >= 0) - { - for (int i = 0; i < varying->size; i++) - { - int rows = VariableRowCount(varying->type); - - for (int j = 0; j < rows; j++) - { - int r = varying->reg + i * rows + j; - mVertexHLSL += " output.v" + str(r); - - bool sharedRegister = false; // Register used by multiple varyings - - for (int x = 0; x < 4; x++) - { - if (packing[r][x] && packing[r][x] != packing[r][0]) - { - sharedRegister = true; - break; - } - } - - if(sharedRegister) - { - mVertexHLSL += "."; - - for (int x = 0; x < 4; x++) - { - if (packing[r][x] == &*varying) - { - switch(x) - { - case 0: mVertexHLSL += "x"; break; - case 1: mVertexHLSL += "y"; break; - case 2: mVertexHLSL += "z"; break; - case 3: mVertexHLSL += "w"; break; - } - } - } - } - - mVertexHLSL += " = " + varying->name; - - if (varying->array) - { - mVertexHLSL += "[" + str(i) + "]"; - } - - if (rows > 1) - { - mVertexHLSL += "[" + str(j) + "]"; - } - - mVertexHLSL += ";\n"; - } - } - } - } - - mVertexHLSL += "\n" - " return output;\n" - "}\n"; - - mPixelHLSL += "struct PS_INPUT\n" - "{\n"; - - for (VaryingList::iterator varying = mFragmentShader->mVaryings.begin(); varying != mFragmentShader->mVaryings.end(); varying++) - { - if (varying->reg >= 0) - { - for (int i = 0; i < varying->size; i++) - { - int rows = VariableRowCount(varying->type); - for (int j = 0; j < rows; j++) - { - std::string n = str(varying->reg + i * rows + j); - mPixelHLSL += " float4 v" + n + " : " + varyingSemantic + n + ";\n"; - } - } - } - else UNREACHABLE(); - } - - if (mFragmentShader->mUsesFragCoord) - { - mPixelHLSL += " float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n"; - if (sm3) { - mPixelHLSL += " float2 dx_VPos : VPOS;\n"; - } - } - - if (mFragmentShader->mUsesPointCoord && sm3) - { - mPixelHLSL += " float2 gl_PointCoord : TEXCOORD0;\n"; - } - - if (mFragmentShader->mUsesFrontFacing) - { - mPixelHLSL += " float vFace : VFACE;\n"; - } - - mPixelHLSL += "};\n" - "\n" - "struct PS_OUTPUT\n" - "{\n" - " float4 gl_Color[1] : COLOR;\n" - "};\n" - "\n" - "PS_OUTPUT main(PS_INPUT input)\n" - "{\n"; - - if (mFragmentShader->mUsesFragCoord) - { - mPixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n"; - - if (sm3) - { - // dx_Coord.y contains the render target height. See Context::applyRenderTarget() - mPixelHLSL += " gl_FragCoord.x = input.dx_VPos.x + 0.5;\n" - " gl_FragCoord.y = dx_Coord.y - input.dx_VPos.y - 0.5;\n"; - } - else - { - // dx_Coord contains the viewport width/2, height/2, center.x and center.y. See Context::applyRenderTarget() - mPixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Coord.x + dx_Coord.z;\n" - " gl_FragCoord.y = -(input.gl_FragCoord.y * rhw) * dx_Coord.y + dx_Coord.w;\n"; - } - - mPixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n" - " gl_FragCoord.w = rhw;\n"; - } - - if (mFragmentShader->mUsesPointCoord && sm3) - { - mPixelHLSL += " gl_PointCoord = input.gl_PointCoord;\n"; - } - - if (mFragmentShader->mUsesFrontFacing) - { - mPixelHLSL += " gl_FrontFacing = dx_PointsOrLines || (dx_FrontCCW ? (input.vFace >= 0.0) : (input.vFace <= 0.0));\n"; - } - - for (VaryingList::iterator varying = mFragmentShader->mVaryings.begin(); varying != mFragmentShader->mVaryings.end(); varying++) - { - if (varying->reg >= 0) - { - for (int i = 0; i < varying->size; i++) - { - int rows = VariableRowCount(varying->type); - for (int j = 0; j < rows; j++) - { - std::string n = str(varying->reg + i * rows + j); - mPixelHLSL += " " + varying->name; - - if (varying->array) - { - mPixelHLSL += "[" + str(i) + "]"; - } - - if (rows > 1) - { - mPixelHLSL += "[" + str(j) + "]"; - } - - mPixelHLSL += " = input.v" + n + ";\n"; - } - } - } - else UNREACHABLE(); - } - - mPixelHLSL += "\n" - " gl_main();\n" - "\n" - " PS_OUTPUT output;\n" - " output.gl_Color[0] = gl_Color[0];\n" - "\n" - " return output;\n" - "}\n"; - - return true; + mAttributeBindings.bindAttributeLocation(index, name); } // Links the HLSL code of the vertex and pixel shader by matching up their varyings, @@ -1634,152 +244,18 @@ bool Program::linkVaryings() // a list of uniforms void Program::link() { - unlink(); - - if (!mFragmentShader || !mFragmentShader->isCompiled()) - { - return; - } - - if (!mVertexShader || !mVertexShader->isCompiled()) - { - return; - } - - mPixelHLSL = mFragmentShader->getHLSL(); - mVertexHLSL = mVertexShader->getHLSL(); - - if (!linkVaryings()) - { - return; - } - - Context *context = getContext(); - const char *vertexProfile = context->supportsShaderModel3() ? "vs_3_0" : "vs_2_0"; - const char *pixelProfile = context->supportsShaderModel3() ? "ps_3_0" : "ps_2_0"; - - ID3D10Blob *vertexBinary = compileToBinary(mVertexHLSL.c_str(), vertexProfile, &mConstantTableVS); - ID3D10Blob *pixelBinary = compileToBinary(mPixelHLSL.c_str(), pixelProfile, &mConstantTablePS); - - if (vertexBinary && pixelBinary) - { - HRESULT vertexResult = mDevice->CreateVertexShader((DWORD*)vertexBinary->GetBufferPointer(), &mVertexExecutable); - HRESULT pixelResult = mDevice->CreatePixelShader((DWORD*)pixelBinary->GetBufferPointer(), &mPixelExecutable); - - if (vertexResult == D3DERR_OUTOFVIDEOMEMORY || vertexResult == E_OUTOFMEMORY || pixelResult == D3DERR_OUTOFVIDEOMEMORY || pixelResult == E_OUTOFMEMORY) - { - return error(GL_OUT_OF_MEMORY); - } - - ASSERT(SUCCEEDED(vertexResult) && SUCCEEDED(pixelResult)); - - vertexBinary->Release(); - pixelBinary->Release(); - vertexBinary = NULL; - pixelBinary = NULL; - - if (mVertexExecutable && mPixelExecutable) - { - if (!linkAttributes()) - { - return; - } - - if (!linkUniforms(mConstantTablePS)) - { - return; - } - - if (!linkUniforms(mConstantTableVS)) - { - return; - } - - // these uniforms are searched as already-decorated because gl_ and dx_ - // are reserved prefixes, and do not receive additional decoration - mDxDepthRangeLocation = getUniformLocation("dx_DepthRange"); - mDxDepthLocation = getUniformLocation("dx_Depth"); - mDxCoordLocation = getUniformLocation("dx_Coord"); - mDxHalfPixelSizeLocation = getUniformLocation("dx_HalfPixelSize"); - mDxFrontCCWLocation = getUniformLocation("dx_FrontCCW"); - mDxPointsOrLinesLocation = getUniformLocation("dx_PointsOrLines"); - - mLinked = true; // Success - } - } -} - -// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices -bool Program::linkAttributes() -{ - unsigned int usedLocations = 0; - - // Link attributes that have a binding location - for (AttributeArray::iterator attribute = mVertexShader->mAttributes.begin(); attribute != mVertexShader->mAttributes.end(); attribute++) - { - int location = getAttributeBinding(attribute->name); + unlink(false); - if (location != -1) // Set by glBindAttribLocation - { - if (!mLinkedAttribute[location].name.empty()) - { - // Multiple active attributes bound to the same location; not an error - } - - mLinkedAttribute[location] = *attribute; - - int rows = VariableRowCount(attribute->type); - - if (rows + location > MAX_VERTEX_ATTRIBS) - { - appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location); - - return false; - } + mInfoLog.reset(); - for (int i = 0; i < rows; i++) - { - usedLocations |= 1 << (location + i); - } - } - } - - // Link attributes that don't have a binding location - for (AttributeArray::iterator attribute = mVertexShader->mAttributes.begin(); attribute != mVertexShader->mAttributes.end(); attribute++) + mProgramBinary = new ProgramBinary; + if (!mProgramBinary->link(mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader)) { - int location = getAttributeBinding(attribute->name); - - if (location == -1) // Not set by glBindAttribLocation - { - int rows = VariableRowCount(attribute->type); - int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS); - - if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS) - { - appendToInfoLog("Too many active attributes (%s)", attribute->name.c_str()); - - return false; // Fail to link - } - - mLinkedAttribute[availableIndex] = *attribute; - } + unlink(false); } - - for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; ) - { - int index = mVertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name); - int rows = std::max(VariableRowCount(mLinkedAttribute[attributeIndex].type), 1); - - for (int r = 0; r < rows; r++) - { - mSemanticIndex[attributeIndex++] = index++; - } - } - - return true; } -int Program::getAttributeBinding(const std::string &name) +int AttributeBindings::getAttributeBinding(const std::string &name) const { for (int location = 0; location < MAX_VERTEX_ATTRIBS; location++) { @@ -1792,527 +268,6 @@ int Program::getAttributeBinding(const std::string &name) return -1; } -bool Program::linkUniforms(ID3DXConstantTable *constantTable) -{ - D3DXCONSTANTTABLE_DESC constantTableDescription; - D3DXCONSTANT_DESC constantDescription; - UINT descriptionCount = 1; - - constantTable->GetDesc(&constantTableDescription); - - for (unsigned int constantIndex = 0; constantIndex < constantTableDescription.Constants; constantIndex++) - { - D3DXHANDLE constantHandle = constantTable->GetConstant(0, constantIndex); - HRESULT result = constantTable->GetConstantDesc(constantHandle, &constantDescription, &descriptionCount); - ASSERT(SUCCEEDED(result)); - - if (!defineUniform(constantHandle, constantDescription)) - { - return false; - } - } - - return true; -} - -// Adds the description of a constant found in the binary shader to the list of uniforms -// Returns true if succesful (uniform not already defined) -bool Program::defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name) -{ - if (constantDescription.RegisterSet == D3DXRS_SAMPLER) - { - for (unsigned int i = 0; i < constantDescription.RegisterCount; i++) - { - D3DXHANDLE psConstant = mConstantTablePS->GetConstantByName(NULL, constantDescription.Name); - D3DXHANDLE vsConstant = mConstantTableVS->GetConstantByName(NULL, constantDescription.Name); - - if (psConstant) - { - unsigned int samplerIndex = mConstantTablePS->GetSamplerIndex(psConstant) + i; - - if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS) - { - mSamplersPS[samplerIndex].active = true; - mSamplersPS[samplerIndex].textureType = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D; - mSamplersPS[samplerIndex].logicalTextureUnit = 0; - mUsedPixelSamplerRange = std::max(samplerIndex + 1, mUsedPixelSamplerRange); - } - else - { - appendToInfoLog("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS); - return false; - } - } - - if (vsConstant) - { - unsigned int samplerIndex = mConstantTableVS->GetSamplerIndex(vsConstant) + i; - - if (samplerIndex < getContext()->getMaximumVertexTextureImageUnits()) - { - mSamplersVS[samplerIndex].active = true; - mSamplersVS[samplerIndex].textureType = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D; - mSamplersVS[samplerIndex].logicalTextureUnit = 0; - mUsedVertexSamplerRange = std::max(samplerIndex + 1, mUsedVertexSamplerRange); - } - else - { - appendToInfoLog("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", getContext()->getMaximumVertexTextureImageUnits()); - return false; - } - } - } - } - - switch(constantDescription.Class) - { - case D3DXPC_STRUCT: - { - for (unsigned int arrayIndex = 0; arrayIndex < constantDescription.Elements; arrayIndex++) - { - for (unsigned int field = 0; field < constantDescription.StructMembers; field++) - { - D3DXHANDLE fieldHandle = mConstantTablePS->GetConstant(constantHandle, field); - - D3DXCONSTANT_DESC fieldDescription; - UINT descriptionCount = 1; - - HRESULT result = mConstantTablePS->GetConstantDesc(fieldHandle, &fieldDescription, &descriptionCount); - ASSERT(SUCCEEDED(result)); - - std::string structIndex = (constantDescription.Elements > 1) ? ("[" + str(arrayIndex) + "]") : ""; - - if (!defineUniform(fieldHandle, fieldDescription, name + constantDescription.Name + structIndex + ".")) - { - return false; - } - } - } - - return true; - } - case D3DXPC_SCALAR: - case D3DXPC_VECTOR: - case D3DXPC_MATRIX_COLUMNS: - case D3DXPC_OBJECT: - return defineUniform(constantDescription, name + constantDescription.Name); - default: - UNREACHABLE(); - return false; - } -} - -bool Program::defineUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &_name) -{ - Uniform *uniform = createUniform(constantDescription, _name); - - if(!uniform) - { - return false; - } - - // Check if already defined - GLint location = getUniformLocation(uniform->name); - GLenum type = uniform->type; - - if (location >= 0) - { - delete uniform; - - if (mUniforms[mUniformIndex[location].index]->type != type) - { - return false; - } - else - { - return true; - } - } - - initializeConstantHandles(uniform, &uniform->ps, mConstantTablePS); - initializeConstantHandles(uniform, &uniform->vs, mConstantTableVS); - - mUniforms.push_back(uniform); - unsigned int uniformIndex = mUniforms.size() - 1; - - for (unsigned int i = 0; i < uniform->arraySize; ++i) - { - mUniformIndex.push_back(UniformLocation(_name, i, uniformIndex)); - } - - return true; -} - -Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &_name) -{ - if (constantDescription.Rows == 1) // Vectors and scalars - { - switch (constantDescription.Type) - { - case D3DXPT_SAMPLER2D: - switch (constantDescription.Columns) - { - case 1: return new Uniform(GL_SAMPLER_2D, _name, constantDescription.Elements); - default: UNREACHABLE(); - } - break; - case D3DXPT_SAMPLERCUBE: - switch (constantDescription.Columns) - { - case 1: return new Uniform(GL_SAMPLER_CUBE, _name, constantDescription.Elements); - default: UNREACHABLE(); - } - break; - case D3DXPT_BOOL: - switch (constantDescription.Columns) - { - case 1: return new Uniform(GL_BOOL, _name, constantDescription.Elements); - case 2: return new Uniform(GL_BOOL_VEC2, _name, constantDescription.Elements); - case 3: return new Uniform(GL_BOOL_VEC3, _name, constantDescription.Elements); - case 4: return new Uniform(GL_BOOL_VEC4, _name, constantDescription.Elements); - default: UNREACHABLE(); - } - break; - case D3DXPT_INT: - switch (constantDescription.Columns) - { - case 1: return new Uniform(GL_INT, _name, constantDescription.Elements); - case 2: return new Uniform(GL_INT_VEC2, _name, constantDescription.Elements); - case 3: return new Uniform(GL_INT_VEC3, _name, constantDescription.Elements); - case 4: return new Uniform(GL_INT_VEC4, _name, constantDescription.Elements); - default: UNREACHABLE(); - } - break; - case D3DXPT_FLOAT: - switch (constantDescription.Columns) - { - case 1: return new Uniform(GL_FLOAT, _name, constantDescription.Elements); - case 2: return new Uniform(GL_FLOAT_VEC2, _name, constantDescription.Elements); - case 3: return new Uniform(GL_FLOAT_VEC3, _name, constantDescription.Elements); - case 4: return new Uniform(GL_FLOAT_VEC4, _name, constantDescription.Elements); - default: UNREACHABLE(); - } - break; - default: - UNREACHABLE(); - } - } - else if (constantDescription.Rows == constantDescription.Columns) // Square matrices - { - switch (constantDescription.Type) - { - case D3DXPT_FLOAT: - switch (constantDescription.Rows) - { - case 2: return new Uniform(GL_FLOAT_MAT2, _name, constantDescription.Elements); - case 3: return new Uniform(GL_FLOAT_MAT3, _name, constantDescription.Elements); - case 4: return new Uniform(GL_FLOAT_MAT4, _name, constantDescription.Elements); - default: UNREACHABLE(); - } - break; - default: UNREACHABLE(); - } - } - else UNREACHABLE(); - - return 0; -} - -// This method needs to match OutputHLSL::decorate -std::string Program::decorateAttribute(const std::string &name) -{ - if (name.compare(0, 3, "gl_") != 0 && name.compare(0, 3, "dx_") != 0) - { - return "_" + name; - } - - return name; -} - -std::string Program::undecorateUniform(const std::string &_name) -{ - if (_name[0] == '_') - { - return _name.substr(1); - } - else if (_name.compare(0, 3, "ar_") == 0) - { - return _name.substr(3); - } - - return _name; -} - -void Program::applyUniformnbv(Uniform *targetUniform, GLsizei count, int width, const GLboolean *v) -{ - float vector[D3D9_MAX_FLOAT_CONSTANTS * 4]; - BOOL boolVector[D3D9_MAX_BOOL_CONSTANTS]; - - if (targetUniform->ps.registerCount && targetUniform->ps.registerSet == D3DXRS_FLOAT4 || - targetUniform->vs.registerCount && targetUniform->vs.registerSet == D3DXRS_FLOAT4) - { - ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); - for (int i = 0; i < count; i++) - { - for (int j = 0; j < 4; j++) - { - if (j < width) - { - vector[i * 4 + j] = (v[i * width + j] == GL_FALSE) ? 0.0f : 1.0f; - } - else - { - vector[i * 4 + j] = 0.0f; - } - } - } - } - - if (targetUniform->ps.registerCount && targetUniform->ps.registerSet == D3DXRS_BOOL || - targetUniform->vs.registerCount && targetUniform->vs.registerSet == D3DXRS_BOOL) - { - int psCount = targetUniform->ps.registerSet == D3DXRS_BOOL ? targetUniform->ps.registerCount : 0; - int vsCount = targetUniform->vs.registerSet == D3DXRS_BOOL ? targetUniform->vs.registerCount : 0; - int copyCount = std::min(count * width, std::max(psCount, vsCount)); - ASSERT(copyCount <= D3D9_MAX_BOOL_CONSTANTS); - for (int i = 0; i < copyCount; i++) - { - boolVector[i] = v[i] != GL_FALSE; - } - } - - if (targetUniform->ps.registerCount) - { - if (targetUniform->ps.registerSet == D3DXRS_FLOAT4) - { - mDevice->SetPixelShaderConstantF(targetUniform->ps.registerIndex, vector, targetUniform->ps.registerCount); - } - else if (targetUniform->ps.registerSet == D3DXRS_BOOL) - { - mDevice->SetPixelShaderConstantB(targetUniform->ps.registerIndex, boolVector, targetUniform->ps.registerCount); - } - else UNREACHABLE(); - } - - if (targetUniform->vs.registerCount) - { - if (targetUniform->vs.registerSet == D3DXRS_FLOAT4) - { - mDevice->SetVertexShaderConstantF(targetUniform->vs.registerIndex, vector, targetUniform->vs.registerCount); - } - else if (targetUniform->vs.registerSet == D3DXRS_BOOL) - { - mDevice->SetVertexShaderConstantB(targetUniform->vs.registerIndex, boolVector, targetUniform->vs.registerCount); - } - else UNREACHABLE(); - } -} - -bool Program::applyUniformnfv(Uniform *targetUniform, const GLfloat *v) -{ - if (targetUniform->ps.registerCount) - { - mDevice->SetPixelShaderConstantF(targetUniform->ps.registerIndex, v, targetUniform->ps.registerCount); - } - - if (targetUniform->vs.registerCount) - { - mDevice->SetVertexShaderConstantF(targetUniform->vs.registerIndex, v, targetUniform->vs.registerCount); - } - - return true; -} - -bool Program::applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint *v) -{ - ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); - D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS]; - - for (int i = 0; i < count; i++) - { - vector[i] = D3DXVECTOR4((float)v[i], 0, 0, 0); - } - - if (targetUniform->ps.registerCount) - { - if (targetUniform->ps.registerSet == D3DXRS_SAMPLER) - { - unsigned int firstIndex = targetUniform->ps.registerIndex; - - for (int i = 0; i < count; i++) - { - unsigned int samplerIndex = firstIndex + i; - - if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS) - { - ASSERT(mSamplersPS[samplerIndex].active); - mSamplersPS[samplerIndex].logicalTextureUnit = v[i]; - } - } - } - else - { - ASSERT(targetUniform->ps.registerSet == D3DXRS_FLOAT4); - mDevice->SetPixelShaderConstantF(targetUniform->ps.registerIndex, (const float*)vector, targetUniform->ps.registerCount); - } - } - - if (targetUniform->vs.registerCount) - { - if (targetUniform->vs.registerSet == D3DXRS_SAMPLER) - { - unsigned int firstIndex = targetUniform->vs.registerIndex; - - for (int i = 0; i < count; i++) - { - unsigned int samplerIndex = firstIndex + i; - - if (samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF) - { - ASSERT(mSamplersVS[samplerIndex].active); - mSamplersVS[samplerIndex].logicalTextureUnit = v[i]; - } - } - } - else - { - ASSERT(targetUniform->vs.registerSet == D3DXRS_FLOAT4); - mDevice->SetVertexShaderConstantF(targetUniform->vs.registerIndex, (const float *)vector, targetUniform->vs.registerCount); - } - } - - return true; -} - -bool Program::applyUniform2iv(Uniform *targetUniform, GLsizei count, const GLint *v) -{ - ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); - D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS]; - - for (int i = 0; i < count; i++) - { - vector[i] = D3DXVECTOR4((float)v[0], (float)v[1], 0, 0); - - v += 2; - } - - applyUniformniv(targetUniform, count, vector); - - return true; -} - -bool Program::applyUniform3iv(Uniform *targetUniform, GLsizei count, const GLint *v) -{ - ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); - D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS]; - - for (int i = 0; i < count; i++) - { - vector[i] = D3DXVECTOR4((float)v[0], (float)v[1], (float)v[2], 0); - - v += 3; - } - - applyUniformniv(targetUniform, count, vector); - - return true; -} - -bool Program::applyUniform4iv(Uniform *targetUniform, GLsizei count, const GLint *v) -{ - ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); - D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS]; - - for (int i = 0; i < count; i++) - { - vector[i] = D3DXVECTOR4((float)v[0], (float)v[1], (float)v[2], (float)v[3]); - - v += 4; - } - - applyUniformniv(targetUniform, count, vector); - - return true; -} - -void Program::applyUniformniv(Uniform *targetUniform, GLsizei count, const D3DXVECTOR4 *vector) -{ - if (targetUniform->ps.registerCount) - { - ASSERT(targetUniform->ps.registerSet == D3DXRS_FLOAT4); - mDevice->SetPixelShaderConstantF(targetUniform->ps.registerIndex, (const float *)vector, targetUniform->ps.registerCount); - } - - if (targetUniform->vs.registerCount) - { - ASSERT(targetUniform->vs.registerSet == D3DXRS_FLOAT4); - mDevice->SetVertexShaderConstantF(targetUniform->vs.registerIndex, (const float *)vector, targetUniform->vs.registerCount); - } -} - -// append a santized message to the program info log. -// The D3D compiler includes a fake file path in some of the warning or error -// messages, so lets remove all occurrences of this fake file path from the log. -void Program::appendToInfoLogSanitized(const char *message) -{ - std::string msg(message); - - size_t found; - do - { - found = msg.find(fakepath); - if (found != std::string::npos) - { - msg.erase(found, strlen(fakepath)); - } - } - while (found != std::string::npos); - - appendToInfoLog("%s\n", msg.c_str()); -} - -void Program::appendToInfoLog(const char *format, ...) -{ - if (!format) - { - return; - } - - char info[1024]; - - va_list vararg; - va_start(vararg, format); - vsnprintf(info, sizeof(info), format, vararg); - va_end(vararg); - - size_t infoLength = strlen(info); - - if (!mInfoLog) - { - mInfoLog = new char[infoLength + 1]; - strcpy(mInfoLog, info); - } - else - { - size_t logLength = strlen(mInfoLog); - char *newLog = new char[logLength + infoLength + 1]; - strcpy(newLog, mInfoLog); - strcpy(newLog + logLength, info); - - delete[] mInfoLog; - mInfoLog = newLog; - } -} - -void Program::resetInfoLog() -{ - if (mInfoLog) - { - delete [] mInfoLog; - mInfoLog = NULL; - } -} - // Returns the program object to an unlinked state, before re-linking, or at destruction void Program::unlink(bool destroy) { @@ -2331,81 +286,22 @@ void Program::unlink(bool destroy) } } - if (mPixelExecutable) - { - mPixelExecutable->Release(); - mPixelExecutable = NULL; - } - - if (mVertexExecutable) - { - mVertexExecutable->Release(); - mVertexExecutable = NULL; - } - - if (mConstantTablePS) - { - mConstantTablePS->Release(); - mConstantTablePS = NULL; - } - - if (mConstantTableVS) - { - mConstantTableVS->Release(); - mConstantTableVS = NULL; - } - - for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++) - { - mLinkedAttribute[index].name.clear(); - mSemanticIndex[index] = -1; - } - - for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++) - { - mSamplersPS[index].active = false; - } - - for (int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; index++) + if (mProgramBinary) { - mSamplersVS[index].active = false; + delete mProgramBinary; + mProgramBinary = NULL; } - - mUsedVertexSamplerRange = 0; - mUsedPixelSamplerRange = 0; - - while (!mUniforms.empty()) - { - delete mUniforms.back(); - mUniforms.pop_back(); - } - - mDxDepthRangeLocation = -1; - mDxDepthLocation = -1; - mDxCoordLocation = -1; - mDxHalfPixelSizeLocation = -1; - mDxFrontCCWLocation = -1; - mDxPointsOrLinesLocation = -1; - - mUniformIndex.clear(); - - mPixelHLSL.clear(); - mVertexHLSL.clear(); - - delete[] mInfoLog; - mInfoLog = NULL; - - mLinked = false; } -bool Program::isLinked() +ProgramBinary* Program::getProgramBinary() { - return mLinked; + return mProgramBinary; } -bool Program::isValidated() const +void Program::setProgramBinary(ProgramBinary *programBinary) { - return mValidated; + unlink(false); + mProgramBinary = programBinary; } void Program::release() @@ -2440,35 +336,12 @@ unsigned int Program::issueSerial() int Program::getInfoLogLength() const { - if (!mInfoLog) - { - return 0; - } - else - { - return strlen(mInfoLog) + 1; - } + return mInfoLog.getLength(); } void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) { - int index = 0; - - if (mInfoLog) - { - index = std::min(bufSize - 1, (int)strlen(mInfoLog)); - memcpy(infoLog, mInfoLog, index); - } - - if (bufSize) - { - infoLog[index] = '\0'; - } - - if (length) - { - *length = index; - } + return mInfoLog.getLog(bufSize, length, infoLog); } void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders) @@ -2503,152 +376,96 @@ void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shade void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) { - // Skip over inactive attributes - unsigned int activeAttribute = 0; - unsigned int attribute; - for (attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++) + if (mProgramBinary) { - if (mLinkedAttribute[attribute].name.empty()) - { - continue; - } - - if (activeAttribute == index) - { - break; - } - - activeAttribute++; + mProgramBinary->getActiveAttribute(index, bufsize, length, size, type, name); } - - if (bufsize > 0) + else { - const char *string = mLinkedAttribute[attribute].name.c_str(); - - strncpy(name, string, bufsize); - name[bufsize - 1] = '\0'; - + if (bufsize > 0) + { + name[0] = '\0'; + } + if (length) { - *length = strlen(name); + *length = 0; } - } - - *size = 1; // Always a single 'type' instance - *type = mLinkedAttribute[attribute].type; + *type = GL_NONE; + *size = 1; + } } GLint Program::getActiveAttributeCount() { - int count = 0; - - for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) + if (mProgramBinary) { - if (!mLinkedAttribute[attributeIndex].name.empty()) - { - count++; - } + return mProgramBinary->getActiveAttributeCount(); + } + else + { + return 0; } - - return count; } GLint Program::getActiveAttributeMaxLength() { - int maxLength = 0; - - for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) + if (mProgramBinary) { - if (!mLinkedAttribute[attributeIndex].name.empty()) - { - maxLength = std::max((int)(mLinkedAttribute[attributeIndex].name.length() + 1), maxLength); - } + return mProgramBinary->getActiveAttributeMaxLength(); + } + else + { + return 0; } - - return maxLength; } void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) { - // Skip over internal uniforms - unsigned int activeUniform = 0; - unsigned int uniform; - for (uniform = 0; uniform < mUniforms.size(); uniform++) + if (mProgramBinary) { - if (mUniforms[uniform]->name.compare(0, 3, "dx_") == 0) - { - continue; - } - - if (activeUniform == index) - { - break; - } - - activeUniform++; + return mProgramBinary->getActiveUniform(index, bufsize, length, size, type, name); } - - ASSERT(uniform < mUniforms.size()); // index must be smaller than getActiveUniformCount() - - if (bufsize > 0) + else { - std::string string = mUniforms[uniform]->name; - - if (mUniforms[uniform]->isArray()) + if (bufsize > 0) { - string += "[0]"; + name[0] = '\0'; } - strncpy(name, string.c_str(), bufsize); - name[bufsize - 1] = '\0'; - if (length) { - *length = strlen(name); + *length = 0; } - } - - *size = mUniforms[uniform]->arraySize; - *type = mUniforms[uniform]->type; + *size = 0; + *type = GL_NONE; + } } GLint Program::getActiveUniformCount() { - int count = 0; - - unsigned int numUniforms = mUniforms.size(); - for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++) + if (mProgramBinary) { - if (mUniforms[uniformIndex]->name.compare(0, 3, "dx_") != 0) - { - count++; - } + return mProgramBinary->getActiveUniformCount(); + } + else + { + return 0; } - - return count; } GLint Program::getActiveUniformMaxLength() { - int maxLength = 0; - - unsigned int numUniforms = mUniforms.size(); - for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++) + if (mProgramBinary) { - if (!mUniforms[uniformIndex]->name.empty() && mUniforms[uniformIndex]->name.compare(0, 3, "dx_") != 0) - { - int length = (int)(mUniforms[uniformIndex]->name.length() + 1); - if (mUniforms[uniformIndex]->isArray()) - { - length += 3; // Counting in "[0]". - } - maxLength = std::max(length, maxLength); - } + return mProgramBinary->getActiveUniformMaxLength(); + } + else + { + return 0; } - - return maxLength; } void Program::flagForDeletion() @@ -2663,161 +480,28 @@ bool Program::isFlaggedForDeletion() const void Program::validate() { - resetInfoLog(); + mInfoLog.reset(); - if (!isLinked()) + if (mProgramBinary) { - appendToInfoLog("Program has not been successfully linked."); - mValidated = false; + mProgramBinary->validate(mInfoLog); } else { - applyUniforms(); - if (!validateSamplers(true)) - { - mValidated = false; - } - else - { - mValidated = true; - } - } -} - -bool Program::validateSamplers(bool logErrors) -{ - // if any two active samplers in a program are of different types, but refer to the same - // texture image unit, and this is the current program, then ValidateProgram will fail, and - // DrawArrays and DrawElements will issue the INVALID_OPERATION error. - - const unsigned int maxCombinedTextureImageUnits = getContext()->getMaximumCombinedTextureImageUnits(); - TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF]; - - for (unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF; ++i) - { - textureUnitType[i] = TEXTURE_UNKNOWN; + mInfoLog.append("Program has not been successfully linked."); } - - for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i) - { - if (mSamplersPS[i].active) - { - unsigned int unit = mSamplersPS[i].logicalTextureUnit; - - if (unit >= maxCombinedTextureImageUnits) - { - if (logErrors) - { - appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits); - } - - return false; - } - - if (textureUnitType[unit] != TEXTURE_UNKNOWN) - { - if (mSamplersPS[i].textureType != textureUnitType[unit]) - { - if (logErrors) - { - appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit); - } - - return false; - } - } - else - { - textureUnitType[unit] = mSamplersPS[i].textureType; - } - } - } - - for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i) - { - if (mSamplersVS[i].active) - { - unsigned int unit = mSamplersVS[i].logicalTextureUnit; - - if (unit >= maxCombinedTextureImageUnits) - { - if (logErrors) - { - appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits); - } - - return false; - } - - if (textureUnitType[unit] != TEXTURE_UNKNOWN) - { - if (mSamplersVS[i].textureType != textureUnitType[unit]) - { - if (logErrors) - { - appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit); - } - - return false; - } - } - else - { - textureUnitType[unit] = mSamplersVS[i].textureType; - } - } - } - - return true; } -void Program::initializeConstantHandles(Uniform *targetUniform, Uniform::RegisterInfo *ri, ID3DXConstantTable *constantTable) +bool Program::isValidated() const { - D3DXHANDLE handle = constantTable->GetConstantByName(0, targetUniform->_name.c_str()); - if (handle) + if (mProgramBinary) { - UINT descriptionCount = 1; - D3DXCONSTANT_DESC constantDescription; - HRESULT result = constantTable->GetConstantDesc(handle, &constantDescription, &descriptionCount); - ASSERT(SUCCEEDED(result)); - ri->registerIndex = constantDescription.RegisterIndex; - ri->registerCount = constantDescription.RegisterCount; - ri->registerSet = constantDescription.RegisterSet; + return mProgramBinary->isValidated(); } else { - ri->registerCount = 0; + return false; } } -GLint Program::getDxDepthRangeLocation() const -{ - return mDxDepthRangeLocation; -} - -GLint Program::getDxDepthLocation() const -{ - return mDxDepthLocation; -} - -GLint Program::getDxCoordLocation() const -{ - return mDxCoordLocation; -} - -GLint Program::getDxHalfPixelSizeLocation() const -{ - return mDxHalfPixelSizeLocation; -} - -GLint Program::getDxFrontCCWLocation() const -{ - return mDxFrontCCWLocation; -} - -GLint Program::getDxPointsOrLinesLocation() const -{ - return mDxPointsOrLinesLocation; -} - } diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Program.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Program.h index 61830c61c..244731d24 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Program.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Program.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -11,9 +11,7 @@ #define LIBGLESV2_PROGRAM_H_ #include <d3dx9.h> -#include <d3dcompiler.h> #include <string> -#include <vector> #include <set> #include "libGLESv2/Shader.h" @@ -25,42 +23,36 @@ class ResourceManager; class FragmentShader; class VertexShader; -// Helper struct representing a single shader uniform -struct Uniform -{ - Uniform(GLenum type, const std::string &_name, unsigned int arraySize); - - ~Uniform(); - - bool isArray(); - - const GLenum type; - const std::string _name; // Decorated name - const std::string name; // Undecorated name - const unsigned int arraySize; +extern const char * const g_fakepath; - unsigned char *data; - bool dirty; +class AttributeBindings +{ + public: + AttributeBindings(); + ~AttributeBindings(); - struct RegisterInfo - { - int registerSet; - int registerIndex; - int registerCount; - }; + void bindAttributeLocation(GLuint index, const char *name); + int getAttributeBinding(const std::string &name) const; - RegisterInfo ps; - RegisterInfo vs; + private: + std::set<std::string> mAttributeBinding[MAX_VERTEX_ATTRIBS]; }; -// Struct used for correlating uniforms/elements of uniform arrays to handles -struct UniformLocation +class InfoLog { - UniformLocation(const std::string &_name, unsigned int element, unsigned int index); + public: + InfoLog(); + ~InfoLog(); - std::string name; - unsigned int element; - unsigned int index; + int getLength() const; + void getLog(GLsizei bufSize, GLsizei *length, char *infoLog); + + void appendSanitized(const char *message); + void append(const char *info, ...); + void reset(); + private: + DISALLOW_COPY_AND_ASSIGN(InfoLog); + char *mInfoLog; }; class Program @@ -74,45 +66,12 @@ class Program bool detachShader(Shader *shader); int getAttachedShadersCount() const; - IDirect3DPixelShader9 *getPixelShader(); - IDirect3DVertexShader9 *getVertexShader(); - void bindAttributeLocation(GLuint index, const char *name); - GLuint getAttributeLocation(const char *name); - int getSemanticIndex(int attributeIndex); - - GLint getSamplerMapping(SamplerType type, unsigned int samplerIndex); - TextureType getSamplerTextureType(SamplerType type, unsigned int samplerIndex); - GLint getUsedSamplerRange(SamplerType type); - - GLint getUniformLocation(std::string name); - bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v); - bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v); - bool setUniform3fv(GLint location, GLsizei count, const GLfloat *v); - bool setUniform4fv(GLint location, GLsizei count, const GLfloat *v); - bool setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value); - bool setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value); - bool setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value); - bool setUniform1iv(GLint location, GLsizei count, const GLint *v); - bool setUniform2iv(GLint location, GLsizei count, const GLint *v); - bool setUniform3iv(GLint location, GLsizei count, const GLint *v); - bool setUniform4iv(GLint location, GLsizei count, const GLint *v); - - bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params); - bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params); - - GLint getDxDepthRangeLocation() const; - GLint getDxDepthLocation() const; - GLint getDxCoordLocation() const; - GLint getDxHalfPixelSizeLocation() const; - GLint getDxFrontCCWLocation() const; - GLint getDxPointsOrLinesLocation() const; - - void dirtyAllUniforms(); - void applyUniforms(); void link(); - bool isLinked(); + void setProgramBinary(ProgramBinary *programBinary); + ProgramBinary *getProgramBinary(); + int getInfoLogLength() const; void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog); void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders); @@ -132,90 +91,24 @@ class Program bool isFlaggedForDeletion() const; void validate(); - bool validateSamplers(bool logErrors); bool isValidated() const; unsigned int getSerial() const; - static std::string decorateAttribute(const std::string &name); // Prepend an underscore - static std::string undecorateUniform(const std::string &_name); // Remove leading underscore - private: DISALLOW_COPY_AND_ASSIGN(Program); - ID3D10Blob *compileToBinary(const char *hlsl, const char *profile, ID3DXConstantTable **constantTable); void unlink(bool destroy = false); - int packVaryings(const Varying *packing[][4]); - bool linkVaryings(); - - bool linkAttributes(); - int getAttributeBinding(const std::string &name); - - bool linkUniforms(ID3DXConstantTable *constantTable); - bool defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name = ""); - bool defineUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &name); - Uniform *createUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &name); - bool applyUniformnfv(Uniform *targetUniform, const GLfloat *v); - bool applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint *v); - bool applyUniform2iv(Uniform *targetUniform, GLsizei count, const GLint *v); - bool applyUniform3iv(Uniform *targetUniform, GLsizei count, const GLint *v); - bool applyUniform4iv(Uniform *targetUniform, GLsizei count, const GLint *v); - void applyUniformniv(Uniform *targetUniform, GLsizei count, const D3DXVECTOR4 *vector); - void applyUniformnbv(Uniform *targetUniform, GLsizei count, int width, const GLboolean *v); - - void initializeConstantHandles(Uniform *targetUniform, Uniform::RegisterInfo *rs, ID3DXConstantTable *constantTable); - - void appendToInfoLogSanitized(const char *message); - void appendToInfoLog(const char *info, ...); - void resetInfoLog(); - static unsigned int issueSerial(); - IDirect3DDevice9 *mDevice; FragmentShader *mFragmentShader; VertexShader *mVertexShader; - std::string mPixelHLSL; - std::string mVertexHLSL; - - IDirect3DPixelShader9 *mPixelExecutable; - IDirect3DVertexShader9 *mVertexExecutable; - ID3DXConstantTable *mConstantTablePS; - ID3DXConstantTable *mConstantTableVS; + AttributeBindings mAttributeBindings; - std::set<std::string> mAttributeBinding[MAX_VERTEX_ATTRIBS]; - Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS]; - int mSemanticIndex[MAX_VERTEX_ATTRIBS]; - - struct Sampler - { - bool active; - GLint logicalTextureUnit; - TextureType textureType; - }; - - Sampler mSamplersPS[MAX_TEXTURE_IMAGE_UNITS]; - Sampler mSamplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF]; - GLuint mUsedVertexSamplerRange; - GLuint mUsedPixelSamplerRange; - - typedef std::vector<Uniform*> UniformArray; - UniformArray mUniforms; - typedef std::vector<UniformLocation> UniformIndex; - UniformIndex mUniformIndex; - - GLint mDxDepthRangeLocation; - GLint mDxDepthLocation; - GLint mDxCoordLocation; - GLint mDxHalfPixelSizeLocation; - GLint mDxFrontCCWLocation; - GLint mDxPointsOrLinesLocation; - - bool mLinked; + ProgramBinary* mProgramBinary; bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use - char *mInfoLog; - bool mValidated; unsigned int mRefCount; @@ -225,6 +118,8 @@ class Program ResourceManager *mResourceManager; const GLuint mHandle; + + InfoLog mInfoLog; }; } diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/ProgramBinary.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/ProgramBinary.cpp new file mode 100644 index 000000000..ac28e5181 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/ProgramBinary.cpp @@ -0,0 +1,2480 @@ +// +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Program.cpp: Implements the gl::Program class. Implements GL program objects +// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28. + +#include "libGLESv2/Program.h" +#include "libGLESv2/ProgramBinary.h" + +#include "common/debug.h" + +#include "libGLESv2/main.h" +#include "libGLESv2/Shader.h" +#include "libGLESv2/utilities.h" + +#include <string> + +#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) +#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3 +#endif + +namespace gl +{ +std::string str(int i) +{ + char buffer[20]; + snprintf(buffer, sizeof(buffer), "%d", i); + return buffer; +} + +Uniform::Uniform(GLenum type, const std::string &_name, unsigned int arraySize) + : type(type), _name(_name), name(ProgramBinary::undecorateUniform(_name)), arraySize(arraySize) +{ + int bytes = UniformInternalSize(type) * arraySize; + data = new unsigned char[bytes]; + memset(data, 0, bytes); + dirty = true; +} + +Uniform::~Uniform() +{ + delete[] data; +} + +bool Uniform::isArray() +{ + return _name.compare(0, 3, "ar_") == 0; +} + +UniformLocation::UniformLocation(const std::string &_name, unsigned int element, unsigned int index) + : name(ProgramBinary::undecorateUniform(_name)), element(element), index(index) +{ +} + +ProgramBinary::ProgramBinary() +{ + mDevice = getDevice(); + + mPixelExecutable = NULL; + mVertexExecutable = NULL; + mConstantTablePS = NULL; + mConstantTableVS = NULL; + + mValidated = false; + + for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++) + { + mSemanticIndex[index] = -1; + } + + for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++) + { + mSamplersPS[index].active = false; + } + + for (int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; index++) + { + mSamplersVS[index].active = false; + } + + mUsedVertexSamplerRange = 0; + mUsedPixelSamplerRange = 0; + + mDxDepthRangeLocation = -1; + mDxDepthLocation = -1; + mDxCoordLocation = -1; + mDxHalfPixelSizeLocation = -1; + mDxFrontCCWLocation = -1; + mDxPointsOrLinesLocation = -1; +} + +ProgramBinary::~ProgramBinary() +{ + if (mPixelExecutable) + { + mPixelExecutable->Release(); + } + + if (mVertexExecutable) + { + mVertexExecutable->Release(); + } + + if (mConstantTablePS) + { + mConstantTablePS->Release(); + } + + if (mConstantTableVS) + { + mConstantTableVS->Release(); + } + + while (!mUniforms.empty()) + { + delete mUniforms.back(); + mUniforms.pop_back(); + } +} + +IDirect3DPixelShader9 *ProgramBinary::getPixelShader() +{ + return mPixelExecutable; +} + +IDirect3DVertexShader9 *ProgramBinary::getVertexShader() +{ + return mVertexExecutable; +} + +GLuint ProgramBinary::getAttributeLocation(const char *name) +{ + if (name) + { + for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++) + { + if (mLinkedAttribute[index].name == std::string(name)) + { + return index; + } + } + } + + return -1; +} + +int ProgramBinary::getSemanticIndex(int attributeIndex) +{ + ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS); + + return mSemanticIndex[attributeIndex]; +} + +// Returns one more than the highest sampler index used. +GLint ProgramBinary::getUsedSamplerRange(SamplerType type) +{ + switch (type) + { + case SAMPLER_PIXEL: + return mUsedPixelSamplerRange; + case SAMPLER_VERTEX: + return mUsedVertexSamplerRange; + default: + UNREACHABLE(); + return 0; + } +} + +// Returns the index of the texture image unit (0-19) corresponding to a Direct3D 9 sampler +// index (0-15 for the pixel shader and 0-3 for the vertex shader). +GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex) +{ + GLint logicalTextureUnit = -1; + + switch (type) + { + case SAMPLER_PIXEL: + ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0])); + + if (mSamplersPS[samplerIndex].active) + { + logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit; + } + break; + case SAMPLER_VERTEX: + ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0])); + + if (mSamplersVS[samplerIndex].active) + { + logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit; + } + break; + default: UNREACHABLE(); + } + + if (logicalTextureUnit >= 0 && logicalTextureUnit < (GLint)getContext()->getMaximumCombinedTextureImageUnits()) + { + return logicalTextureUnit; + } + + return -1; +} + +// Returns the texture type for a given Direct3D 9 sampler type and +// index (0-15 for the pixel shader and 0-3 for the vertex shader). +TextureType ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex) +{ + switch (type) + { + case SAMPLER_PIXEL: + ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0])); + ASSERT(mSamplersPS[samplerIndex].active); + return mSamplersPS[samplerIndex].textureType; + case SAMPLER_VERTEX: + ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0])); + ASSERT(mSamplersVS[samplerIndex].active); + return mSamplersVS[samplerIndex].textureType; + default: UNREACHABLE(); + } + + return TEXTURE_2D; +} + +GLint ProgramBinary::getUniformLocation(std::string name) +{ + unsigned int subscript = 0; + + // Strip any trailing array operator and retrieve the subscript + size_t open = name.find_last_of('['); + size_t close = name.find_last_of(']'); + if (open != std::string::npos && close == name.length() - 1) + { + subscript = atoi(name.substr(open + 1).c_str()); + name.erase(open); + } + + unsigned int numUniforms = mUniformIndex.size(); + for (unsigned int location = 0; location < numUniforms; location++) + { + if (mUniformIndex[location].name == name && + mUniformIndex[location].element == subscript) + { + return location; + } + } + + return -1; +} + +bool ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) +{ + if (location < 0 || location >= (int)mUniformIndex.size()) + { + return false; + } + + Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; + targetUniform->dirty = true; + + if (targetUniform->type == GL_FLOAT) + { + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + + GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; + + for (int i = 0; i < count; i++) + { + target[0] = v[0]; + target[1] = 0; + target[2] = 0; + target[3] = 0; + target += 4; + v += 1; + } + } + else if (targetUniform->type == GL_BOOL) + { + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element; + + for (int i = 0; i < count; ++i) + { + if (v[i] == 0.0f) + { + boolParams[i] = GL_FALSE; + } + else + { + boolParams[i] = GL_TRUE; + } + } + } + else + { + return false; + } + + return true; +} + +bool ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) +{ + if (location < 0 || location >= (int)mUniformIndex.size()) + { + return false; + } + + Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; + targetUniform->dirty = true; + + if (targetUniform->type == GL_FLOAT_VEC2) + { + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + + GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; + + for (int i = 0; i < count; i++) + { + target[0] = v[0]; + target[1] = v[1]; + target[2] = 0; + target[3] = 0; + target += 4; + v += 2; + } + } + else if (targetUniform->type == GL_BOOL_VEC2) + { + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 2; + + for (int i = 0; i < count * 2; ++i) + { + if (v[i] == 0.0f) + { + boolParams[i] = GL_FALSE; + } + else + { + boolParams[i] = GL_TRUE; + } + } + } + else + { + return false; + } + + return true; +} + +bool ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) +{ + if (location < 0 || location >= (int)mUniformIndex.size()) + { + return false; + } + + Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; + targetUniform->dirty = true; + + if (targetUniform->type == GL_FLOAT_VEC3) + { + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + + GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; + + for (int i = 0; i < count; i++) + { + target[0] = v[0]; + target[1] = v[1]; + target[2] = v[2]; + target[3] = 0; + target += 4; + v += 3; + } + } + else if (targetUniform->type == GL_BOOL_VEC3) + { + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 3; + + for (int i = 0; i < count * 3; ++i) + { + if (v[i] == 0.0f) + { + boolParams[i] = GL_FALSE; + } + else + { + boolParams[i] = GL_TRUE; + } + } + } + else + { + return false; + } + + return true; +} + +bool ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) +{ + if (location < 0 || location >= (int)mUniformIndex.size()) + { + return false; + } + + Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; + targetUniform->dirty = true; + + if (targetUniform->type == GL_FLOAT_VEC4) + { + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + + memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 4, + v, 4 * sizeof(GLfloat) * count); + } + else if (targetUniform->type == GL_BOOL_VEC4) + { + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 4; + + for (int i = 0; i < count * 4; ++i) + { + if (v[i] == 0.0f) + { + boolParams[i] = GL_FALSE; + } + else + { + boolParams[i] = GL_TRUE; + } + } + } + else + { + return false; + } + + return true; +} + +template<typename T, int targetWidth, int targetHeight, int srcWidth, int srcHeight> +void transposeMatrix(T *target, const GLfloat *value) +{ + int copyWidth = std::min(targetWidth, srcWidth); + int copyHeight = std::min(targetHeight, srcHeight); + + for (int x = 0; x < copyWidth; x++) + { + for (int y = 0; y < copyHeight; y++) + { + target[x * targetWidth + y] = (T)value[y * srcWidth + x]; + } + } + // clear unfilled right side + for (int y = 0; y < copyHeight; y++) + { + for (int x = srcWidth; x < targetWidth; x++) + { + target[y * targetWidth + x] = (T)0; + } + } + // clear unfilled bottom. + for (int y = srcHeight; y < targetHeight; y++) + { + for (int x = 0; x < targetWidth; x++) + { + target[y * targetWidth + x] = (T)0; + } + } +} + +bool ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) +{ + if (location < 0 || location >= (int)mUniformIndex.size()) + { + return false; + } + + Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; + targetUniform->dirty = true; + + if (targetUniform->type != GL_FLOAT_MAT2) + { + return false; + } + + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + + GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8; + for (int i = 0; i < count; i++) + { + transposeMatrix<GLfloat,4,2,2,2>(target, value); + target += 8; + value += 4; + } + + return true; +} + +bool ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) +{ + if (location < 0 || location >= (int)mUniformIndex.size()) + { + return false; + } + + Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; + targetUniform->dirty = true; + + if (targetUniform->type != GL_FLOAT_MAT3) + { + return false; + } + + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + + GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12; + for (int i = 0; i < count; i++) + { + transposeMatrix<GLfloat,4,3,3,3>(target, value); + target += 12; + value += 9; + } + + return true; +} + + +bool ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) +{ + if (location < 0 || location >= (int)mUniformIndex.size()) + { + return false; + } + + Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; + targetUniform->dirty = true; + + if (targetUniform->type != GL_FLOAT_MAT4) + { + return false; + } + + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + + GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 16); + for (int i = 0; i < count; i++) + { + transposeMatrix<GLfloat,4,4,4,4>(target, value); + target += 16; + value += 16; + } + + return true; +} + +bool ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v) +{ + if (location < 0 || location >= (int)mUniformIndex.size()) + { + return false; + } + + Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; + targetUniform->dirty = true; + + if (targetUniform->type == GL_INT || + targetUniform->type == GL_SAMPLER_2D || + targetUniform->type == GL_SAMPLER_CUBE) + { + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + + memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLint), + v, sizeof(GLint) * count); + } + else if (targetUniform->type == GL_BOOL) + { + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element; + + for (int i = 0; i < count; ++i) + { + if (v[i] == 0) + { + boolParams[i] = GL_FALSE; + } + else + { + boolParams[i] = GL_TRUE; + } + } + } + else + { + return false; + } + + return true; +} + +bool ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v) +{ + if (location < 0 || location >= (int)mUniformIndex.size()) + { + return false; + } + + Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; + targetUniform->dirty = true; + + if (targetUniform->type == GL_INT_VEC2) + { + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + + memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLint) * 2, + v, 2 * sizeof(GLint) * count); + } + else if (targetUniform->type == GL_BOOL_VEC2) + { + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 2; + + for (int i = 0; i < count * 2; ++i) + { + if (v[i] == 0) + { + boolParams[i] = GL_FALSE; + } + else + { + boolParams[i] = GL_TRUE; + } + } + } + else + { + return false; + } + + return true; +} + +bool ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v) +{ + if (location < 0 || location >= (int)mUniformIndex.size()) + { + return false; + } + + Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; + targetUniform->dirty = true; + + if (targetUniform->type == GL_INT_VEC3) + { + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + + memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLint) * 3, + v, 3 * sizeof(GLint) * count); + } + else if (targetUniform->type == GL_BOOL_VEC3) + { + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 3; + + for (int i = 0; i < count * 3; ++i) + { + if (v[i] == 0) + { + boolParams[i] = GL_FALSE; + } + else + { + boolParams[i] = GL_TRUE; + } + } + } + else + { + return false; + } + + return true; +} + +bool ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v) +{ + if (location < 0 || location >= (int)mUniformIndex.size()) + { + return false; + } + + Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; + targetUniform->dirty = true; + + if (targetUniform->type == GL_INT_VEC4) + { + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + + memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLint) * 4, + v, 4 * sizeof(GLint) * count); + } + else if (targetUniform->type == GL_BOOL_VEC4) + { + int arraySize = targetUniform->arraySize; + + if (arraySize == 1 && count > 1) + return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION + + count = std::min(arraySize - (int)mUniformIndex[location].element, count); + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 4; + + for (int i = 0; i < count * 4; ++i) + { + if (v[i] == 0) + { + boolParams[i] = GL_FALSE; + } + else + { + boolParams[i] = GL_TRUE; + } + } + } + else + { + return false; + } + + return true; +} + +bool ProgramBinary::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params) +{ + if (location < 0 || location >= (int)mUniformIndex.size()) + { + return false; + } + + Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; + + // sized queries -- ensure the provided buffer is large enough + if (bufSize) + { + int requiredBytes = UniformExternalSize(targetUniform->type); + if (*bufSize < requiredBytes) + { + return false; + } + } + + switch (targetUniform->type) + { + case GL_FLOAT_MAT2: + transposeMatrix<GLfloat,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8); + break; + case GL_FLOAT_MAT3: + transposeMatrix<GLfloat,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12); + break; + case GL_FLOAT_MAT4: + transposeMatrix<GLfloat,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16); + break; + default: + { + unsigned int count = UniformExternalComponentCount(targetUniform->type); + unsigned int internalCount = UniformInternalComponentCount(targetUniform->type); + + switch (UniformComponentType(targetUniform->type)) + { + case GL_BOOL: + { + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * internalCount; + + for (unsigned int i = 0; i < count; ++i) + { + params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f; + } + } + break; + case GL_FLOAT: + memcpy(params, targetUniform->data + mUniformIndex[location].element * internalCount * sizeof(GLfloat), + count * sizeof(GLfloat)); + break; + case GL_INT: + { + GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * internalCount; + + for (unsigned int i = 0; i < count; ++i) + { + params[i] = (float)intParams[i]; + } + } + break; + default: UNREACHABLE(); + } + } + } + + return true; +} + +bool ProgramBinary::getUniformiv(GLint location, GLsizei *bufSize, GLint *params) +{ + if (location < 0 || location >= (int)mUniformIndex.size()) + { + return false; + } + + Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; + + // sized queries -- ensure the provided buffer is large enough + if (bufSize) + { + int requiredBytes = UniformExternalSize(targetUniform->type); + if (*bufSize < requiredBytes) + { + return false; + } + } + + switch (targetUniform->type) + { + case GL_FLOAT_MAT2: + { + transposeMatrix<GLint,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8); + } + break; + case GL_FLOAT_MAT3: + { + transposeMatrix<GLint,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12); + } + break; + case GL_FLOAT_MAT4: + { + transposeMatrix<GLint,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16); + } + break; + default: + { + unsigned int count = UniformExternalComponentCount(targetUniform->type); + unsigned int internalCount = UniformInternalComponentCount(targetUniform->type); + + switch (UniformComponentType(targetUniform->type)) + { + case GL_BOOL: + { + GLboolean *boolParams = targetUniform->data + mUniformIndex[location].element * internalCount; + + for (unsigned int i = 0; i < count; ++i) + { + params[i] = (GLint)boolParams[i]; + } + } + break; + case GL_FLOAT: + { + GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * internalCount; + + for (unsigned int i = 0; i < count; ++i) + { + params[i] = (GLint)floatParams[i]; + } + } + break; + case GL_INT: + memcpy(params, targetUniform->data + mUniformIndex[location].element * internalCount * sizeof(GLint), + count * sizeof(GLint)); + break; + default: UNREACHABLE(); + } + } + } + + return true; +} + +void ProgramBinary::dirtyAllUniforms() +{ + unsigned int numUniforms = mUniforms.size(); + for (unsigned int index = 0; index < numUniforms; index++) + { + mUniforms[index]->dirty = true; + } +} + +// Applies all the uniforms set for this program object to the Direct3D 9 device +void ProgramBinary::applyUniforms() +{ + for (std::vector<Uniform*>::iterator ub = mUniforms.begin(), ue = mUniforms.end(); ub != ue; ++ub) { + Uniform *targetUniform = *ub; + + if (targetUniform->dirty) + { + int arraySize = targetUniform->arraySize; + GLfloat *f = (GLfloat*)targetUniform->data; + GLint *i = (GLint*)targetUniform->data; + GLboolean *b = (GLboolean*)targetUniform->data; + + switch (targetUniform->type) + { + case GL_BOOL: applyUniformnbv(targetUniform, arraySize, 1, b); break; + case GL_BOOL_VEC2: applyUniformnbv(targetUniform, arraySize, 2, b); break; + case GL_BOOL_VEC3: applyUniformnbv(targetUniform, arraySize, 3, b); break; + case GL_BOOL_VEC4: applyUniformnbv(targetUniform, arraySize, 4, b); break; + case GL_FLOAT: + case GL_FLOAT_VEC2: + case GL_FLOAT_VEC3: + case GL_FLOAT_VEC4: + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT4: applyUniformnfv(targetUniform, f); break; + case GL_SAMPLER_2D: + case GL_SAMPLER_CUBE: + case GL_INT: applyUniform1iv(targetUniform, arraySize, i); break; + case GL_INT_VEC2: applyUniform2iv(targetUniform, arraySize, i); break; + case GL_INT_VEC3: applyUniform3iv(targetUniform, arraySize, i); break; + case GL_INT_VEC4: applyUniform4iv(targetUniform, arraySize, i); break; + default: + UNREACHABLE(); + } + + targetUniform->dirty = false; + } + } +} + +// Compiles the HLSL code of the attached shaders into executable binaries +ID3D10Blob *ProgramBinary::compileToBinary(InfoLog &infoLog, const char *hlsl, const char *profile, ID3DXConstantTable **constantTable) +{ + if (!hlsl) + { + return NULL; + } + + DWORD result; + UINT flags = 0; + std::string sourceText; + if (perfActive()) + { + flags |= D3DCOMPILE_DEBUG; +#ifdef NDEBUG + flags |= ANGLE_COMPILE_OPTIMIZATION_LEVEL; +#else + flags |= D3DCOMPILE_SKIP_OPTIMIZATION; +#endif + + std::string sourcePath = getTempPath(); + sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(hlsl); + writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); + } + else + { + flags |= ANGLE_COMPILE_OPTIMIZATION_LEVEL; + sourceText = hlsl; + } + + ID3D10Blob *binary = NULL; + ID3D10Blob *errorMessage = NULL; + result = D3DCompile(hlsl, strlen(hlsl), g_fakepath, NULL, NULL, "main", profile, flags, 0, &binary, &errorMessage); + + if (errorMessage) + { + const char *message = (const char*)errorMessage->GetBufferPointer(); + + infoLog.appendSanitized(message); + TRACE("\n%s", hlsl); + TRACE("\n%s", message); + + errorMessage->Release(); + errorMessage = NULL; + } + + if (FAILED(result)) + { + if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) + { + error(GL_OUT_OF_MEMORY); + } + + return NULL; + } + + result = D3DXGetShaderConstantTable(static_cast<const DWORD*>(binary->GetBufferPointer()), constantTable); + + if (FAILED(result)) + { + if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) + { + error(GL_OUT_OF_MEMORY); + } + + binary->Release(); + + return NULL; + } + + return binary; +} + +// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111 +// Returns the number of used varying registers, or -1 if unsuccesful +int ProgramBinary::packVaryings(InfoLog &infoLog, const Varying *packing[][4], FragmentShader *fragmentShader) +{ + Context *context = getContext(); + const int maxVaryingVectors = context->getMaximumVaryingVectors(); + + for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++) + { + int n = VariableRowCount(varying->type) * varying->size; + int m = VariableColumnCount(varying->type); + bool success = false; + + if (m == 2 || m == 3 || m == 4) + { + for (int r = 0; r <= maxVaryingVectors - n && !success; r++) + { + bool available = true; + + for (int y = 0; y < n && available; y++) + { + for (int x = 0; x < m && available; x++) + { + if (packing[r + y][x]) + { + available = false; + } + } + } + + if (available) + { + varying->reg = r; + varying->col = 0; + + for (int y = 0; y < n; y++) + { + for (int x = 0; x < m; x++) + { + packing[r + y][x] = &*varying; + } + } + + success = true; + } + } + + if (!success && m == 2) + { + for (int r = maxVaryingVectors - n; r >= 0 && !success; r--) + { + bool available = true; + + for (int y = 0; y < n && available; y++) + { + for (int x = 2; x < 4 && available; x++) + { + if (packing[r + y][x]) + { + available = false; + } + } + } + + if (available) + { + varying->reg = r; + varying->col = 2; + + for (int y = 0; y < n; y++) + { + for (int x = 2; x < 4; x++) + { + packing[r + y][x] = &*varying; + } + } + + success = true; + } + } + } + } + else if (m == 1) + { + int space[4] = {0}; + + for (int y = 0; y < maxVaryingVectors; y++) + { + for (int x = 0; x < 4; x++) + { + space[x] += packing[y][x] ? 0 : 1; + } + } + + int column = 0; + + for (int x = 0; x < 4; x++) + { + if (space[x] >= n && space[x] < space[column]) + { + column = x; + } + } + + if (space[column] >= n) + { + for (int r = 0; r < maxVaryingVectors; r++) + { + if (!packing[r][column]) + { + varying->reg = r; + + for (int y = r; y < r + n; y++) + { + packing[y][column] = &*varying; + } + + break; + } + } + + varying->col = column; + + success = true; + } + } + else UNREACHABLE(); + + if (!success) + { + infoLog.append("Could not pack varying %s", varying->name.c_str()); + + return -1; + } + } + + // Return the number of used registers + int registers = 0; + + for (int r = 0; r < maxVaryingVectors; r++) + { + if (packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3]) + { + registers++; + } + } + + return registers; +} + +bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::string& vertexHLSL, FragmentShader *fragmentShader, VertexShader *vertexShader) +{ + if (pixelHLSL.empty() || vertexHLSL.empty()) + { + return false; + } + + // Reset the varying register assignments + for (VaryingList::iterator fragVar = fragmentShader->mVaryings.begin(); fragVar != fragmentShader->mVaryings.end(); fragVar++) + { + fragVar->reg = -1; + fragVar->col = -1; + } + + for (VaryingList::iterator vtxVar = vertexShader->mVaryings.begin(); vtxVar != vertexShader->mVaryings.end(); vtxVar++) + { + vtxVar->reg = -1; + vtxVar->col = -1; + } + + // Map the varyings to the register file + const Varying *packing[MAX_VARYING_VECTORS_SM3][4] = {NULL}; + int registers = packVaryings(infoLog, packing, fragmentShader); + + if (registers < 0) + { + return false; + } + + // Write the HLSL input/output declarations + Context *context = getContext(); + const bool sm3 = context->supportsShaderModel3(); + const int maxVaryingVectors = context->getMaximumVaryingVectors(); + + if (registers == maxVaryingVectors && fragmentShader->mUsesFragCoord) + { + infoLog.append("No varying registers left to support gl_FragCoord"); + + return false; + } + + for (VaryingList::iterator input = fragmentShader->mVaryings.begin(); input != fragmentShader->mVaryings.end(); input++) + { + bool matched = false; + + for (VaryingList::iterator output = vertexShader->mVaryings.begin(); output != vertexShader->mVaryings.end(); output++) + { + if (output->name == input->name) + { + if (output->type != input->type || output->size != input->size) + { + infoLog.append("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str()); + + return false; + } + + output->reg = input->reg; + output->col = input->col; + + matched = true; + break; + } + } + + if (!matched) + { + infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str()); + + return false; + } + } + + std::string varyingSemantic = (sm3 ? "COLOR" : "TEXCOORD"); + + vertexHLSL += "struct VS_INPUT\n" + "{\n"; + + int semanticIndex = 0; + for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++) + { + switch (attribute->type) + { + case GL_FLOAT: vertexHLSL += " float "; break; + case GL_FLOAT_VEC2: vertexHLSL += " float2 "; break; + case GL_FLOAT_VEC3: vertexHLSL += " float3 "; break; + case GL_FLOAT_VEC4: vertexHLSL += " float4 "; break; + case GL_FLOAT_MAT2: vertexHLSL += " float2x2 "; break; + case GL_FLOAT_MAT3: vertexHLSL += " float3x3 "; break; + case GL_FLOAT_MAT4: vertexHLSL += " float4x4 "; break; + default: UNREACHABLE(); + } + + vertexHLSL += decorateAttribute(attribute->name) + " : TEXCOORD" + str(semanticIndex) + ";\n"; + + semanticIndex += VariableRowCount(attribute->type); + } + + vertexHLSL += "};\n" + "\n" + "struct VS_OUTPUT\n" + "{\n" + " float4 gl_Position : POSITION;\n"; + + for (int r = 0; r < registers; r++) + { + int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1)); + + vertexHLSL += " float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n"; + } + + if (fragmentShader->mUsesFragCoord) + { + vertexHLSL += " float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n"; + } + + if (vertexShader->mUsesPointSize && sm3) + { + vertexHLSL += " float gl_PointSize : PSIZE;\n"; + } + + vertexHLSL += "};\n" + "\n" + "VS_OUTPUT main(VS_INPUT input)\n" + "{\n"; + + for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++) + { + vertexHLSL += " " + decorateAttribute(attribute->name) + " = "; + + if (VariableRowCount(attribute->type) > 1) // Matrix + { + vertexHLSL += "transpose"; + } + + vertexHLSL += "(input." + decorateAttribute(attribute->name) + ");\n"; + } + + vertexHLSL += "\n" + " gl_main();\n" + "\n" + " VS_OUTPUT output;\n" + " output.gl_Position.x = gl_Position.x - dx_HalfPixelSize.x * gl_Position.w;\n" + " output.gl_Position.y = -(gl_Position.y + dx_HalfPixelSize.y * gl_Position.w);\n" + " output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n" + " output.gl_Position.w = gl_Position.w;\n"; + + if (vertexShader->mUsesPointSize && sm3) + { + vertexHLSL += " output.gl_PointSize = clamp(gl_PointSize, 1.0, " + str((int)ALIASED_POINT_SIZE_RANGE_MAX_SM3) + ");\n"; + } + + if (fragmentShader->mUsesFragCoord) + { + vertexHLSL += " output.gl_FragCoord = gl_Position;\n"; + } + + for (VaryingList::iterator varying = vertexShader->mVaryings.begin(); varying != vertexShader->mVaryings.end(); varying++) + { + if (varying->reg >= 0) + { + for (int i = 0; i < varying->size; i++) + { + int rows = VariableRowCount(varying->type); + + for (int j = 0; j < rows; j++) + { + int r = varying->reg + i * rows + j; + vertexHLSL += " output.v" + str(r); + + bool sharedRegister = false; // Register used by multiple varyings + + for (int x = 0; x < 4; x++) + { + if (packing[r][x] && packing[r][x] != packing[r][0]) + { + sharedRegister = true; + break; + } + } + + if(sharedRegister) + { + vertexHLSL += "."; + + for (int x = 0; x < 4; x++) + { + if (packing[r][x] == &*varying) + { + switch(x) + { + case 0: vertexHLSL += "x"; break; + case 1: vertexHLSL += "y"; break; + case 2: vertexHLSL += "z"; break; + case 3: vertexHLSL += "w"; break; + } + } + } + } + + vertexHLSL += " = " + varying->name; + + if (varying->array) + { + vertexHLSL += "[" + str(i) + "]"; + } + + if (rows > 1) + { + vertexHLSL += "[" + str(j) + "]"; + } + + vertexHLSL += ";\n"; + } + } + } + } + + vertexHLSL += "\n" + " return output;\n" + "}\n"; + + pixelHLSL += "struct PS_INPUT\n" + "{\n"; + + for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++) + { + if (varying->reg >= 0) + { + for (int i = 0; i < varying->size; i++) + { + int rows = VariableRowCount(varying->type); + for (int j = 0; j < rows; j++) + { + std::string n = str(varying->reg + i * rows + j); + pixelHLSL += " float4 v" + n + " : " + varyingSemantic + n + ";\n"; + } + } + } + else UNREACHABLE(); + } + + if (fragmentShader->mUsesFragCoord) + { + pixelHLSL += " float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n"; + if (sm3) { + pixelHLSL += " float2 dx_VPos : VPOS;\n"; + } + } + + if (fragmentShader->mUsesPointCoord && sm3) + { + pixelHLSL += " float2 gl_PointCoord : TEXCOORD0;\n"; + } + + if (fragmentShader->mUsesFrontFacing) + { + pixelHLSL += " float vFace : VFACE;\n"; + } + + pixelHLSL += "};\n" + "\n" + "struct PS_OUTPUT\n" + "{\n" + " float4 gl_Color[1] : COLOR;\n" + "};\n" + "\n" + "PS_OUTPUT main(PS_INPUT input)\n" + "{\n"; + + if (fragmentShader->mUsesFragCoord) + { + pixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n"; + + if (sm3) + { + pixelHLSL += " gl_FragCoord.x = input.dx_VPos.x + 0.5;\n" + " gl_FragCoord.y = input.dx_VPos.y + 0.5;\n"; + } + else + { + // dx_Coord contains the viewport width/2, height/2, center.x and center.y. See Context::applyRenderTarget() + pixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Coord.x + dx_Coord.z;\n" + " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_Coord.y + dx_Coord.w;\n"; + } + + pixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n" + " gl_FragCoord.w = rhw;\n"; + } + + if (fragmentShader->mUsesPointCoord && sm3) + { + pixelHLSL += " gl_PointCoord.x = input.gl_PointCoord.x;\n"; + pixelHLSL += " gl_PointCoord.y = 1.0 - input.gl_PointCoord.y;\n"; + } + + if (fragmentShader->mUsesFrontFacing) + { + pixelHLSL += " gl_FrontFacing = dx_PointsOrLines || (dx_FrontCCW ? (input.vFace >= 0.0) : (input.vFace <= 0.0));\n"; + } + + for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++) + { + if (varying->reg >= 0) + { + for (int i = 0; i < varying->size; i++) + { + int rows = VariableRowCount(varying->type); + for (int j = 0; j < rows; j++) + { + std::string n = str(varying->reg + i * rows + j); + pixelHLSL += " " + varying->name; + + if (varying->array) + { + pixelHLSL += "[" + str(i) + "]"; + } + + if (rows > 1) + { + pixelHLSL += "[" + str(j) + "]"; + } + + pixelHLSL += " = input.v" + n + ";\n"; + } + } + } + else UNREACHABLE(); + } + + pixelHLSL += "\n" + " gl_main();\n" + "\n" + " PS_OUTPUT output;\n" + " output.gl_Color[0] = gl_Color[0];\n" + "\n" + " return output;\n" + "}\n"; + + return true; +} + +bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader) +{ + if (!fragmentShader || !fragmentShader->isCompiled()) + { + return false; + } + + if (!vertexShader || !vertexShader->isCompiled()) + { + return false; + } + + std::string pixelHLSL = fragmentShader->getHLSL(); + std::string vertexHLSL = vertexShader->getHLSL(); + + if (!linkVaryings(infoLog, pixelHLSL, vertexHLSL, fragmentShader, vertexShader)) + { + return false; + } + + Context *context = getContext(); + const char *vertexProfile = context->supportsShaderModel3() ? "vs_3_0" : "vs_2_0"; + const char *pixelProfile = context->supportsShaderModel3() ? "ps_3_0" : "ps_2_0"; + + ID3D10Blob *vertexBinary = compileToBinary(infoLog, vertexHLSL.c_str(), vertexProfile, &mConstantTableVS); + ID3D10Blob *pixelBinary = compileToBinary(infoLog, pixelHLSL.c_str(), pixelProfile, &mConstantTablePS); + + if (vertexBinary && pixelBinary) + { + HRESULT vertexResult = mDevice->CreateVertexShader((DWORD*)vertexBinary->GetBufferPointer(), &mVertexExecutable); + HRESULT pixelResult = mDevice->CreatePixelShader((DWORD*)pixelBinary->GetBufferPointer(), &mPixelExecutable); + + if (vertexResult == D3DERR_OUTOFVIDEOMEMORY || vertexResult == E_OUTOFMEMORY || pixelResult == D3DERR_OUTOFVIDEOMEMORY || pixelResult == E_OUTOFMEMORY) + { + return error(GL_OUT_OF_MEMORY, false); + } + + ASSERT(SUCCEEDED(vertexResult) && SUCCEEDED(pixelResult)); + + vertexBinary->Release(); + pixelBinary->Release(); + vertexBinary = NULL; + pixelBinary = NULL; + + if (mVertexExecutable && mPixelExecutable) + { + if (!linkAttributes(infoLog, attributeBindings, fragmentShader, vertexShader)) + { + return false; + } + + if (!linkUniforms(infoLog, GL_FRAGMENT_SHADER, mConstantTablePS)) + { + return false; + } + + if (!linkUniforms(infoLog, GL_VERTEX_SHADER, mConstantTableVS)) + { + return false; + } + + // these uniforms are searched as already-decorated because gl_ and dx_ + // are reserved prefixes, and do not receive additional decoration + mDxDepthRangeLocation = getUniformLocation("dx_DepthRange"); + mDxDepthLocation = getUniformLocation("dx_Depth"); + mDxCoordLocation = getUniformLocation("dx_Coord"); + mDxHalfPixelSizeLocation = getUniformLocation("dx_HalfPixelSize"); + mDxFrontCCWLocation = getUniformLocation("dx_FrontCCW"); + mDxPointsOrLinesLocation = getUniformLocation("dx_PointsOrLines"); + + context->markDxUniformsDirty(); + + return true; + } + } + + return false; +} + +// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices +bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader) +{ + unsigned int usedLocations = 0; + + // Link attributes that have a binding location + for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++) + { + int location = attributeBindings.getAttributeBinding(attribute->name); + + if (location != -1) // Set by glBindAttribLocation + { + if (!mLinkedAttribute[location].name.empty()) + { + // Multiple active attributes bound to the same location; not an error + } + + mLinkedAttribute[location] = *attribute; + + int rows = VariableRowCount(attribute->type); + + if (rows + location > MAX_VERTEX_ATTRIBS) + { + infoLog.append("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location); + + return false; + } + + for (int i = 0; i < rows; i++) + { + usedLocations |= 1 << (location + i); + } + } + } + + // Link attributes that don't have a binding location + for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++) + { + int location = attributeBindings.getAttributeBinding(attribute->name); + + if (location == -1) // Not set by glBindAttribLocation + { + int rows = VariableRowCount(attribute->type); + int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS); + + if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS) + { + infoLog.append("Too many active attributes (%s)", attribute->name.c_str()); + + return false; // Fail to link + } + + mLinkedAttribute[availableIndex] = *attribute; + } + } + + for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; ) + { + int index = vertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name); + int rows = std::max(VariableRowCount(mLinkedAttribute[attributeIndex].type), 1); + + for (int r = 0; r < rows; r++) + { + mSemanticIndex[attributeIndex++] = index++; + } + } + + return true; +} + +bool ProgramBinary::linkUniforms(InfoLog &infoLog, GLenum shader, ID3DXConstantTable *constantTable) +{ + D3DXCONSTANTTABLE_DESC constantTableDescription; + + constantTable->GetDesc(&constantTableDescription); + + for (unsigned int constantIndex = 0; constantIndex < constantTableDescription.Constants; constantIndex++) + { + D3DXHANDLE constantHandle = constantTable->GetConstant(0, constantIndex); + + D3DXCONSTANT_DESC constantDescription; + UINT descriptionCount = 1; + HRESULT result = constantTable->GetConstantDesc(constantHandle, &constantDescription, &descriptionCount); + ASSERT(SUCCEEDED(result)); + + if (!defineUniform(infoLog, shader, constantHandle, constantDescription)) + { + return false; + } + } + + return true; +} + +// Adds the description of a constant found in the binary shader to the list of uniforms +// Returns true if succesful (uniform not already defined) +bool ProgramBinary::defineUniform(InfoLog &infoLog, GLenum shader, const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name) +{ + if (constantDescription.RegisterSet == D3DXRS_SAMPLER) + { + for (unsigned int i = 0; i < constantDescription.RegisterCount; i++) + { + D3DXHANDLE psConstant = mConstantTablePS->GetConstantByName(NULL, constantDescription.Name); + D3DXHANDLE vsConstant = mConstantTableVS->GetConstantByName(NULL, constantDescription.Name); + + if (psConstant) + { + unsigned int samplerIndex = mConstantTablePS->GetSamplerIndex(psConstant) + i; + + if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS) + { + mSamplersPS[samplerIndex].active = true; + mSamplersPS[samplerIndex].textureType = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D; + mSamplersPS[samplerIndex].logicalTextureUnit = 0; + mUsedPixelSamplerRange = std::max(samplerIndex + 1, mUsedPixelSamplerRange); + } + else + { + infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS); + return false; + } + } + + if (vsConstant) + { + unsigned int samplerIndex = mConstantTableVS->GetSamplerIndex(vsConstant) + i; + + if (samplerIndex < getContext()->getMaximumVertexTextureImageUnits()) + { + mSamplersVS[samplerIndex].active = true; + mSamplersVS[samplerIndex].textureType = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D; + mSamplersVS[samplerIndex].logicalTextureUnit = 0; + mUsedVertexSamplerRange = std::max(samplerIndex + 1, mUsedVertexSamplerRange); + } + else + { + infoLog.append("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", getContext()->getMaximumVertexTextureImageUnits()); + return false; + } + } + } + } + + switch(constantDescription.Class) + { + case D3DXPC_STRUCT: + { + for (unsigned int arrayIndex = 0; arrayIndex < constantDescription.Elements; arrayIndex++) + { + for (unsigned int field = 0; field < constantDescription.StructMembers; field++) + { + D3DXHANDLE fieldHandle = mConstantTablePS->GetConstant(constantHandle, field); + + D3DXCONSTANT_DESC fieldDescription; + UINT descriptionCount = 1; + + HRESULT result = mConstantTablePS->GetConstantDesc(fieldHandle, &fieldDescription, &descriptionCount); + ASSERT(SUCCEEDED(result)); + + std::string structIndex = (constantDescription.Elements > 1) ? ("[" + str(arrayIndex) + "]") : ""; + + if (!defineUniform(infoLog, shader, fieldHandle, fieldDescription, name + constantDescription.Name + structIndex + ".")) + { + return false; + } + } + } + + return true; + } + case D3DXPC_SCALAR: + case D3DXPC_VECTOR: + case D3DXPC_MATRIX_COLUMNS: + case D3DXPC_OBJECT: + return defineUniform(shader, constantDescription, name + constantDescription.Name); + default: + UNREACHABLE(); + return false; + } +} + +bool ProgramBinary::defineUniform(GLenum shader, const D3DXCONSTANT_DESC &constantDescription, const std::string &_name) +{ + Uniform *uniform = createUniform(constantDescription, _name); + + if(!uniform) + { + return false; + } + + // Check if already defined + GLint location = getUniformLocation(uniform->name); + GLenum type = uniform->type; + + if (location >= 0) + { + delete uniform; + uniform = mUniforms[mUniformIndex[location].index]; + } + + if (shader == GL_FRAGMENT_SHADER) uniform->ps.set(constantDescription); + if (shader == GL_VERTEX_SHADER) uniform->vs.set(constantDescription); + + if (location >= 0) + { + return uniform->type == type; + } + + mUniforms.push_back(uniform); + unsigned int uniformIndex = mUniforms.size() - 1; + + for (unsigned int i = 0; i < uniform->arraySize; ++i) + { + mUniformIndex.push_back(UniformLocation(_name, i, uniformIndex)); + } + + return true; +} + +Uniform *ProgramBinary::createUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &_name) +{ + if (constantDescription.Rows == 1) // Vectors and scalars + { + switch (constantDescription.Type) + { + case D3DXPT_SAMPLER2D: + switch (constantDescription.Columns) + { + case 1: return new Uniform(GL_SAMPLER_2D, _name, constantDescription.Elements); + default: UNREACHABLE(); + } + break; + case D3DXPT_SAMPLERCUBE: + switch (constantDescription.Columns) + { + case 1: return new Uniform(GL_SAMPLER_CUBE, _name, constantDescription.Elements); + default: UNREACHABLE(); + } + break; + case D3DXPT_BOOL: + switch (constantDescription.Columns) + { + case 1: return new Uniform(GL_BOOL, _name, constantDescription.Elements); + case 2: return new Uniform(GL_BOOL_VEC2, _name, constantDescription.Elements); + case 3: return new Uniform(GL_BOOL_VEC3, _name, constantDescription.Elements); + case 4: return new Uniform(GL_BOOL_VEC4, _name, constantDescription.Elements); + default: UNREACHABLE(); + } + break; + case D3DXPT_INT: + switch (constantDescription.Columns) + { + case 1: return new Uniform(GL_INT, _name, constantDescription.Elements); + case 2: return new Uniform(GL_INT_VEC2, _name, constantDescription.Elements); + case 3: return new Uniform(GL_INT_VEC3, _name, constantDescription.Elements); + case 4: return new Uniform(GL_INT_VEC4, _name, constantDescription.Elements); + default: UNREACHABLE(); + } + break; + case D3DXPT_FLOAT: + switch (constantDescription.Columns) + { + case 1: return new Uniform(GL_FLOAT, _name, constantDescription.Elements); + case 2: return new Uniform(GL_FLOAT_VEC2, _name, constantDescription.Elements); + case 3: return new Uniform(GL_FLOAT_VEC3, _name, constantDescription.Elements); + case 4: return new Uniform(GL_FLOAT_VEC4, _name, constantDescription.Elements); + default: UNREACHABLE(); + } + break; + default: + UNREACHABLE(); + } + } + else if (constantDescription.Rows == constantDescription.Columns) // Square matrices + { + switch (constantDescription.Type) + { + case D3DXPT_FLOAT: + switch (constantDescription.Rows) + { + case 2: return new Uniform(GL_FLOAT_MAT2, _name, constantDescription.Elements); + case 3: return new Uniform(GL_FLOAT_MAT3, _name, constantDescription.Elements); + case 4: return new Uniform(GL_FLOAT_MAT4, _name, constantDescription.Elements); + default: UNREACHABLE(); + } + break; + default: UNREACHABLE(); + } + } + else UNREACHABLE(); + + return 0; +} + +// This method needs to match OutputHLSL::decorate +std::string ProgramBinary::decorateAttribute(const std::string &name) +{ + if (name.compare(0, 3, "gl_") != 0 && name.compare(0, 3, "dx_") != 0) + { + return "_" + name; + } + + return name; +} + +std::string ProgramBinary::undecorateUniform(const std::string &_name) +{ + std::string name = _name; + + // Remove any structure field decoration + size_t pos = 0; + while ((pos = name.find("._", pos)) != std::string::npos) + { + name.replace(pos, 2, "."); + } + + // Remove the leading decoration + if (name[0] == '_') + { + return name.substr(1); + } + else if (name.compare(0, 3, "ar_") == 0) + { + return name.substr(3); + } + + return name; +} + +void ProgramBinary::applyUniformnbv(Uniform *targetUniform, GLsizei count, int width, const GLboolean *v) +{ + float vector[D3D9_MAX_FLOAT_CONSTANTS * 4]; + BOOL boolVector[D3D9_MAX_BOOL_CONSTANTS]; + + if (targetUniform->ps.float4Index >= 0 || targetUniform->vs.float4Index >= 0) + { + ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); + for (int i = 0; i < count; i++) + { + for (int j = 0; j < 4; j++) + { + if (j < width) + { + vector[i * 4 + j] = (v[i * width + j] == GL_FALSE) ? 0.0f : 1.0f; + } + else + { + vector[i * 4 + j] = 0.0f; + } + } + } + } + + if (targetUniform->ps.boolIndex >= 0 || targetUniform->vs.boolIndex >= 0) + { + int psCount = targetUniform->ps.boolIndex >= 0 ? targetUniform->ps.registerCount : 0; + int vsCount = targetUniform->vs.boolIndex >= 0 ? targetUniform->vs.registerCount : 0; + int copyCount = std::min(count * width, std::max(psCount, vsCount)); + ASSERT(copyCount <= D3D9_MAX_BOOL_CONSTANTS); + for (int i = 0; i < copyCount; i++) + { + boolVector[i] = v[i] != GL_FALSE; + } + } + + if (targetUniform->ps.float4Index >= 0) + { + mDevice->SetPixelShaderConstantF(targetUniform->ps.float4Index, vector, targetUniform->ps.registerCount); + } + + if (targetUniform->ps.boolIndex >= 0) + { + mDevice->SetPixelShaderConstantB(targetUniform->ps.boolIndex, boolVector, targetUniform->ps.registerCount); + } + + if (targetUniform->vs.float4Index >= 0) + { + mDevice->SetVertexShaderConstantF(targetUniform->vs.float4Index, vector, targetUniform->vs.registerCount); + } + + if (targetUniform->vs.boolIndex >= 0) + { + mDevice->SetVertexShaderConstantB(targetUniform->vs.boolIndex, boolVector, targetUniform->vs.registerCount); + } +} + +bool ProgramBinary::applyUniformnfv(Uniform *targetUniform, const GLfloat *v) +{ + if (targetUniform->ps.registerCount) + { + mDevice->SetPixelShaderConstantF(targetUniform->ps.float4Index, v, targetUniform->ps.registerCount); + } + + if (targetUniform->vs.registerCount) + { + mDevice->SetVertexShaderConstantF(targetUniform->vs.float4Index, v, targetUniform->vs.registerCount); + } + + return true; +} + +bool ProgramBinary::applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint *v) +{ + ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); + D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS]; + + for (int i = 0; i < count; i++) + { + vector[i] = D3DXVECTOR4((float)v[i], 0, 0, 0); + } + + if (targetUniform->ps.registerCount) + { + if (targetUniform->ps.samplerIndex >= 0) + { + unsigned int firstIndex = targetUniform->ps.samplerIndex; + + for (int i = 0; i < count; i++) + { + unsigned int samplerIndex = firstIndex + i; + + if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS) + { + ASSERT(mSamplersPS[samplerIndex].active); + mSamplersPS[samplerIndex].logicalTextureUnit = v[i]; + } + } + } + else + { + ASSERT(targetUniform->ps.float4Index >= 0); + mDevice->SetPixelShaderConstantF(targetUniform->ps.float4Index, (const float*)vector, targetUniform->ps.registerCount); + } + } + + if (targetUniform->vs.registerCount) + { + if (targetUniform->vs.samplerIndex >= 0) + { + unsigned int firstIndex = targetUniform->vs.samplerIndex; + + for (int i = 0; i < count; i++) + { + unsigned int samplerIndex = firstIndex + i; + + if (samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF) + { + ASSERT(mSamplersVS[samplerIndex].active); + mSamplersVS[samplerIndex].logicalTextureUnit = v[i]; + } + } + } + else + { + ASSERT(targetUniform->vs.float4Index >= 0); + mDevice->SetVertexShaderConstantF(targetUniform->vs.float4Index, (const float *)vector, targetUniform->vs.registerCount); + } + } + + return true; +} + +bool ProgramBinary::applyUniform2iv(Uniform *targetUniform, GLsizei count, const GLint *v) +{ + ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); + D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS]; + + for (int i = 0; i < count; i++) + { + vector[i] = D3DXVECTOR4((float)v[0], (float)v[1], 0, 0); + + v += 2; + } + + applyUniformniv(targetUniform, count, vector); + + return true; +} + +bool ProgramBinary::applyUniform3iv(Uniform *targetUniform, GLsizei count, const GLint *v) +{ + ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); + D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS]; + + for (int i = 0; i < count; i++) + { + vector[i] = D3DXVECTOR4((float)v[0], (float)v[1], (float)v[2], 0); + + v += 3; + } + + applyUniformniv(targetUniform, count, vector); + + return true; +} + +bool ProgramBinary::applyUniform4iv(Uniform *targetUniform, GLsizei count, const GLint *v) +{ + ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); + D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS]; + + for (int i = 0; i < count; i++) + { + vector[i] = D3DXVECTOR4((float)v[0], (float)v[1], (float)v[2], (float)v[3]); + + v += 4; + } + + applyUniformniv(targetUniform, count, vector); + + return true; +} + +void ProgramBinary::applyUniformniv(Uniform *targetUniform, GLsizei count, const D3DXVECTOR4 *vector) +{ + if (targetUniform->ps.registerCount) + { + ASSERT(targetUniform->ps.float4Index >= 0); + mDevice->SetPixelShaderConstantF(targetUniform->ps.float4Index, (const float *)vector, targetUniform->ps.registerCount); + } + + if (targetUniform->vs.registerCount) + { + ASSERT(targetUniform->vs.float4Index >= 0); + mDevice->SetVertexShaderConstantF(targetUniform->vs.float4Index, (const float *)vector, targetUniform->vs.registerCount); + } +} + +bool ProgramBinary::isValidated() const +{ + return mValidated; +} + +void ProgramBinary::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) +{ + // Skip over inactive attributes + unsigned int activeAttribute = 0; + unsigned int attribute; + for (attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++) + { + if (mLinkedAttribute[attribute].name.empty()) + { + continue; + } + + if (activeAttribute == index) + { + break; + } + + activeAttribute++; + } + + if (bufsize > 0) + { + const char *string = mLinkedAttribute[attribute].name.c_str(); + + strncpy(name, string, bufsize); + name[bufsize - 1] = '\0'; + + if (length) + { + *length = strlen(name); + } + } + + *size = 1; // Always a single 'type' instance + + *type = mLinkedAttribute[attribute].type; +} + +GLint ProgramBinary::getActiveAttributeCount() +{ + int count = 0; + + for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) + { + if (!mLinkedAttribute[attributeIndex].name.empty()) + { + count++; + } + } + + return count; +} + +GLint ProgramBinary::getActiveAttributeMaxLength() +{ + int maxLength = 0; + + for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) + { + if (!mLinkedAttribute[attributeIndex].name.empty()) + { + maxLength = std::max((int)(mLinkedAttribute[attributeIndex].name.length() + 1), maxLength); + } + } + + return maxLength; +} + +void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) +{ + // Skip over internal uniforms + unsigned int activeUniform = 0; + unsigned int uniform; + for (uniform = 0; uniform < mUniforms.size(); uniform++) + { + if (mUniforms[uniform]->name.compare(0, 3, "dx_") == 0) + { + continue; + } + + if (activeUniform == index) + { + break; + } + + activeUniform++; + } + + ASSERT(uniform < mUniforms.size()); // index must be smaller than getActiveUniformCount() + + if (bufsize > 0) + { + std::string string = mUniforms[uniform]->name; + + if (mUniforms[uniform]->isArray()) + { + string += "[0]"; + } + + strncpy(name, string.c_str(), bufsize); + name[bufsize - 1] = '\0'; + + if (length) + { + *length = strlen(name); + } + } + + *size = mUniforms[uniform]->arraySize; + + *type = mUniforms[uniform]->type; +} + +GLint ProgramBinary::getActiveUniformCount() +{ + int count = 0; + + unsigned int numUniforms = mUniforms.size(); + for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++) + { + if (mUniforms[uniformIndex]->name.compare(0, 3, "dx_") != 0) + { + count++; + } + } + + return count; +} + +GLint ProgramBinary::getActiveUniformMaxLength() +{ + int maxLength = 0; + + unsigned int numUniforms = mUniforms.size(); + for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++) + { + if (!mUniforms[uniformIndex]->name.empty() && mUniforms[uniformIndex]->name.compare(0, 3, "dx_") != 0) + { + int length = (int)(mUniforms[uniformIndex]->name.length() + 1); + if (mUniforms[uniformIndex]->isArray()) + { + length += 3; // Counting in "[0]". + } + maxLength = std::max(length, maxLength); + } + } + + return maxLength; +} + +void ProgramBinary::validate(InfoLog &infoLog) +{ + applyUniforms(); + if (!validateSamplers(&infoLog)) + { + mValidated = false; + } + else + { + mValidated = true; + } +} + +bool ProgramBinary::validateSamplers(InfoLog *infoLog) +{ + // if any two active samplers in a program are of different types, but refer to the same + // texture image unit, and this is the current program, then ValidateProgram will fail, and + // DrawArrays and DrawElements will issue the INVALID_OPERATION error. + + const unsigned int maxCombinedTextureImageUnits = getContext()->getMaximumCombinedTextureImageUnits(); + TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF]; + + for (unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF; ++i) + { + textureUnitType[i] = TEXTURE_UNKNOWN; + } + + for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i) + { + if (mSamplersPS[i].active) + { + unsigned int unit = mSamplersPS[i].logicalTextureUnit; + + if (unit >= maxCombinedTextureImageUnits) + { + if (infoLog) + { + infoLog->append("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits); + } + + return false; + } + + if (textureUnitType[unit] != TEXTURE_UNKNOWN) + { + if (mSamplersPS[i].textureType != textureUnitType[unit]) + { + if (infoLog) + { + infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit); + } + + return false; + } + } + else + { + textureUnitType[unit] = mSamplersPS[i].textureType; + } + } + } + + for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i) + { + if (mSamplersVS[i].active) + { + unsigned int unit = mSamplersVS[i].logicalTextureUnit; + + if (unit >= maxCombinedTextureImageUnits) + { + if (infoLog) + { + infoLog->append("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits); + } + + return false; + } + + if (textureUnitType[unit] != TEXTURE_UNKNOWN) + { + if (mSamplersVS[i].textureType != textureUnitType[unit]) + { + if (infoLog) + { + infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit); + } + + return false; + } + } + else + { + textureUnitType[unit] = mSamplersVS[i].textureType; + } + } + } + + return true; +} + +GLint ProgramBinary::getDxDepthRangeLocation() const +{ + return mDxDepthRangeLocation; +} + +GLint ProgramBinary::getDxDepthLocation() const +{ + return mDxDepthLocation; +} + +GLint ProgramBinary::getDxCoordLocation() const +{ + return mDxCoordLocation; +} + +GLint ProgramBinary::getDxHalfPixelSizeLocation() const +{ + return mDxHalfPixelSizeLocation; +} + +GLint ProgramBinary::getDxFrontCCWLocation() const +{ + return mDxFrontCCWLocation; +} + +GLint ProgramBinary::getDxPointsOrLinesLocation() const +{ + return mDxPointsOrLinesLocation; +} + +} diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/ProgramBinary.h b/Source/ThirdParty/ANGLE/src/libGLESv2/ProgramBinary.h new file mode 100644 index 000000000..1e9c5e2ae --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/ProgramBinary.h @@ -0,0 +1,211 @@ +// +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Program.h: Defines the gl::Program class. Implements GL program objects +// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28. + +#ifndef LIBGLESV2_PROGRAM_BINARY_H_ +#define LIBGLESV2_PROGRAM_BINARY_H_ + +#include <d3dx9.h> +#include <d3dcompiler.h> +#include <string> +#include <vector> + +#include "libGLESv2/Shader.h" +#include "libGLESv2/Context.h" + +namespace gl +{ +class FragmentShader; +class VertexShader; + +// Helper struct representing a single shader uniform +struct Uniform +{ + Uniform(GLenum type, const std::string &_name, unsigned int arraySize); + + ~Uniform(); + + bool isArray(); + + const GLenum type; + const std::string _name; // Decorated name + const std::string name; // Undecorated name + const unsigned int arraySize; + + unsigned char *data; + bool dirty; + + struct RegisterInfo + { + RegisterInfo() + { + float4Index = -1; + samplerIndex = -1; + boolIndex = -1; + registerCount = 0; + } + + void set(const D3DXCONSTANT_DESC &constantDescription) + { + switch(constantDescription.RegisterSet) + { + case D3DXRS_BOOL: boolIndex = constantDescription.RegisterIndex; break; + case D3DXRS_FLOAT4: float4Index = constantDescription.RegisterIndex; break; + case D3DXRS_SAMPLER: samplerIndex = constantDescription.RegisterIndex; break; + default: UNREACHABLE(); + } + + ASSERT(registerCount == 0 || registerCount == (int)constantDescription.RegisterCount); + registerCount = constantDescription.RegisterCount; + } + + int float4Index; + int samplerIndex; + int boolIndex; + + int registerCount; + }; + + RegisterInfo ps; + RegisterInfo vs; +}; + +// Struct used for correlating uniforms/elements of uniform arrays to handles +struct UniformLocation +{ + UniformLocation(const std::string &_name, unsigned int element, unsigned int index); + + std::string name; + unsigned int element; + unsigned int index; +}; + +// This is the result of linking a program. It is the state that would be passed to ProgramBinary. +class ProgramBinary +{ + public: + ProgramBinary(); + ~ProgramBinary(); + + IDirect3DPixelShader9 *getPixelShader(); + IDirect3DVertexShader9 *getVertexShader(); + + GLuint getAttributeLocation(const char *name); + int getSemanticIndex(int attributeIndex); + + GLint getSamplerMapping(SamplerType type, unsigned int samplerIndex); + TextureType getSamplerTextureType(SamplerType type, unsigned int samplerIndex); + GLint getUsedSamplerRange(SamplerType type); + + GLint getUniformLocation(std::string name); + bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v); + bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v); + bool setUniform3fv(GLint location, GLsizei count, const GLfloat *v); + bool setUniform4fv(GLint location, GLsizei count, const GLfloat *v); + bool setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value); + bool setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value); + bool setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value); + bool setUniform1iv(GLint location, GLsizei count, const GLint *v); + bool setUniform2iv(GLint location, GLsizei count, const GLint *v); + bool setUniform3iv(GLint location, GLsizei count, const GLint *v); + bool setUniform4iv(GLint location, GLsizei count, const GLint *v); + + bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params); + bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params); + + GLint getDxDepthRangeLocation() const; + GLint getDxDepthLocation() const; + GLint getDxCoordLocation() const; + GLint getDxHalfPixelSizeLocation() const; + GLint getDxFrontCCWLocation() const; + GLint getDxPointsOrLinesLocation() const; + + void dirtyAllUniforms(); + void applyUniforms(); + + bool link(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader); + void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders); + + void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); + GLint getActiveAttributeCount(); + GLint getActiveAttributeMaxLength(); + + void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); + GLint getActiveUniformCount(); + GLint getActiveUniformMaxLength(); + + void validate(InfoLog &infoLog); + bool validateSamplers(InfoLog *infoLog); + bool isValidated() const; + + static std::string decorateAttribute(const std::string &name); // Prepend an underscore + static std::string undecorateUniform(const std::string &_name); // Remove leading underscore + + private: + DISALLOW_COPY_AND_ASSIGN(ProgramBinary); + + ID3D10Blob *compileToBinary(InfoLog &infoLog, const char *hlsl, const char *profile, ID3DXConstantTable **constantTable); + + int packVaryings(InfoLog &infoLog, const Varying *packing[][4], FragmentShader *fragmentShader); + bool linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::string& vertexHLSL, FragmentShader *fragmentShader, VertexShader *vertexShader); + + bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader); + + bool linkUniforms(InfoLog &infoLog, GLenum shader, ID3DXConstantTable *constantTable); + bool defineUniform(InfoLog &infoLog, GLenum shader, const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name = ""); + bool defineUniform(GLenum shader, const D3DXCONSTANT_DESC &constantDescription, const std::string &name); + Uniform *createUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &name); + bool applyUniformnfv(Uniform *targetUniform, const GLfloat *v); + bool applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint *v); + bool applyUniform2iv(Uniform *targetUniform, GLsizei count, const GLint *v); + bool applyUniform3iv(Uniform *targetUniform, GLsizei count, const GLint *v); + bool applyUniform4iv(Uniform *targetUniform, GLsizei count, const GLint *v); + void applyUniformniv(Uniform *targetUniform, GLsizei count, const D3DXVECTOR4 *vector); + void applyUniformnbv(Uniform *targetUniform, GLsizei count, int width, const GLboolean *v); + + IDirect3DDevice9 *mDevice; + + IDirect3DPixelShader9 *mPixelExecutable; + IDirect3DVertexShader9 *mVertexExecutable; + + // These are only used during linking. + ID3DXConstantTable *mConstantTablePS; + ID3DXConstantTable *mConstantTableVS; + + Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS]; + int mSemanticIndex[MAX_VERTEX_ATTRIBS]; + + struct Sampler + { + bool active; + GLint logicalTextureUnit; + TextureType textureType; + }; + + Sampler mSamplersPS[MAX_TEXTURE_IMAGE_UNITS]; + Sampler mSamplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF]; + GLuint mUsedVertexSamplerRange; + GLuint mUsedPixelSamplerRange; + + typedef std::vector<Uniform*> UniformArray; + UniformArray mUniforms; + typedef std::vector<UniformLocation> UniformIndex; + UniformIndex mUniformIndex; + + GLint mDxDepthRangeLocation; + GLint mDxDepthLocation; + GLint mDxCoordLocation; + GLint mDxHalfPixelSizeLocation; + GLint mDxFrontCCWLocation; + GLint mDxPointsOrLinesLocation; + + bool mValidated; +}; +} + +#endif // LIBGLESV2_PROGRAM_BINARY_H_ diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.cpp index 60042556b..4b911e812 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.cpp @@ -63,68 +63,144 @@ GLuint RenderbufferInterface::getStencilSize() const return dx2es::GetStencilSize(getD3DFormat()); } -RenderbufferTexture::RenderbufferTexture(Texture *texture, GLenum target) : mTarget(target) +///// RenderbufferTexture2D Implementation //////// + +RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture, GLenum target) : mTarget(target) +{ + mTexture2D.set(texture); +} + +RenderbufferTexture2D::~RenderbufferTexture2D() +{ + mTexture2D.set(NULL); +} + +// Textures need to maintain their own reference count for references via +// Renderbuffers acting as proxies. Here, we notify the texture of a reference. +void RenderbufferTexture2D::addProxyRef(const Renderbuffer *proxy) +{ + mTexture2D->addProxyRef(proxy); +} + +void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy) +{ + mTexture2D->releaseProxy(proxy); +} + +// Increments refcount on surface. +// caller must Release() the returned surface +IDirect3DSurface9 *RenderbufferTexture2D::getRenderTarget() +{ + return mTexture2D->getRenderTarget(mTarget); +} + +// Increments refcount on surface. +// caller must Release() the returned surface +IDirect3DSurface9 *RenderbufferTexture2D::getDepthStencil() +{ + return mTexture2D->getDepthStencil(mTarget); +} + +GLsizei RenderbufferTexture2D::getWidth() const +{ + return mTexture2D->getWidth(0); +} + +GLsizei RenderbufferTexture2D::getHeight() const { - mTexture.set(texture); + return mTexture2D->getHeight(0); } -RenderbufferTexture::~RenderbufferTexture() +GLenum RenderbufferTexture2D::getInternalFormat() const { - mTexture.set(NULL); + return mTexture2D->getInternalFormat(0); +} + +D3DFORMAT RenderbufferTexture2D::getD3DFormat() const +{ + return mTexture2D->getD3DFormat(0); +} + +GLsizei RenderbufferTexture2D::getSamples() const +{ + return 0; +} + +unsigned int RenderbufferTexture2D::getSerial() const +{ + return mTexture2D->getRenderTargetSerial(mTarget); +} + +///// RenderbufferTextureCubeMap Implementation //////// + +RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target) : mTarget(target) +{ + mTextureCubeMap.set(texture); +} + +RenderbufferTextureCubeMap::~RenderbufferTextureCubeMap() +{ + mTextureCubeMap.set(NULL); } // Textures need to maintain their own reference count for references via // Renderbuffers acting as proxies. Here, we notify the texture of a reference. -void RenderbufferTexture::addProxyRef(const Renderbuffer *proxy) +void RenderbufferTextureCubeMap::addProxyRef(const Renderbuffer *proxy) { - mTexture->addProxyRef(proxy); + mTextureCubeMap->addProxyRef(proxy); } -void RenderbufferTexture::releaseProxy(const Renderbuffer *proxy) +void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy) { - mTexture->releaseProxy(proxy); + mTextureCubeMap->releaseProxy(proxy); } -IDirect3DSurface9 *RenderbufferTexture::getRenderTarget() +// Increments refcount on surface. +// caller must Release() the returned surface +IDirect3DSurface9 *RenderbufferTextureCubeMap::getRenderTarget() { - return mTexture->getRenderTarget(mTarget); + return mTextureCubeMap->getRenderTarget(mTarget); } -IDirect3DSurface9 *RenderbufferTexture::getDepthStencil() +// Increments refcount on surface. +// caller must Release() the returned surface +IDirect3DSurface9 *RenderbufferTextureCubeMap::getDepthStencil() { return NULL; } -GLsizei RenderbufferTexture::getWidth() const +GLsizei RenderbufferTextureCubeMap::getWidth() const { - return mTexture->getWidth(0); + return mTextureCubeMap->getWidth(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0); } - -GLsizei RenderbufferTexture::getHeight() const + +GLsizei RenderbufferTextureCubeMap::getHeight() const { - return mTexture->getHeight(0); + return mTextureCubeMap->getHeight(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0); } - -GLenum RenderbufferTexture::getInternalFormat() const + +GLenum RenderbufferTextureCubeMap::getInternalFormat() const { - return mTexture->getInternalFormat(); + return mTextureCubeMap->getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0); } -D3DFORMAT RenderbufferTexture::getD3DFormat() const +D3DFORMAT RenderbufferTextureCubeMap::getD3DFormat() const { - return mTexture->getD3DFormat(); + return mTextureCubeMap->getD3DFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0); } -GLsizei RenderbufferTexture::getSamples() const +GLsizei RenderbufferTextureCubeMap::getSamples() const { return 0; } -unsigned int RenderbufferTexture::getSerial() const +unsigned int RenderbufferTextureCubeMap::getSerial() const { - return mTexture->getRenderTargetSerial(mTarget); + return mTextureCubeMap->getRenderTargetSerial(mTarget); } +////// Renderbuffer Implementation ////// + Renderbuffer::Renderbuffer(GLuint id, RenderbufferInterface *instance) : RefCountObject(id) { ASSERT(instance != NULL); @@ -152,11 +228,15 @@ void Renderbuffer::release() const RefCountObject::release(); } +// Increments refcount on surface. +// caller must Release() the returned surface IDirect3DSurface9 *Renderbuffer::getRenderTarget() { return mInstance->getRenderTarget(); } +// Increments refcount on surface. +// caller must Release() the returned surface IDirect3DSurface9 *Renderbuffer::getDepthStencil() { return mInstance->getDepthStencil(); @@ -243,11 +323,15 @@ RenderbufferStorage::~RenderbufferStorage() { } +// Increments refcount on surface. +// caller must Release() the returned surface IDirect3DSurface9 *RenderbufferStorage::getRenderTarget() { return NULL; } +// Increments refcount on surface. +// caller must Release() the returned surface IDirect3DSurface9 *RenderbufferStorage::getDepthStencil() { return NULL; @@ -356,6 +440,8 @@ Colorbuffer::~Colorbuffer() } } +// Increments refcount on surface. +// caller must Release() the returned surface IDirect3DSurface9 *Colorbuffer::getRenderTarget() { if (mRenderTarget) @@ -428,8 +514,15 @@ DepthStencilbuffer::~DepthStencilbuffer() } } +// Increments refcount on surface. +// caller must Release() the returned surface IDirect3DSurface9 *DepthStencilbuffer::getDepthStencil() { + if (mDepthStencil) + { + mDepthStencil->AddRef(); + } + return mDepthStencil; } diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.h index 60ec0588c..e6d5ddb87 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.h @@ -21,7 +21,8 @@ namespace gl { -class Texture; +class Texture2D; +class TextureCubeMap; class Renderbuffer; class Colorbuffer; class DepthStencilbuffer; @@ -58,12 +59,12 @@ class RenderbufferInterface DISALLOW_COPY_AND_ASSIGN(RenderbufferInterface); }; -class RenderbufferTexture : public RenderbufferInterface +class RenderbufferTexture2D : public RenderbufferInterface { public: - RenderbufferTexture(Texture *texture, GLenum target); + RenderbufferTexture2D(Texture2D *texture, GLenum target); - virtual ~RenderbufferTexture(); + virtual ~RenderbufferTexture2D(); void addProxyRef(const Renderbuffer *proxy); void releaseProxy(const Renderbuffer *proxy); @@ -80,9 +81,37 @@ class RenderbufferTexture : public RenderbufferInterface virtual unsigned int getSerial() const; private: - DISALLOW_COPY_AND_ASSIGN(RenderbufferTexture); + DISALLOW_COPY_AND_ASSIGN(RenderbufferTexture2D); - BindingPointer <Texture> mTexture; + BindingPointer <Texture2D> mTexture2D; + GLenum mTarget; +}; + +class RenderbufferTextureCubeMap : public RenderbufferInterface +{ + public: + RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target); + + virtual ~RenderbufferTextureCubeMap(); + + void addProxyRef(const Renderbuffer *proxy); + void releaseProxy(const Renderbuffer *proxy); + + IDirect3DSurface9 *getRenderTarget(); + IDirect3DSurface9 *getDepthStencil(); + + virtual GLsizei getWidth() const; + virtual GLsizei getHeight() const; + virtual GLenum getInternalFormat() const; + virtual D3DFORMAT getD3DFormat() const; + virtual GLsizei getSamples() const; + + virtual unsigned int getSerial() const; + + private: + DISALLOW_COPY_AND_ASSIGN(RenderbufferTextureCubeMap); + + BindingPointer <TextureCubeMap> mTextureCubeMap; GLenum mTarget; }; diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.cpp index ac58abe59..57fd3d579 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.cpp @@ -102,14 +102,14 @@ void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) { int index = 0; - if (mInfoLog) + if (bufSize > 0) { - index = std::min(bufSize - 1, (int)strlen(mInfoLog)); - memcpy(infoLog, mInfoLog, index); - } + if (mInfoLog) + { + index = std::min(bufSize - 1, (int)strlen(mInfoLog)); + memcpy(infoLog, mInfoLog, index); + } - if (bufSize) - { infoLog[index] = '\0'; } @@ -147,14 +147,14 @@ void Shader::getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char { int index = 0; - if (source) + if (bufSize > 0) { - index = std::min(bufSize - 1, (int)strlen(source)); - memcpy(buffer, source, index); - } + if (source) + { + index = std::min(bufSize - 1, (int)strlen(source)); + memcpy(buffer, source, index); + } - if (bufSize) - { buffer[index] = '\0'; } diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.h index 9c7c0df67..43083ec42 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.h @@ -42,7 +42,7 @@ typedef std::list<Varying> VaryingList; class Shader { - friend Program; + friend class ProgramBinary; public: Shader(ResourceManager *manager, GLuint handle); @@ -128,7 +128,7 @@ typedef std::vector<Attribute> AttributeArray; class VertexShader : public Shader { - friend Program; + friend class ProgramBinary; public: VertexShader(ResourceManager *manager, GLuint handle); diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp index 29177d203..6ff2453b6 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp @@ -31,8 +31,12 @@ unsigned int TextureStorage::mCurrentTextureSerial = 1; static D3DFORMAT ConvertTextureFormatType(GLenum format, GLenum type) { - if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || - format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) + if (IsDepthTexture(format)) + { + return D3DFMT_INTZ; + } + else if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || + format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) { return D3DFMT_DXT1; } @@ -75,6 +79,10 @@ static D3DFORMAT ConvertTextureFormatType(GLenum format, GLenum type) static bool IsTextureFormatRenderable(D3DFORMAT format) { + if (format == D3DFMT_INTZ) + { + return true; + } switch(format) { case D3DFMT_L8: @@ -95,6 +103,21 @@ static bool IsTextureFormatRenderable(D3DFORMAT format) return false; } +static inline DWORD GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable) +{ + DWORD d3dusage = 0; + + if (d3dfmt == D3DFMT_INTZ) + { + d3dusage |= D3DUSAGE_DEPTHSTENCIL; + } + else if(forceRenderable || (IsTextureFormatRenderable(d3dfmt) && (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE))) + { + d3dusage |= D3DUSAGE_RENDERTARGET; + } + return d3dusage; +} + Image::Image() { mWidth = 0; @@ -155,6 +178,8 @@ void Image::createSurface() IDirect3DTexture9 *newTexture = NULL; IDirect3DSurface9 *newSurface = NULL; const D3DPOOL poolToUse = D3DPOOL_SYSTEMMEM; + const D3DFORMAT d3dFormat = getD3DFormat(); + ASSERT(d3dFormat != D3DFMT_INTZ); // We should never get here for depth textures if (mWidth != 0 && mHeight != 0) { @@ -178,7 +203,7 @@ void Image::createSurface() levelToFetch = upsampleCount; } - HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, getD3DFormat(), + HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, d3dFormat, poolToUse, &newTexture, NULL); if (FAILED(result)) @@ -264,9 +289,13 @@ void Image::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint y { IDirect3DSurface9 *sourceSurface = getSurface(); - if (sourceSurface != destSurface) + if (sourceSurface && sourceSurface != destSurface) { - RECT rect = transformPixelRect(xoffset, yoffset, width, height, mHeight); + RECT rect; + rect.left = xoffset; + rect.top = yoffset; + rect.right = xoffset + width; + rect.bottom = yoffset + height; if (mD3DPool == D3DPOOL_MANAGED) { @@ -284,12 +313,24 @@ void Image::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint y } // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input -// into the target pixel rectangle at output with outputPitch bytes in between each line. +// into the target pixel rectangle. void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type, - GLint unpackAlignment, const void *input, size_t outputPitch, void *output) const + GLint unpackAlignment, const void *input) { - GLsizei inputPitch = -ComputePitch(width, mFormat, type, unpackAlignment); - input = ((char*)input) - inputPitch * (height - 1); + RECT lockRect = + { + xoffset, yoffset, + xoffset + width, yoffset + height + }; + + D3DLOCKED_RECT locked; + HRESULT result = lock(&locked, &lockRect); + if (FAILED(result)) + { + return; + } + + GLsizei inputPitch = ComputePitch(width, mFormat, type, unpackAlignment); switch (type) { @@ -297,29 +338,36 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height switch (mFormat) { case GL_ALPHA: - loadAlphaData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + if (supportsSSE2()) + { + loadAlphaDataSSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits); + } + else + { + loadAlphaData(width, height, inputPitch, input, locked.Pitch, locked.pBits); + } break; case GL_LUMINANCE: - loadLuminanceData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output, getD3DFormat() == D3DFMT_L8); + loadLuminanceData(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_L8); break; case GL_LUMINANCE_ALPHA: - loadLuminanceAlphaData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output, getD3DFormat() == D3DFMT_A8L8); + loadLuminanceAlphaData(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_A8L8); break; case GL_RGB: - loadRGBUByteData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGBUByteData(width, height, inputPitch, input, locked.Pitch, locked.pBits); break; case GL_RGBA: if (supportsSSE2()) { - loadRGBAUByteDataSSE2(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGBAUByteDataSSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits); } else { - loadRGBAUByteData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGBAUByteData(width, height, inputPitch, input, locked.Pitch, locked.pBits); } break; case GL_BGRA_EXT: - loadBGRAData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadBGRAData(width, height, inputPitch, input, locked.Pitch, locked.pBits); break; default: UNREACHABLE(); } @@ -328,7 +376,7 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height switch (mFormat) { case GL_RGB: - loadRGB565Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGB565Data(width, height, inputPitch, input, locked.Pitch, locked.pBits); break; default: UNREACHABLE(); } @@ -337,7 +385,7 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height switch (mFormat) { case GL_RGBA: - loadRGBA4444Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGBA4444Data(width, height, inputPitch, input, locked.Pitch, locked.pBits); break; default: UNREACHABLE(); } @@ -346,7 +394,7 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height switch (mFormat) { case GL_RGBA: - loadRGBA5551Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGBA5551Data(width, height, inputPitch, input, locked.Pitch, locked.pBits); break; default: UNREACHABLE(); } @@ -356,19 +404,19 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height { // float textures are converted to RGBA, not BGRA, as they're stored that way in D3D case GL_ALPHA: - loadAlphaFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadAlphaFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits); break; case GL_LUMINANCE: - loadLuminanceFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadLuminanceFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits); break; case GL_LUMINANCE_ALPHA: - loadLuminanceAlphaFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadLuminanceAlphaFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits); break; case GL_RGB: - loadRGBFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGBFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits); break; case GL_RGBA: - loadRGBAFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGBAFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits); break; default: UNREACHABLE(); } @@ -378,28 +426,30 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height { // float textures are converted to RGBA, not BGRA, as they're stored that way in D3D case GL_ALPHA: - loadAlphaHalfFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadAlphaHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits); break; case GL_LUMINANCE: - loadLuminanceHalfFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadLuminanceHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits); break; case GL_LUMINANCE_ALPHA: - loadLuminanceAlphaHalfFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadLuminanceAlphaHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits); break; case GL_RGB: - loadRGBHalfFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGBHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits); break; case GL_RGBA: - loadRGBAHalfFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGBAHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits); break; default: UNREACHABLE(); } break; default: UNREACHABLE(); } + + unlock(); } -void Image::loadAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadAlphaData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned char *source = NULL; @@ -408,7 +458,7 @@ void Image::loadAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei h for (int y = 0; y < height; y++) { source = static_cast<const unsigned char*>(input) + y * inputPitch; - dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4; + dest = static_cast<unsigned char*>(output) + y * outputPitch; for (int x = 0; x < width; x++) { dest[4 * x + 0] = 0; @@ -419,7 +469,47 @@ void Image::loadAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei h } } -void Image::loadAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadAlphaDataSSE2(GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const +{ + const unsigned char *source = NULL; + unsigned int *dest = NULL; + __m128i zeroWide = _mm_setzero_si128(); + + for (int y = 0; y < height; y++) + { + source = static_cast<const unsigned char*>(input) + y * inputPitch; + dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch); + + int x; + // Make output writes aligned + for (x = 0; ((reinterpret_cast<intptr_t>(&dest[x]) & 0xF) != 0 && x < width); x++) + { + dest[x] = static_cast<unsigned int>(source[x]) << 24; + } + + for (; x + 7 < width; x += 8) + { + __m128i sourceData = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(&source[x])); + // Interleave each byte to 16bit, make the lower byte to zero + sourceData = _mm_unpacklo_epi8(zeroWide, sourceData); + // Interleave each 16bit to 32bit, make the lower 16bit to zero + __m128i lo = _mm_unpacklo_epi16(zeroWide, sourceData); + __m128i hi = _mm_unpackhi_epi16(zeroWide, sourceData); + + _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x]), lo); + _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x + 4]), hi); + } + + // Handle the remainder + for (; x < width; x++) + { + dest[x] = static_cast<unsigned int>(source[x]) << 24; + } + } +} + +void Image::loadAlphaFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const float *source = NULL; @@ -428,7 +518,7 @@ void Image::loadAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsi for (int y = 0; y < height; y++) { source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16); + dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch); for (int x = 0; x < width; x++) { dest[4 * x + 0] = 0; @@ -439,7 +529,7 @@ void Image::loadAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsi } } -void Image::loadAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadAlphaHalfFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned short *source = NULL; @@ -448,7 +538,7 @@ void Image::loadAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, for (int y = 0; y < height; y++) { source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8); + dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch); for (int x = 0; x < width; x++) { dest[4 * x + 0] = 0; @@ -459,17 +549,16 @@ void Image::loadAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, } } -void Image::loadLuminanceData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadLuminanceData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const { - const int destBytesPerPixel = native? 1: 4; const unsigned char *source = NULL; unsigned char *dest = NULL; for (int y = 0; y < height; y++) { source = static_cast<const unsigned char*>(input) + y * inputPitch; - dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * destBytesPerPixel; + dest = static_cast<unsigned char*>(output) + y * outputPitch; if (!native) // BGRA8 destination format { @@ -488,7 +577,7 @@ void Image::loadLuminanceData(GLint xoffset, GLint yoffset, GLsizei width, GLsiz } } -void Image::loadLuminanceFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadLuminanceFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const float *source = NULL; @@ -497,7 +586,7 @@ void Image::loadLuminanceFloatData(GLint xoffset, GLint yoffset, GLsizei width, for (int y = 0; y < height; y++) { source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16); + dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch); for (int x = 0; x < width; x++) { dest[4 * x + 0] = source[x]; @@ -508,7 +597,7 @@ void Image::loadLuminanceFloatData(GLint xoffset, GLint yoffset, GLsizei width, } } -void Image::loadLuminanceHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadLuminanceHalfFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned short *source = NULL; @@ -517,7 +606,7 @@ void Image::loadLuminanceHalfFloatData(GLint xoffset, GLint yoffset, GLsizei wid for (int y = 0; y < height; y++) { source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8); + dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch); for (int x = 0; x < width; x++) { dest[4 * x + 0] = source[x]; @@ -528,17 +617,16 @@ void Image::loadLuminanceHalfFloatData(GLint xoffset, GLint yoffset, GLsizei wid } } -void Image::loadLuminanceAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadLuminanceAlphaData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const { - const int destBytesPerPixel = native? 2: 4; const unsigned char *source = NULL; unsigned char *dest = NULL; for (int y = 0; y < height; y++) { source = static_cast<const unsigned char*>(input) + y * inputPitch; - dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * destBytesPerPixel; + dest = static_cast<unsigned char*>(output) + y * outputPitch; if (!native) // BGRA8 destination format { @@ -557,7 +645,7 @@ void Image::loadLuminanceAlphaData(GLint xoffset, GLint yoffset, GLsizei width, } } -void Image::loadLuminanceAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadLuminanceAlphaFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const float *source = NULL; @@ -566,7 +654,7 @@ void Image::loadLuminanceAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei wi for (int y = 0; y < height; y++) { source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16); + dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch); for (int x = 0; x < width; x++) { dest[4 * x + 0] = source[2*x+0]; @@ -577,7 +665,7 @@ void Image::loadLuminanceAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei wi } } -void Image::loadLuminanceAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadLuminanceAlphaHalfFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned short *source = NULL; @@ -586,7 +674,7 @@ void Image::loadLuminanceAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsize for (int y = 0; y < height; y++) { source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8); + dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch); for (int x = 0; x < width; x++) { dest[4 * x + 0] = source[2*x+0]; @@ -597,7 +685,7 @@ void Image::loadLuminanceAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsize } } -void Image::loadRGBUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadRGBUByteData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned char *source = NULL; @@ -606,7 +694,7 @@ void Image::loadRGBUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsize for (int y = 0; y < height; y++) { source = static_cast<const unsigned char*>(input) + y * inputPitch; - dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4; + dest = static_cast<unsigned char*>(output) + y * outputPitch; for (int x = 0; x < width; x++) { dest[4 * x + 0] = source[x * 3 + 2]; @@ -617,7 +705,7 @@ void Image::loadRGBUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsize } } -void Image::loadRGB565Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadRGB565Data(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned short *source = NULL; @@ -626,7 +714,7 @@ void Image::loadRGB565Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei for (int y = 0; y < height; y++) { source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4; + dest = static_cast<unsigned char*>(output) + y * outputPitch; for (int x = 0; x < width; x++) { unsigned short rgba = source[x]; @@ -638,7 +726,7 @@ void Image::loadRGB565Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei } } -void Image::loadRGBFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadRGBFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const float *source = NULL; @@ -647,7 +735,7 @@ void Image::loadRGBFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsize for (int y = 0; y < height; y++) { source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16); + dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch); for (int x = 0; x < width; x++) { dest[4 * x + 0] = source[x * 3 + 0]; @@ -658,7 +746,7 @@ void Image::loadRGBFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsize } } -void Image::loadRGBHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadRGBHalfFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned short *source = NULL; @@ -667,7 +755,7 @@ void Image::loadRGBHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GL for (int y = 0; y < height; y++) { source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8); + dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch); for (int x = 0; x < width; x++) { dest[4 * x + 0] = source[x * 3 + 0]; @@ -678,7 +766,7 @@ void Image::loadRGBHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GL } } -void Image::loadRGBAUByteDataSSE2(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadRGBAUByteDataSSE2(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned int *source = NULL; @@ -688,7 +776,7 @@ void Image::loadRGBAUByteDataSSE2(GLint xoffset, GLint yoffset, GLsizei width, G for (int y = 0; y < height; y++) { source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4); + dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch); int x = 0; // Make output writes aligned @@ -720,7 +808,7 @@ void Image::loadRGBAUByteDataSSE2(GLint xoffset, GLint yoffset, GLsizei width, G } } -void Image::loadRGBAUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadRGBAUByteData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned int *source = NULL; @@ -728,7 +816,7 @@ void Image::loadRGBAUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsiz for (int y = 0; y < height; y++) { source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4); + dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch); for (int x = 0; x < width; x++) { @@ -738,7 +826,7 @@ void Image::loadRGBAUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsiz } } -void Image::loadRGBA4444Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadRGBA4444Data(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned short *source = NULL; @@ -747,7 +835,7 @@ void Image::loadRGBA4444Data(GLint xoffset, GLint yoffset, GLsizei width, GLsize for (int y = 0; y < height; y++) { source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4; + dest = static_cast<unsigned char*>(output) + y * outputPitch; for (int x = 0; x < width; x++) { unsigned short rgba = source[x]; @@ -759,7 +847,7 @@ void Image::loadRGBA4444Data(GLint xoffset, GLint yoffset, GLsizei width, GLsize } } -void Image::loadRGBA5551Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadRGBA5551Data(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned short *source = NULL; @@ -768,7 +856,7 @@ void Image::loadRGBA5551Data(GLint xoffset, GLint yoffset, GLsizei width, GLsize for (int y = 0; y < height; y++) { source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4; + dest = static_cast<unsigned char*>(output) + y * outputPitch; for (int x = 0; x < width; x++) { unsigned short rgba = source[x]; @@ -780,7 +868,7 @@ void Image::loadRGBA5551Data(GLint xoffset, GLint yoffset, GLsizei width, GLsize } } -void Image::loadRGBAFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadRGBAFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const float *source = NULL; @@ -789,12 +877,12 @@ void Image::loadRGBAFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsiz for (int y = 0; y < height; y++) { source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch); - dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16); + dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch); memcpy(dest, source, width * 16); } } -void Image::loadRGBAHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadRGBAHalfFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned char *source = NULL; @@ -803,12 +891,12 @@ void Image::loadRGBAHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, G for (int y = 0; y < height; y++) { source = static_cast<const unsigned char*>(input) + y * inputPitch; - dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8; + dest = static_cast<unsigned char*>(output) + y * outputPitch; memcpy(dest, source, width * 8); } } -void Image::loadBGRAData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void Image::loadBGRAData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned char *source = NULL; @@ -817,283 +905,37 @@ void Image::loadBGRAData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei he for (int y = 0; y < height; y++) { source = static_cast<const unsigned char*>(input) + y * inputPitch; - dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4; + dest = static_cast<unsigned char*>(output) + y * outputPitch; memcpy(dest, source, width*4); } } void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) const { - switch (getD3DFormat()) - { - case D3DFMT_DXT1: - loadDXT1Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); - break; - case D3DFMT_DXT3: - loadDXT3Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); - break; - case D3DFMT_DXT5: - loadDXT5Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); - break; - } -} - -static void FlipCopyDXT1BlockFull(const unsigned int* source, unsigned int* dest) { - // A DXT1 block layout is: - // [0-1] color0. - // [2-3] color1. - // [4-7] color bitmap, 2 bits per pixel. - // So each of the 4-7 bytes represents one line, flipping a block is just - // flipping those bytes. - - // First 32-bits is two RGB565 colors shared by tile and does not need to be modified. - dest[0] = source[0]; - - // Second 32-bits contains 4 rows of 4 2-bit interpolants between the colors. All rows should be flipped. - dest[1] = (source[1] >> 24) | - ((source[1] << 8) & 0x00FF0000) | - ((source[1] >> 8) & 0x0000FF00) | - (source[1] << 24); -} - -// Flips the first 2 lines of a DXT1 block in the y direction. -static void FlipCopyDXT1BlockHalf(const unsigned int* source, unsigned int* dest) { - // See layout above. - dest[0] = source[0]; - dest[1] = ((source[1] << 8) & 0x0000FF00) | - ((source[1] >> 8) & 0x000000FF); -} - -// Flips a full DXT3 block in the y direction. -static void FlipCopyDXT3BlockFull(const unsigned int* source, unsigned int* dest) { - // A DXT3 block layout is: - // [0-7] alpha bitmap, 4 bits per pixel. - // [8-15] a DXT1 block. - - // First and Second 32 bits are 4bit per pixel alpha and need to be flipped. - dest[0] = (source[1] >> 16) | (source[1] << 16); - dest[1] = (source[0] >> 16) | (source[0] << 16); - - // And flip the DXT1 block using the above function. - FlipCopyDXT1BlockFull(source + 2, dest + 2); -} - -// Flips the first 2 lines of a DXT3 block in the y direction. -static void FlipCopyDXT3BlockHalf(const unsigned int* source, unsigned int* dest) { - // See layout above. - dest[0] = (source[1] >> 16) | (source[1] << 16); - FlipCopyDXT1BlockHalf(source + 2, dest + 2); -} - -// Flips a full DXT5 block in the y direction. -static void FlipCopyDXT5BlockFull(const unsigned int* source, unsigned int* dest) { - // A DXT5 block layout is: - // [0] alpha0. - // [1] alpha1. - // [2-7] alpha bitmap, 3 bits per pixel. - // [8-15] a DXT1 block. - - // The alpha bitmap doesn't easily map lines to bytes, so we have to - // interpret it correctly. Extracted from - // http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt : - // - // The 6 "bits" bytes of the block are decoded into one 48-bit integer: - // - // bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * (bits_3 + - // 256 * (bits_4 + 256 * bits_5)))) - // - // bits is a 48-bit unsigned integer, from which a three-bit control code - // is extracted for a texel at location (x,y) in the block using: - // - // code(x,y) = bits[3*(4*y+x)+1..3*(4*y+x)+0] - // - // where bit 47 is the most significant and bit 0 is the least - // significant bit. - const unsigned char* sourceBytes = static_cast<const unsigned char*>(static_cast<const void*>(source)); - unsigned char* destBytes = static_cast<unsigned char*>(static_cast<void*>(dest)); - unsigned int line_0_1 = sourceBytes[2] + 256 * (sourceBytes[3] + 256 * sourceBytes[4]); - unsigned int line_2_3 = sourceBytes[5] + 256 * (sourceBytes[6] + 256 * sourceBytes[7]); - // swap lines 0 and 1 in line_0_1. - unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) | - ((line_0_1 & 0xfff000) >> 12); - // swap lines 2 and 3 in line_2_3. - unsigned int line_3_2 = ((line_2_3 & 0x000fff) << 12) | - ((line_2_3 & 0xfff000) >> 12); - destBytes[0] = sourceBytes[0]; - destBytes[1] = sourceBytes[1]; - destBytes[2] = line_3_2 & 0xff; - destBytes[3] = (line_3_2 & 0xff00) >> 8; - destBytes[4] = (line_3_2 & 0xff0000) >> 16; - destBytes[5] = line_1_0 & 0xff; - destBytes[6] = (line_1_0 & 0xff00) >> 8; - destBytes[7] = (line_1_0 & 0xff0000) >> 16; - - // And flip the DXT1 block using the above function. - FlipCopyDXT1BlockFull(source + 2, dest + 2); -} - -// Flips the first 2 lines of a DXT5 block in the y direction. -static void FlipCopyDXT5BlockHalf(const unsigned int* source, unsigned int* dest) { - // See layout above. - const unsigned char* sourceBytes = static_cast<const unsigned char*>(static_cast<const void*>(source)); - unsigned char* destBytes = static_cast<unsigned char*>(static_cast<void*>(dest)); - unsigned int line_0_1 = sourceBytes[2] + 256 * (sourceBytes[3] + 256 * sourceBytes[4]); - unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) | - ((line_0_1 & 0xfff000) >> 12); - destBytes[0] = sourceBytes[0]; - destBytes[1] = sourceBytes[1]; - destBytes[2] = line_1_0 & 0xff; - destBytes[3] = (line_1_0 & 0xff00) >> 8; - destBytes[4] = (line_1_0 & 0xff0000) >> 16; - FlipCopyDXT1BlockHalf(source + 2, dest + 2); -} - -void Image::loadDXT1Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) const -{ + const void *input) { ASSERT(xoffset % 4 == 0); ASSERT(yoffset % 4 == 0); - ASSERT(width % 4 == 0 || width == 2 || width == 1); - ASSERT(inputPitch % 8 == 0); - ASSERT(outputPitch % 8 == 0); - const unsigned int *source = reinterpret_cast<const unsigned int*>(input); - unsigned int *dest = reinterpret_cast<unsigned int*>(output); + RECT lockRect = { + xoffset, yoffset, + xoffset + width, yoffset + height + }; - // Round width up in case it is less than 4. - int blocksAcross = (width + 3) / 4; - int intsAcross = blocksAcross * 2; - - switch (height) + D3DLOCKED_RECT locked; + HRESULT result = lock(&locked, &lockRect); + if (FAILED(result)) { - case 1: - for (int x = 0; x < intsAcross; x += 2) - { - // just copy the block - dest[x] = source[x]; - dest[x + 1] = source[x + 1]; - } - break; - case 2: - for (int x = 0; x < intsAcross; x += 2) - { - FlipCopyDXT1BlockHalf(source + x, dest + x); - } - break; - default: - ASSERT(height % 4 == 0); - for (int y = 0; y < height / 4; ++y) - { - const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch); - unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8); - - for (int x = 0; x < intsAcross; x += 2) - { - FlipCopyDXT1BlockFull(source + x, dest + x); - } - } - break; + return; } -} -void Image::loadDXT3Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) const -{ - ASSERT(xoffset % 4 == 0); - ASSERT(yoffset % 4 == 0); - ASSERT(width % 4 == 0 || width == 2 || width == 1); - ASSERT(inputPitch % 16 == 0); - ASSERT(outputPitch % 16 == 0); - - const unsigned int *source = reinterpret_cast<const unsigned int*>(input); - unsigned int *dest = reinterpret_cast<unsigned int*>(output); - - // Round width up in case it is less than 4. - int blocksAcross = (width + 3) / 4; - int intsAcross = blocksAcross * 4; - - switch (height) + GLsizei inputSize = ComputeCompressedSize(width, height, mFormat); + GLsizei inputPitch = ComputeCompressedPitch(width, mFormat); + int rows = inputSize / inputPitch; + for (int i = 0; i < rows; ++i) { - case 1: - for (int x = 0; x < intsAcross; x += 4) - { - // just copy the block - dest[x] = source[x]; - dest[x + 1] = source[x + 1]; - dest[x + 2] = source[x + 2]; - dest[x + 3] = source[x + 3]; - } - break; - case 2: - for (int x = 0; x < intsAcross; x += 4) - { - FlipCopyDXT3BlockHalf(source + x, dest + x); - } - break; - default: - ASSERT(height % 4 == 0); - for (int y = 0; y < height / 4; ++y) - { - const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch); - unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16); - - for (int x = 0; x < intsAcross; x += 4) - { - FlipCopyDXT3BlockFull(source + x, dest + x); - } - } - break; + memcpy((void*)((BYTE*)locked.pBits + i * locked.Pitch), (void*)((BYTE*)input + i * inputPitch), inputPitch); } -} - -void Image::loadDXT5Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) const -{ - ASSERT(xoffset % 4 == 0); - ASSERT(yoffset % 4 == 0); - ASSERT(width % 4 == 0 || width == 2 || width == 1); - ASSERT(inputPitch % 16 == 0); - ASSERT(outputPitch % 16 == 0); - - const unsigned int *source = reinterpret_cast<const unsigned int*>(input); - unsigned int *dest = reinterpret_cast<unsigned int*>(output); - - // Round width up in case it is less than 4. - int blocksAcross = (width + 3) / 4; - int intsAcross = blocksAcross * 4; - - switch (height) - { - case 1: - for (int x = 0; x < intsAcross; x += 4) - { - // just copy the block - dest[x] = source[x]; - dest[x + 1] = source[x + 1]; - dest[x + 2] = source[x + 2]; - dest[x + 3] = source[x + 3]; - } - break; - case 2: - for (int x = 0; x < intsAcross; x += 4) - { - FlipCopyDXT5BlockHalf(source + x, dest + x); - } - break; - default: - ASSERT(height % 4 == 0); - for (int y = 0; y < height / 4; ++y) - { - const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch); - unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16); - for (int x = 0; x < intsAcross; x += 4) - { - FlipCopyDXT5BlockFull(source + x, dest + x); - } - } - break; - } + unlock(); } // This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures @@ -1121,9 +963,8 @@ void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, return error(GL_OUT_OF_MEMORY); } - RECT sourceRect = transformPixelRect(x, y, width, height, description.Height); - int destYOffset = transformPixelYOffset(yoffset, height, mHeight); - RECT destRect = {xoffset, destYOffset, xoffset + width, destYOffset + height}; + RECT sourceRect = {x, y, x + width, y + height}; + RECT destRect = {xoffset, yoffset, xoffset + width, yoffset + height}; if (isRenderableFormat()) { @@ -1267,9 +1108,9 @@ void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, mDirty = true; } -TextureStorage::TextureStorage(bool renderTarget) - : mRenderTarget(renderTarget), - mD3DPool(getDisplay()->getTexturePool(mRenderTarget)), +TextureStorage::TextureStorage(DWORD usage) + : mD3DUsage(usage), + mD3DPool(getDisplay()->getTexturePool(usage)), mTextureSerial(issueTextureSerial()) { } @@ -1280,7 +1121,7 @@ TextureStorage::~TextureStorage() bool TextureStorage::isRenderTarget() const { - return mRenderTarget; + return (mD3DUsage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) != 0; } bool TextureStorage::isManaged() const @@ -1293,6 +1134,11 @@ D3DPOOL TextureStorage::getPool() const return mD3DPool; } +DWORD TextureStorage::getUsage() const +{ + return mD3DUsage; +} + unsigned int TextureStorage::getTextureSerial() const { return mTextureSerial; @@ -1450,15 +1296,7 @@ void Texture::setImage(GLint unpackAlignment, const void *pixels, Image *image) { if (pixels != NULL) { - D3DLOCKED_RECT locked; - HRESULT result = image->lock(&locked, NULL); - - if (SUCCEEDED(result)) - { - image->loadData(0, 0, image->getWidth(), image->getHeight(), image->getType(), unpackAlignment, pixels, locked.Pitch, locked.pBits); - image->unlock(); - } - + image->loadData(0, 0, image->getWidth(), image->getHeight(), image->getType(), unpackAlignment, pixels); mDirtyImages = true; } } @@ -1467,52 +1305,16 @@ void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, Image *i { if (pixels != NULL) { - D3DLOCKED_RECT locked; - HRESULT result = image->lock(&locked, NULL); - - if (SUCCEEDED(result)) - { - int inputPitch = ComputeCompressedPitch(image->getWidth(), image->getFormat()); - int inputSize = ComputeCompressedSize(image->getWidth(), image->getHeight(), image->getFormat()); - image->loadCompressedData(0, 0, image->getWidth(), image->getHeight(), -inputPitch, static_cast<const char*>(pixels) + inputSize - inputPitch, locked.Pitch, locked.pBits); - image->unlock(); - } - + image->loadCompressedData(0, 0, image->getWidth(), image->getHeight(), pixels); mDirtyImages = true; } } bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image) { - if (width + xoffset > image->getWidth() || height + yoffset > image->getHeight()) - { - error(GL_INVALID_VALUE); - return false; - } - - if (IsCompressed(image->getFormat())) - { - error(GL_INVALID_OPERATION); - return false; - } - - if (format != image->getFormat()) - { - error(GL_INVALID_OPERATION); - return false; - } - if (pixels != NULL) { - D3DLOCKED_RECT locked; - HRESULT result = image->lock(&locked, NULL); - - if (SUCCEEDED(result)) - { - image->loadData(xoffset, transformPixelYOffset(yoffset, height, image->getHeight()), width, height, type, unpackAlignment, pixels, locked.Pitch, locked.pBits); - image->unlock(); - } - + image->loadData(xoffset, yoffset, width, height, type, unpackAlignment, pixels); mDirtyImages = true; } @@ -1521,37 +1323,9 @@ bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image) { - if (width + xoffset > image->getWidth() || height + yoffset > image->getHeight()) - { - error(GL_INVALID_VALUE); - return false; - } - - if (format != getInternalFormat()) - { - error(GL_INVALID_OPERATION); - return false; - } - if (pixels != NULL) { - RECT updateRegion; - updateRegion.left = xoffset; - updateRegion.right = xoffset + width; - updateRegion.bottom = yoffset + height; - updateRegion.top = yoffset; - - D3DLOCKED_RECT locked; - HRESULT result = image->lock(&locked, &updateRegion); - - if (SUCCEEDED(result)) - { - int inputPitch = ComputeCompressedPitch(width, format); - int inputSize = ComputeCompressedSize(width, height, format); - image->loadCompressedData(xoffset, transformPixelYOffset(yoffset, height, image->getHeight()), width, height, -inputPitch, static_cast<const char*>(pixels) + inputSize - inputPitch, locked.Pitch, locked.pBits); - image->unlock(); - } - + image->loadCompressedData(xoffset, yoffset, width, height, pixels); mDirtyImages = true; } @@ -1667,23 +1441,27 @@ bool Texture::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *sou return true; } -TextureStorage2D::TextureStorage2D(IDirect3DTexture9 *surfaceTexture) : TextureStorage(true), mRenderTargetSerial(RenderbufferStorage::issueSerial()) +TextureStorage2D::TextureStorage2D(IDirect3DTexture9 *surfaceTexture) : TextureStorage(D3DUSAGE_RENDERTARGET), mRenderTargetSerial(RenderbufferStorage::issueSerial()) { mTexture = surfaceTexture; } -TextureStorage2D::TextureStorage2D(int levels, D3DFORMAT format, int width, int height, bool renderTarget) - : TextureStorage(renderTarget), mRenderTargetSerial(RenderbufferStorage::issueSerial()) +TextureStorage2D::TextureStorage2D(int levels, D3DFORMAT format, DWORD usage, int width, int height) + : TextureStorage(usage), mRenderTargetSerial(RenderbufferStorage::issueSerial()) { - IDirect3DDevice9 *device = getDevice(); - mTexture = NULL; - HRESULT result = device->CreateTexture(width, height, levels, isRenderTarget() ? D3DUSAGE_RENDERTARGET : 0, format, getPool(), &mTexture, NULL); - - if (FAILED(result)) + // if the width or height is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (width > 0 && height > 0) { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - error(GL_OUT_OF_MEMORY); + IDirect3DDevice9 *device = getDevice(); + HRESULT result = device->CreateTexture(width, height, levels, getUsage(), format, getPool(), &mTexture, NULL); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + error(GL_OUT_OF_MEMORY); + } } } @@ -1695,6 +1473,8 @@ TextureStorage2D::~TextureStorage2D() } } +// Increments refcount on surface. +// caller must Release() the returned surface IDirect3DSurface9 *TextureStorage2D::getSurfaceLevel(int level) { IDirect3DSurface9 *surface = NULL; @@ -1778,19 +1558,20 @@ GLsizei Texture2D::getHeight(GLint level) const return 0; } -GLenum Texture2D::getInternalFormat() const +GLenum Texture2D::getInternalFormat(GLint level) const { - return mImageArray[0].getFormat(); -} - -GLenum Texture2D::getType() const -{ - return mImageArray[0].getType(); + if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) + return mImageArray[level].getFormat(); + else + return GL_NONE; } -D3DFORMAT Texture2D::getD3DFormat() const +D3DFORMAT Texture2D::getD3DFormat(GLint level) const { - return mImageArray[0].getD3DFormat(); + if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) + return mImageArray[level].getD3DFormat(); + else + return D3DFMT_UNKNOWN; } void Texture2D::redefineImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type) @@ -1938,19 +1719,17 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei if (width != 0 && height != 0 && level < levelCount()) { - RECT sourceRect = transformPixelRect(x, y, width, height, source->getColorbuffer()->getHeight()); - sourceRect.left = clamp(sourceRect.left, 0, source->getColorbuffer()->getWidth()); - sourceRect.top = clamp(sourceRect.top, 0, source->getColorbuffer()->getHeight()); - sourceRect.right = clamp(sourceRect.right, 0, source->getColorbuffer()->getWidth()); - sourceRect.bottom = clamp(sourceRect.bottom, 0, source->getColorbuffer()->getHeight()); - - GLint destYOffset = transformPixelYOffset(0, height, mImageArray[level].getHeight()); + RECT sourceRect; + sourceRect.left = x; + sourceRect.right = x + width; + sourceRect.top = y; + sourceRect.bottom = y + height; IDirect3DSurface9 *dest = mTexStorage->getSurfaceLevel(level); if (dest) { - getBlitter()->copy(renderTarget, sourceRect, format, 0, destYOffset, dest); + getBlitter()->copy(renderTarget, sourceRect, format, 0, 0, dest); dest->Release(); } } @@ -1990,19 +1769,18 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo if (level < levelCount()) { - RECT sourceRect = transformPixelRect(x, y, width, height, source->getColorbuffer()->getHeight()); - sourceRect.left = clamp(sourceRect.left, 0, source->getColorbuffer()->getWidth()); - sourceRect.top = clamp(sourceRect.top, 0, source->getColorbuffer()->getHeight()); - sourceRect.right = clamp(sourceRect.right, 0, source->getColorbuffer()->getWidth()); - sourceRect.bottom = clamp(sourceRect.bottom, 0, source->getColorbuffer()->getHeight()); + RECT sourceRect; + sourceRect.left = x; + sourceRect.right = x + width; + sourceRect.top = y; + sourceRect.bottom = y + height; - GLint destYOffset = transformPixelYOffset(yoffset, height, mImageArray[level].getHeight()); IDirect3DSurface9 *dest = mTexStorage->getSurfaceLevel(level); if (dest) { - getBlitter()->copy(renderTarget, sourceRect, mImageArray[0].getFormat(), xoffset, destYOffset, dest); + getBlitter()->copy(renderTarget, sourceRect, mImageArray[0].getFormat(), xoffset, yoffset, dest); dest->Release(); } } @@ -2016,10 +1794,10 @@ void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GL GLenum format = gl::ExtractFormat(internalformat); GLenum type = gl::ExtractType(internalformat); D3DFORMAT d3dfmt = ConvertTextureFormatType(format, type); - const bool renderTarget = IsTextureFormatRenderable(d3dfmt) && (mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); + DWORD d3dusage = GetTextureUsage(d3dfmt, mUsage, false); delete mTexStorage; - mTexStorage = new TextureStorage2D(levels, d3dfmt, width, height, renderTarget); + mTexStorage = new TextureStorage2D(levels, d3dfmt, d3dusage, width, height); mImmutable = true; for (int level = 0; level < levels; level++) @@ -2074,8 +1852,8 @@ bool Texture2D::isSamplerComplete() const default: UNREACHABLE(); } - if ((getInternalFormat() == GL_FLOAT && !getContext()->supportsFloat32LinearFilter()) || - (getInternalFormat() == GL_HALF_FLOAT_OES && !getContext()->supportsFloat16LinearFilter())) + if ((getInternalFormat(0) == GL_FLOAT && !getContext()->supportsFloat32LinearFilter()) || + (getInternalFormat(0) == GL_HALF_FLOAT_OES && !getContext()->supportsFloat16LinearFilter())) { if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST)) { @@ -2157,9 +1935,14 @@ bool Texture2D::isMipmapComplete() const return true; } -bool Texture2D::isCompressed() const +bool Texture2D::isCompressed(GLint level) const +{ + return IsCompressed(getInternalFormat(level)); +} + +bool Texture2D::isDepth(GLint level) const { - return IsCompressed(getInternalFormat()); + return IsDepthTexture(getInternalFormat(level)); } IDirect3DBaseTexture9 *Texture2D::getBaseTexture() const @@ -2173,11 +1956,11 @@ void Texture2D::createTexture() GLsizei width = mImageArray[0].getWidth(); GLsizei height = mImageArray[0].getHeight(); GLint levels = creationLevels(width, height); - D3DFORMAT format = mImageArray[0].getD3DFormat(); - const bool renderTarget = IsTextureFormatRenderable(format) && (mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); + D3DFORMAT d3dfmt = mImageArray[0].getD3DFormat(); + DWORD d3dusage = GetTextureUsage(d3dfmt, mUsage, false); delete mTexStorage; - mTexStorage = new TextureStorage2D(levels, format, width, height, renderTarget); + mTexStorage = new TextureStorage2D(levels, d3dfmt, d3dusage, width, height); if (mTexStorage->isManaged()) { @@ -2217,9 +2000,10 @@ void Texture2D::convertToRenderTarget() GLsizei width = mImageArray[0].getWidth(); GLsizei height = mImageArray[0].getHeight(); GLint levels = creationLevels(width, height); - D3DFORMAT format = mImageArray[0].getD3DFormat(); + D3DFORMAT d3dfmt = mImageArray[0].getD3DFormat(); + DWORD d3dusage = GetTextureUsage(d3dfmt, GL_FRAMEBUFFER_ATTACHMENT_ANGLE, true); - newTexStorage = new TextureStorage2D(levels, format, width, height, true); + newTexStorage = new TextureStorage2D(levels, d3dfmt, d3dusage, width, height); if (mTexStorage != NULL) { @@ -2232,8 +2016,8 @@ void Texture2D::convertToRenderTarget() if (!copyToRenderTarget(dest, source, mTexStorage->isManaged())) { delete newTexStorage; - source->Release(); - dest->Release(); + if (source) source->Release(); + if (dest) dest->Release(); return error(GL_OUT_OF_MEMORY); } @@ -2315,12 +2099,14 @@ Renderbuffer *Texture2D::getRenderbuffer(GLenum target) if (mColorbufferProxy == NULL) { - mColorbufferProxy = new Renderbuffer(id(), new RenderbufferTexture(this, target)); + mColorbufferProxy = new Renderbuffer(id(), new RenderbufferTexture2D(this, target)); } return mColorbufferProxy; } +// Increments refcount on surface. +// caller must Release() the returned surface IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target) { ASSERT(target == GL_TEXTURE_2D); @@ -2333,6 +2119,33 @@ IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target) updateTexture(); + // ensure this is NOT a depth texture + if (isDepth(0)) + { + return NULL; + } + return mTexStorage->getSurfaceLevel(0); +} + +// Increments refcount on surface. +// caller must Release() the returned surface +IDirect3DSurface9 *Texture2D::getDepthStencil(GLenum target) +{ + ASSERT(target == GL_TEXTURE_2D); + + // ensure the underlying texture is created + if (getStorage(true) == NULL) + { + return NULL; + } + + updateTexture(); + + // ensure this is actually a depth texture + if (!isDepth(0)) + { + return NULL; + } return mTexStorage->getSurfaceLevel(0); } @@ -2353,18 +2166,22 @@ TextureStorage *Texture2D::getStorage(bool renderTarget) return mTexStorage; } -TextureStorageCubeMap::TextureStorageCubeMap(int levels, D3DFORMAT format, int size, bool renderTarget) - : TextureStorage(renderTarget), mFirstRenderTargetSerial(RenderbufferStorage::issueCubeSerials()) +TextureStorageCubeMap::TextureStorageCubeMap(int levels, D3DFORMAT format, DWORD usage, int size) + : TextureStorage(usage), mFirstRenderTargetSerial(RenderbufferStorage::issueCubeSerials()) { - IDirect3DDevice9 *device = getDevice(); - mTexture = NULL; - HRESULT result = device->CreateCubeTexture(size, levels, isRenderTarget() ? D3DUSAGE_RENDERTARGET : 0, format, getPool(), &mTexture, NULL); - - if (FAILED(result)) + // if the size is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (size > 0) { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - error(GL_OUT_OF_MEMORY); + IDirect3DDevice9 *device = getDevice(); + HRESULT result = device->CreateCubeTexture(size, levels, getUsage(), format, getPool(), &mTexture, NULL); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + error(GL_OUT_OF_MEMORY); + } } } @@ -2376,6 +2193,8 @@ TextureStorageCubeMap::~TextureStorageCubeMap() } } +// Increments refcount on surface. +// caller must Release() the returned surface IDirect3DSurface9 *TextureStorageCubeMap::getCubeMapSurface(GLenum faceTarget, int level) { IDirect3DSurface9 *surface = NULL; @@ -2454,35 +2273,36 @@ GLenum TextureCubeMap::getTarget() const return GL_TEXTURE_CUBE_MAP; } -GLsizei TextureCubeMap::getWidth(GLint level) const +GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const { if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) - return mImageArray[0][level].getWidth(); + return mImageArray[faceIndex(target)][level].getWidth(); else return 0; } -GLsizei TextureCubeMap::getHeight(GLint level) const +GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const { if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) - return mImageArray[0][level].getHeight(); + return mImageArray[faceIndex(target)][level].getHeight(); else return 0; } -GLenum TextureCubeMap::getInternalFormat() const +GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const { - return mImageArray[0][0].getFormat(); -} - -GLenum TextureCubeMap::getType() const -{ - return mImageArray[0][0].getType(); + if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) + return mImageArray[faceIndex(target)][level].getFormat(); + else + return GL_NONE; } -D3DFORMAT TextureCubeMap::getD3DFormat() const +D3DFORMAT TextureCubeMap::getD3DFormat(GLenum target, GLint level) const { - return mImageArray[0][0].getD3DFormat(); + if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) + return mImageArray[faceIndex(target)][level].getD3DFormat(); + else + return D3DFMT_UNKNOWN; } void TextureCubeMap::setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) @@ -2582,8 +2402,8 @@ bool TextureCubeMap::isSamplerComplete() const return false; } - if ((getInternalFormat() == GL_FLOAT && !getContext()->supportsFloat32LinearFilter()) || - (getInternalFormat() == GL_HALF_FLOAT_OES && !getContext()->supportsFloat16LinearFilter())) + if ((getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0) == GL_FLOAT && !getContext()->supportsFloat32LinearFilter()) || + (getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0) == GL_HALF_FLOAT_OES && !getContext()->supportsFloat16LinearFilter())) { if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST)) { @@ -2679,9 +2499,9 @@ bool TextureCubeMap::isMipmapCubeComplete() const return true; } -bool TextureCubeMap::isCompressed() const +bool TextureCubeMap::isCompressed(GLenum target, GLint level) const { - return IsCompressed(getInternalFormat()); + return IsCompressed(getInternalFormat(target, level)); } IDirect3DBaseTexture9 *TextureCubeMap::getBaseTexture() const @@ -2694,11 +2514,11 @@ void TextureCubeMap::createTexture() { GLsizei size = mImageArray[0][0].getWidth(); GLint levels = creationLevels(size, 0); - D3DFORMAT format = mImageArray[0][0].getD3DFormat(); - const bool renderTarget = IsTextureFormatRenderable(format) && (mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); + D3DFORMAT d3dfmt = mImageArray[0][0].getD3DFormat(); + DWORD d3dusage = GetTextureUsage(d3dfmt, mUsage, false); delete mTexStorage; - mTexStorage = new TextureStorageCubeMap(levels, format, size, renderTarget); + mTexStorage = new TextureStorageCubeMap(levels, d3dfmt, d3dusage, size); if (mTexStorage->isManaged()) { @@ -2742,9 +2562,10 @@ void TextureCubeMap::convertToRenderTarget() { GLsizei size = mImageArray[0][0].getWidth(); GLint levels = creationLevels(size, 0); - D3DFORMAT format = mImageArray[0][0].getD3DFormat(); + D3DFORMAT d3dfmt = mImageArray[0][0].getD3DFormat(); + DWORD d3dusage = GetTextureUsage(d3dfmt, GL_FRAMEBUFFER_ATTACHMENT_ANGLE, true); - newTexStorage = new TextureStorageCubeMap(levels, format, size, true); + newTexStorage = new TextureStorageCubeMap(levels, d3dfmt, d3dusage, size); if (mTexStorage != NULL) { @@ -2759,8 +2580,8 @@ void TextureCubeMap::convertToRenderTarget() if (!copyToRenderTarget(dest, source, mTexStorage->isManaged())) { delete newTexStorage; - source->Release(); - dest->Release(); + if (source) source->Release(); + if (dest) dest->Release(); return error(GL_OUT_OF_MEMORY); } @@ -2847,19 +2668,17 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint if (width > 0 && level < levelCount()) { - RECT sourceRect = transformPixelRect(x, y, width, height, source->getColorbuffer()->getHeight()); - sourceRect.left = clamp(sourceRect.left, 0, source->getColorbuffer()->getWidth()); - sourceRect.top = clamp(sourceRect.top, 0, source->getColorbuffer()->getHeight()); - sourceRect.right = clamp(sourceRect.right, 0, source->getColorbuffer()->getWidth()); - sourceRect.bottom = clamp(sourceRect.bottom, 0, source->getColorbuffer()->getHeight()); - - GLint destYOffset = transformPixelYOffset(0, height, mImageArray[faceindex][level].getWidth()); + RECT sourceRect; + sourceRect.left = x; + sourceRect.right = x + width; + sourceRect.top = y; + sourceRect.bottom = y + height; IDirect3DSurface9 *dest = mTexStorage->getCubeMapSurface(target, level); if (dest) { - getBlitter()->copy(renderTarget, sourceRect, format, 0, destYOffset, dest); + getBlitter()->copy(renderTarget, sourceRect, format, 0, 0, dest); dest->Release(); } } @@ -2903,19 +2722,17 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi if (level < levelCount()) { - RECT sourceRect = transformPixelRect(x, y, width, height, source->getColorbuffer()->getHeight()); - sourceRect.left = clamp(sourceRect.left, 0, source->getColorbuffer()->getWidth()); - sourceRect.top = clamp(sourceRect.top, 0, source->getColorbuffer()->getHeight()); - sourceRect.right = clamp(sourceRect.right, 0, source->getColorbuffer()->getWidth()); - sourceRect.bottom = clamp(sourceRect.bottom, 0, source->getColorbuffer()->getHeight()); - - GLint destYOffset = transformPixelYOffset(yoffset, height, mImageArray[faceindex][level].getWidth()); + RECT sourceRect; + sourceRect.left = x; + sourceRect.right = x + width; + sourceRect.top = y; + sourceRect.bottom = y + height; IDirect3DSurface9 *dest = mTexStorage->getCubeMapSurface(target, level); if (dest) { - getBlitter()->copy(renderTarget, sourceRect, mImageArray[0][0].getFormat(), xoffset, destYOffset, dest); + getBlitter()->copy(renderTarget, sourceRect, mImageArray[0][0].getFormat(), xoffset, yoffset, dest); dest->Release(); } } @@ -2929,10 +2746,10 @@ void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size GLenum format = gl::ExtractFormat(internalformat); GLenum type = gl::ExtractType(internalformat); D3DFORMAT d3dfmt = ConvertTextureFormatType(format, type); - const bool renderTarget = IsTextureFormatRenderable(d3dfmt) && (mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); + DWORD d3dusage = GetTextureUsage(d3dfmt, mUsage, false); delete mTexStorage; - mTexStorage = new TextureStorageCubeMap(levels, d3dfmt, size, renderTarget); + mTexStorage = new TextureStorageCubeMap(levels, d3dfmt, d3dusage, size); mImmutable = true; for (int level = 0; level < levels; level++) @@ -3049,12 +2866,14 @@ Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target) if (mFaceProxies[face] == NULL) { - mFaceProxies[face] = new Renderbuffer(id(), new RenderbufferTexture(this, target)); + mFaceProxies[face] = new Renderbuffer(id(), new RenderbufferTextureCubeMap(this, target)); } return mFaceProxies[face]; } +// Increments refcount on surface. +// caller must Release() the returned surface IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target) { ASSERT(IsCubemapTextureTarget(target)); @@ -3087,4 +2906,4 @@ TextureStorage *TextureCubeMap::getStorage(bool renderTarget) return mTexStorage; } -}
\ No newline at end of file +} diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.h index 19a6eb59c..313a162b6 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.h @@ -53,9 +53,6 @@ class Image void markDirty() {mDirty = true;} void markClean() {mDirty = false;} - HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect); - void unlock(); - bool isRenderableFormat() const; D3DFORMAT getD3DFormat() const; @@ -70,56 +67,52 @@ class Image void updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type, - GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const; + GLint unpackAlignment, const void *input); - void loadAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadAlphaData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadAlphaDataSSE2(GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadAlphaFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadAlphaHalfFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadLuminanceData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadLuminanceData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const; - void loadLuminanceFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadLuminanceFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadLuminanceHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadLuminanceHalfFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadLuminanceAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadLuminanceAlphaData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const; - void loadLuminanceAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadLuminanceAlphaFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadLuminanceAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadLuminanceAlphaHalfFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadRGBUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadRGBUByteData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadRGB565Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadRGB565Data(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadRGBFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadRGBFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadRGBHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadRGBHalfFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadRGBAUByteDataSSE2(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadRGBAUByteDataSSE2(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadRGBAUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadRGBAUByteData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadRGBA4444Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadRGBA4444Data(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadRGBA5551Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadRGBA5551Data(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadRGBAFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadRGBAFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadRGBAHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadRGBAHalfFloatData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadBGRAData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + void loadBGRAData(GLsizei width, GLsizei height, int inputPitch, const void *input, size_t outputPitch, void *output) const; void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadDXT1Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadDXT3Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) const; - void loadDXT5Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - int inputPitch, const void *input, size_t outputPitch, void *output) const; + const void *input); void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget); @@ -128,6 +121,9 @@ class Image void createSurface(); + HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect); + void unlock(); + GLsizei mWidth; GLsizei mHeight; GLenum mFormat; @@ -144,20 +140,21 @@ class Image class TextureStorage { public: - explicit TextureStorage(bool renderTarget); + explicit TextureStorage(DWORD usage); virtual ~TextureStorage(); bool isRenderTarget() const; bool isManaged() const; D3DPOOL getPool() const; + DWORD getUsage() const; unsigned int getTextureSerial() const; virtual unsigned int getRenderTargetSerial(GLenum target) const = 0; private: DISALLOW_COPY_AND_ASSIGN(TextureStorage); - const bool mRenderTarget; + const DWORD mD3DUsage; const D3DPOOL mD3DPool; const unsigned int mTextureSerial; @@ -190,14 +187,7 @@ class Texture : public RefCountObject GLenum getWrapT() const; GLenum getUsage() const; - virtual GLsizei getWidth(GLint level) const = 0; - virtual GLsizei getHeight(GLint level) const = 0; - virtual GLenum getInternalFormat() const = 0; - virtual GLenum getType() const = 0; - virtual D3DFORMAT getD3DFormat() const = 0; - virtual bool isSamplerComplete() const = 0; - virtual bool isCompressed() const = 0; IDirect3DBaseTexture9 *getTexture(); virtual Renderbuffer *getRenderbuffer(GLenum target) = 0; @@ -216,8 +206,6 @@ class Texture : public RefCountObject static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager. protected: - friend class RenderbufferTexture; - void setImage(GLint unpackAlignment, const void *pixels, Image *image); bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image); void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image); @@ -258,7 +246,7 @@ class TextureStorage2D : public TextureStorage { public: explicit TextureStorage2D(IDirect3DTexture9 *surfaceTexture); - TextureStorage2D(int levels, D3DFORMAT format, int width, int height, bool renderTarget); + TextureStorage2D(int levels, D3DFORMAT format, DWORD usage, int width, int height); virtual ~TextureStorage2D(); @@ -286,11 +274,12 @@ class Texture2D : public Texture virtual GLenum getTarget() const; - virtual GLsizei getWidth(GLint level) const; - virtual GLsizei getHeight(GLint level) const; - virtual GLenum getInternalFormat() const; - virtual GLenum getType() const; - virtual D3DFORMAT getD3DFormat() const; + GLsizei getWidth(GLint level) const; + GLsizei getHeight(GLint level) const; + GLenum getInternalFormat(GLint level) const; + D3DFORMAT getD3DFormat(GLint level) const; + bool isCompressed(GLint level) const; + bool isDepth(GLint level) const; void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); @@ -301,7 +290,6 @@ class Texture2D : public Texture void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); virtual bool isSamplerComplete() const; - virtual bool isCompressed() const; virtual void bindTexImage(egl::Surface *surface); virtual void releaseTexImage(); @@ -309,6 +297,11 @@ class Texture2D : public Texture virtual Renderbuffer *getRenderbuffer(GLenum target); + protected: + friend class RenderbufferTexture2D; + virtual IDirect3DSurface9 *getRenderTarget(GLenum target); + virtual IDirect3DSurface9 *getDepthStencil(GLenum target); + private: DISALLOW_COPY_AND_ASSIGN(Texture2D); @@ -316,7 +309,6 @@ class Texture2D : public Texture virtual void createTexture(); virtual void updateTexture(); virtual void convertToRenderTarget(); - virtual IDirect3DSurface9 *getRenderTarget(GLenum target); virtual TextureStorage *getStorage(bool renderTarget); bool isMipmapComplete() const; @@ -341,7 +333,7 @@ class Texture2D : public Texture class TextureStorageCubeMap : public TextureStorage { public: - TextureStorageCubeMap(int levels, D3DFORMAT format, int size, bool renderTarget); + TextureStorageCubeMap(int levels, D3DFORMAT format, DWORD usage, int size); virtual ~TextureStorageCubeMap(); @@ -369,11 +361,11 @@ class TextureCubeMap : public Texture virtual GLenum getTarget() const; - virtual GLsizei getWidth(GLint level) const; - virtual GLsizei getHeight(GLint level) const; - virtual GLenum getInternalFormat() const; - virtual GLenum getType() const; - virtual D3DFORMAT getD3DFormat() const; + GLsizei getWidth(GLenum target, GLint level) const; + GLsizei getHeight(GLenum target, GLint level) const; + GLenum getInternalFormat(GLenum target, GLint level) const; + D3DFORMAT getD3DFormat(GLenum target, GLint level) const; + bool isCompressed(GLenum target, GLint level) const; void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); @@ -391,7 +383,6 @@ class TextureCubeMap : public Texture void storage(GLsizei levels, GLenum internalformat, GLsizei size); virtual bool isSamplerComplete() const; - virtual bool isCompressed() const; virtual void generateMipmaps(); @@ -399,6 +390,10 @@ class TextureCubeMap : public Texture static unsigned int faceIndex(GLenum face); + protected: + friend class RenderbufferTextureCubeMap; + virtual IDirect3DSurface9 *getRenderTarget(GLenum target); + private: DISALLOW_COPY_AND_ASSIGN(TextureCubeMap); @@ -406,7 +401,6 @@ class TextureCubeMap : public Texture virtual void createTexture(); virtual void updateTexture(); virtual void convertToRenderTarget(); - virtual IDirect3DSurface9 *getRenderTarget(GLenum target); virtual TextureStorage *getStorage(bool renderTarget); bool isCubeComplete() const; diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/VertexDataManager.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/VertexDataManager.cpp index 95bc3fb87..70f475f8d 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/VertexDataManager.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/VertexDataManager.cpp @@ -13,6 +13,7 @@ #include "libGLESv2/Buffer.h" #include "libGLESv2/Program.h" +#include "libGLESv2/ProgramBinary.h" #include "libGLESv2/main.h" #include "libGLESv2/vertexconversion.h" @@ -128,10 +129,11 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat const VertexAttributeArray &attribs = mContext->getVertexAttributes(); Program *program = mContext->getCurrentProgram(); + ProgramBinary *programBinary = program->getProgramBinary(); for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) { - translated[attributeIndex].active = (program->getSemanticIndex(attributeIndex) != -1); + translated[attributeIndex].active = (programBinary->getSemanticIndex(attributeIndex) != -1); } // Determine the required storage size per used buffer, and invalidate static buffers that don't contain matching attributes @@ -448,8 +450,8 @@ struct ConversionRule : gl::Cast<typename GLToCType<fromType>::type, typename D3 template <GLenum fromType> struct ConversionRule<fromType, true, D3DVT_FLOAT> : gl::Normalize<typename GLToCType<fromType>::type> { }; // Use a full specialisation for this so that it preferentially matches ahead of the generic normalize-to-float rules. -template <> struct ConversionRule<GL_FIXED, true, D3DVT_FLOAT> : gl::FixedToFloat<GLuint, 16> { }; -template <> struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : gl::FixedToFloat<GLuint, 16> { }; +template <> struct ConversionRule<GL_FIXED, true, D3DVT_FLOAT> : gl::FixedToFloat<GLint, 16> { }; +template <> struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : gl::FixedToFloat<GLint, 16> { }; // A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues (i.e. 0/1) // whether it is normalized or not. diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp index ee8eca9dc..fba253d8a 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp @@ -24,6 +24,7 @@ #include "libGLESv2/Fence.h" #include "libGLESv2/Framebuffer.h" #include "libGLESv2/Program.h" +#include "libGLESv2/ProgramBinary.h" #include "libGLESv2/Renderbuffer.h" #include "libGLESv2/Shader.h" #include "libGLESv2/Texture.h" @@ -54,26 +55,121 @@ bool validImageSize(GLint level, GLsizei width, GLsizei height) return false; } -bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLint level, GLenum format, gl::Texture *texture) +// Verify that format/type are one of the combinations from table 3.4. +bool checkTextureFormatType(GLenum format, GLenum type) +{ + // validate <format> by itself (used as secondary key below) + switch (format) + { + case GL_RGBA: + case GL_BGRA_EXT: + case GL_RGB: + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL_OES: + break; + default: + return error(GL_INVALID_ENUM, false); + } + + // invalid <type> -> sets INVALID_ENUM + // invalid <format>+<type> combination -> sets INVALID_OPERATION + switch (type) + { + case GL_UNSIGNED_BYTE: + switch (format) + { + case GL_RGBA: + case GL_BGRA_EXT: + case GL_RGB: + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + return true; + default: + return error(GL_INVALID_OPERATION, false); + } + + case GL_FLOAT: + case GL_HALF_FLOAT_OES: + switch (format) + { + case GL_RGBA: + case GL_RGB: + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + return true; + default: + return error(GL_INVALID_OPERATION, false); + } + + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_5_5_5_1: + switch (format) + { + case GL_RGBA: + return true; + default: + return error(GL_INVALID_OPERATION, false); + } + + case GL_UNSIGNED_SHORT_5_6_5: + switch (format) + { + case GL_RGB: + return true; + default: + return error(GL_INVALID_OPERATION, false); + } + + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_INT: + switch (format) + { + case GL_DEPTH_COMPONENT: + return true; + default: + return error(GL_INVALID_OPERATION, false); + } + + case GL_UNSIGNED_INT_24_8_OES: + switch (format) + { + case GL_DEPTH_STENCIL_OES: + return true; + default: + return error(GL_INVALID_OPERATION, false); + } + + default: + return error(GL_INVALID_ENUM, false); + } +} +bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height, + GLint xoffset, GLint yoffset, GLint level, GLenum format, + gl::Texture2D *texture) { if (!texture) { return error(GL_INVALID_OPERATION, false); } - if (compressed != texture->isCompressed()) + if (compressed != texture->isCompressed(level)) { return error(GL_INVALID_OPERATION, false); } - if (format != GL_NONE && format != texture->getInternalFormat()) + if (format != GL_NONE && format != texture->getInternalFormat(level)) { return error(GL_INVALID_OPERATION, false); } if (compressed) { - if ((width % 4 != 0 && width != texture->getWidth(0)) || + if ((width % 4 != 0 && width != texture->getWidth(0)) || (height % 4 != 0 && height != texture->getHeight(0))) { return error(GL_INVALID_OPERATION, false); @@ -89,6 +185,43 @@ bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLin return true; } +bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height, + GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, + gl::TextureCubeMap *texture) +{ + if (!texture) + { + return error(GL_INVALID_OPERATION, false); + } + + if (compressed != texture->isCompressed(target, level)) + { + return error(GL_INVALID_OPERATION, false); + } + + if (format != GL_NONE && format != texture->getInternalFormat(target, level)) + { + return error(GL_INVALID_OPERATION, false); + } + + if (compressed) + { + if ((width % 4 != 0 && width != texture->getWidth(target, 0)) || + (height % 4 != 0 && height != texture->getHeight(target, 0))) + { + return error(GL_INVALID_OPERATION, false); + } + } + + if (xoffset + width > texture->getWidth(target, level) || + yoffset + height > texture->getHeight(target, level)) + { + return error(GL_INVALID_VALUE, false); + } + + return true; +} + // check for combinations of format and type that are valid for ReadPixels bool validReadFormatType(GLenum format, GLenum type) { @@ -1094,7 +1227,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs if (target == GL_TEXTURE_2D) { gl::Texture2D *texture = context->getTexture2D(); - if (validateSubImageParams(true, width, height, xoffset, yoffset, level, GL_NONE, texture)) + if (validateSubImageParams2D(true, width, height, xoffset, yoffset, level, format, texture)) { texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data); } @@ -1102,7 +1235,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs else if (gl::IsCubemapTextureTarget(target)) { gl::TextureCubeMap *texture = context->getTextureCubeMap(); - if (validateSubImageParams(true, width, height, xoffset, yoffset, level, GL_NONE, texture)) + if (validateSubImageParamsCube(true, width, height, xoffset, yoffset, target, level, format, texture)) { texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data); } @@ -1258,6 +1391,19 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma return error(GL_INVALID_ENUM); } break; + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT32_OES: + case GL_DEPTH_STENCIL_OES: + case GL_DEPTH24_STENCIL8_OES: + if (context->supportsDepthTextures()) + { + return error(GL_INVALID_OPERATION); + } + else + { + return error(GL_INVALID_ENUM); + } default: return error(GL_INVALID_ENUM); } @@ -1355,23 +1501,31 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL gl::Renderbuffer *source = framebuffer->getColorbuffer(); GLenum colorbufferFormat = source->getInternalFormat(); gl::Texture *texture = NULL; + GLenum textureFormat = GL_RGBA; if (target == GL_TEXTURE_2D) { - texture = context->getTexture2D(); + gl::Texture2D *tex2d = context->getTexture2D(); + + if (!validateSubImageParams2D(false, width, height, xoffset, yoffset, level, GL_NONE, tex2d)) + { + return; // error already registered by validateSubImageParams + } + textureFormat = tex2d->getInternalFormat(level); + texture = tex2d; } else if (gl::IsCubemapTextureTarget(target)) { - texture = context->getTextureCubeMap(); - } - else UNREACHABLE(); + gl::TextureCubeMap *texcube = context->getTextureCubeMap(); - if (!validateSubImageParams(false, width, height, xoffset, yoffset, level, GL_NONE, texture)) - { - return; // error already registered by validateSubImageParams + if (!validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, GL_NONE, texcube)) + { + return; // error already registered by validateSubImageParams + } + textureFormat = texcube->getInternalFormat(target, level); + texture = texcube; } - - GLenum textureFormat = texture->getInternalFormat(); + else UNREACHABLE(); // [OpenGL ES 2.0.24] table 3.9 switch (textureFormat) @@ -1414,6 +1568,9 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: return error(GL_INVALID_OPERATION); + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL_OES: + return error(GL_INVALID_OPERATION); default: return error(GL_INVALID_OPERATION); } @@ -2306,19 +2463,21 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t return error(GL_INVALID_OPERATION); } - if (tex->isCompressed()) - { - return error(GL_INVALID_OPERATION); - } - switch (textarget) { case GL_TEXTURE_2D: - if (tex->getTarget() != GL_TEXTURE_2D) { - return error(GL_INVALID_OPERATION); + if (tex->getTarget() != GL_TEXTURE_2D) + { + return error(GL_INVALID_OPERATION); + } + gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex); + if (tex2d->isCompressed(0)) + { + return error(GL_INVALID_OPERATION); + } + break; } - break; case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: @@ -2326,11 +2485,18 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - if (tex->getTarget() != GL_TEXTURE_CUBE_MAP) { - return error(GL_INVALID_OPERATION); + if (tex->getTarget() != GL_TEXTURE_CUBE_MAP) + { + return error(GL_INVALID_OPERATION); + } + gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex); + if (texcube->isCompressed(textarget, level)) + { + return error(GL_INVALID_OPERATION); + } + break; } - break; default: return error(GL_INVALID_ENUM); @@ -2440,28 +2606,41 @@ void __stdcall glGenerateMipmap(GLenum target) if (context) { - gl::Texture *texture; - switch (target) { case GL_TEXTURE_2D: - texture = context->getTexture2D(); - break; + { + gl::Texture2D *tex2d = context->getTexture2D(); + + if (tex2d->isCompressed(0)) + { + return error(GL_INVALID_OPERATION); + } + if (tex2d->isDepth(0)) + { + return error(GL_INVALID_OPERATION); + } + + tex2d->generateMipmaps(); + break; + } case GL_TEXTURE_CUBE_MAP: - texture = context->getTextureCubeMap(); - break; + { + gl::TextureCubeMap *texcube = context->getTextureCubeMap(); + + if (texcube->isCompressed(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)) + { + return error(GL_INVALID_OPERATION); + } + + texcube->generateMipmaps(); + break; + } default: return error(GL_INVALID_ENUM); } - - if (texture->isCompressed()) - { - return error(GL_INVALID_OPERATION); - } - - texture->generateMipmaps(); } } catch(std::bad_alloc&) @@ -2759,12 +2938,13 @@ int __stdcall glGetAttribLocation(GLuint program, const GLchar* name) } } - if (!programObject->isLinked()) + gl::ProgramBinary *programBinary = programObject->getProgramBinary(); + if (!programBinary) { return error(GL_INVALID_OPERATION, -1); } - return programObject->getAttributeLocation(name); + return programBinary->getAttributeLocation(name); } } catch(std::bad_alloc&) @@ -3218,7 +3398,7 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) *params = programObject->isFlaggedForDeletion(); return; case GL_LINK_STATUS: - *params = programObject->isLinked(); + *params = programObject->getProgramBinary() != NULL; return; case GL_VALIDATE_STATUS: *params = programObject->isValidated(); @@ -3241,6 +3421,9 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) case GL_ACTIVE_UNIFORM_MAX_LENGTH: *params = programObject->getActiveUniformMaxLength(); return; + case GL_PROGRAM_BINARY_LENGTH_OES: + *params = 0; + return; default: return error(GL_INVALID_ENUM); } @@ -3766,12 +3949,18 @@ void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSiz gl::Program *programObject = context->getProgram(program); - if (!programObject || !programObject->isLinked()) + if (!programObject) { return error(GL_INVALID_OPERATION); } - if (!programObject->getUniformfv(location, &bufSize, params)) + gl::ProgramBinary *programBinary = programObject->getProgramBinary(); + if (!programBinary) + { + return error(GL_INVALID_OPERATION); + } + + if (!programBinary->getUniformfv(location, &bufSize, params)) { return error(GL_INVALID_OPERATION); } @@ -3800,12 +3989,18 @@ void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params) gl::Program *programObject = context->getProgram(program); - if (!programObject || !programObject->isLinked()) + if (!programObject) { return error(GL_INVALID_OPERATION); } - if (!programObject->getUniformfv(location, NULL, params)) + gl::ProgramBinary *programBinary = programObject->getProgramBinary(); + if (!programBinary) + { + return error(GL_INVALID_OPERATION); + } + + if (!programBinary->getUniformfv(location, NULL, params)) { return error(GL_INVALID_OPERATION); } @@ -3840,17 +4035,18 @@ void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSiz gl::Program *programObject = context->getProgram(program); - if (!programObject || !programObject->isLinked()) + if (!programObject) { return error(GL_INVALID_OPERATION); } - if (!programObject) + gl::ProgramBinary *programBinary = programObject->getProgramBinary(); + if (!programBinary) { return error(GL_INVALID_OPERATION); } - if (!programObject->getUniformiv(location, &bufSize, params)) + if (!programBinary->getUniformiv(location, &bufSize, params)) { return error(GL_INVALID_OPERATION); } @@ -3879,17 +4075,18 @@ void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params) gl::Program *programObject = context->getProgram(program); - if (!programObject || !programObject->isLinked()) + if (!programObject) { return error(GL_INVALID_OPERATION); } - if (!programObject) + gl::ProgramBinary *programBinary = programObject->getProgramBinary(); + if (!programBinary) { return error(GL_INVALID_OPERATION); } - if (!programObject->getUniformiv(location, NULL, params)) + if (!programBinary->getUniformiv(location, NULL, params)) { return error(GL_INVALID_OPERATION); } @@ -3930,12 +4127,13 @@ int __stdcall glGetUniformLocation(GLuint program, const GLchar* name) } } - if (!programObject->isLinked()) + gl::ProgramBinary *programBinary = programObject->getProgramBinary(); + if (!programBinary) { return error(GL_INVALID_OPERATION, -1); } - return programObject->getUniformLocation(name); + return programBinary->getUniformLocation(name); } } catch(std::bad_alloc&) @@ -5012,6 +5210,26 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL return error(GL_INVALID_OPERATION); } + // validate <type> by itself (used as secondary key below) + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_24_8_OES: + case GL_HALF_FLOAT_OES: + case GL_FLOAT: + break; + default: + return error(GL_INVALID_ENUM); + } + + // validate <format> + <type> combinations + // - invalid <format> -> sets INVALID_ENUM + // - invalid <format>+<type> combination -> sets INVALID_OPERATION switch (format) { case GL_ALPHA: @@ -5024,7 +5242,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL case GL_HALF_FLOAT_OES: break; default: - return error(GL_INVALID_ENUM); + return error(GL_INVALID_OPERATION); } break; case GL_RGB: @@ -5036,7 +5254,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL case GL_HALF_FLOAT_OES: break; default: - return error(GL_INVALID_ENUM); + return error(GL_INVALID_OPERATION); } break; case GL_RGBA: @@ -5049,7 +5267,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL case GL_HALF_FLOAT_OES: break; default: - return error(GL_INVALID_ENUM); + return error(GL_INVALID_OPERATION); } break; case GL_BGRA_EXT: @@ -5058,7 +5276,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL case GL_UNSIGNED_BYTE: break; default: - return error(GL_INVALID_ENUM); + return error(GL_INVALID_OPERATION); } break; case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below @@ -5066,8 +5284,27 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: break; + case GL_DEPTH_COMPONENT: + switch (type) + { + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_INT: + break; + default: + return error(GL_INVALID_OPERATION); + } + break; + case GL_DEPTH_STENCIL_OES: + switch (type) + { + case GL_UNSIGNED_INT_24_8_OES: + break; + default: + return error(GL_INVALID_OPERATION); + } + break; default: - return error(GL_INVALID_VALUE); + return error(GL_INVALID_ENUM); } if (border != 0) @@ -5146,6 +5383,23 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL return error(GL_INVALID_ENUM); } break; + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL_OES: + if (!context->supportsDepthTextures()) + { + return error(GL_INVALID_VALUE); + } + if (target != GL_TEXTURE_2D) + { + return error(GL_INVALID_OPERATION); + } + // OES_depth_texture supports loading depth data and multiple levels, + // but ANGLE_depth_texture does not + if (pixels != NULL || level != 0) + { + return error(GL_INVALID_OPERATION); + } + break; default: break; } @@ -5416,6 +5670,25 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf return error(GL_INVALID_ENUM); } break; + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT32_OES: + case GL_DEPTH24_STENCIL8_OES: + if (!context->supportsDepthTextures()) + { + return error(GL_INVALID_ENUM); + } + if (target != GL_TEXTURE_2D) + { + return error(GL_INVALID_OPERATION); + } + // ANGLE_depth_texture only supports 1-level textures + if (levels != 1) + { + return error(GL_INVALID_OPERATION); + } + break; + default: + break; } if (target == GL_TEXTURE_2D) @@ -5484,14 +5757,9 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint return error(GL_INVALID_VALUE); } - if (!gl::CheckTextureFormatType(format, type)) - { - return error(GL_INVALID_ENUM); - } - - if (width == 0 || height == 0 || pixels == NULL) + if (!checkTextureFormatType(format, type)) { - return; + return; // error is set by helper function } gl::Context *context = gl::getNonLostContext(); @@ -5517,11 +5785,29 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint return error(GL_INVALID_ENUM); } } + else if (gl::IsDepthTexture(format)) + { + if (!context->supportsDepthTextures()) + { + return error(GL_INVALID_ENUM); + } + if (target != GL_TEXTURE_2D) + { + return error(GL_INVALID_OPERATION); + } + // OES_depth_texture supports loading depth data, but ANGLE_depth_texture does not + return error(GL_INVALID_OPERATION); + } + + if (width == 0 || height == 0 || pixels == NULL) + { + return; + } if (target == GL_TEXTURE_2D) { gl::Texture2D *texture = context->getTexture2D(); - if (validateSubImageParams(false, width, height, xoffset, yoffset, level, format, texture)) + if (validateSubImageParams2D(false, width, height, xoffset, yoffset, level, format, texture)) { texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels); } @@ -5529,7 +5815,7 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint else if (gl::IsCubemapTextureTarget(target)) { gl::TextureCubeMap *texture = context->getTextureCubeMap(); - if (validateSubImageParams(false, width, height, xoffset, yoffset, level, format, texture)) + if (validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, format, texture)) { texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels); } @@ -5578,7 +5864,13 @@ void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v) return error(GL_INVALID_OPERATION); } - if (!program->setUniform1fv(location, count, v)) + gl::ProgramBinary *programBinary = program->getProgramBinary(); + if (!programBinary) + { + return error(GL_INVALID_OPERATION); + } + + if (!programBinary->setUniform1fv(location, count, v)) { return error(GL_INVALID_OPERATION); } @@ -5622,7 +5914,13 @@ void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v) return error(GL_INVALID_OPERATION); } - if (!program->setUniform1iv(location, count, v)) + gl::ProgramBinary *programBinary = program->getProgramBinary(); + if (!programBinary) + { + return error(GL_INVALID_OPERATION); + } + + if (!programBinary->setUniform1iv(location, count, v)) { return error(GL_INVALID_OPERATION); } @@ -5668,7 +5966,13 @@ void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v) return error(GL_INVALID_OPERATION); } - if (!program->setUniform2fv(location, count, v)) + gl::ProgramBinary *programBinary = program->getProgramBinary(); + if (!programBinary) + { + return error(GL_INVALID_OPERATION); + } + + if (!programBinary->setUniform2fv(location, count, v)) { return error(GL_INVALID_OPERATION); } @@ -5714,7 +6018,13 @@ void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v) return error(GL_INVALID_OPERATION); } - if (!program->setUniform2iv(location, count, v)) + gl::ProgramBinary *programBinary = program->getProgramBinary(); + if (!programBinary) + { + return error(GL_INVALID_OPERATION); + } + + if (!programBinary->setUniform2iv(location, count, v)) { return error(GL_INVALID_OPERATION); } @@ -5760,7 +6070,13 @@ void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v) return error(GL_INVALID_OPERATION); } - if (!program->setUniform3fv(location, count, v)) + gl::ProgramBinary *programBinary = program->getProgramBinary(); + if (!programBinary) + { + return error(GL_INVALID_OPERATION); + } + + if (!programBinary->setUniform3fv(location, count, v)) { return error(GL_INVALID_OPERATION); } @@ -5806,7 +6122,13 @@ void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v) return error(GL_INVALID_OPERATION); } - if (!program->setUniform3iv(location, count, v)) + gl::ProgramBinary *programBinary = program->getProgramBinary(); + if (!programBinary) + { + return error(GL_INVALID_OPERATION); + } + + if (!programBinary->setUniform3iv(location, count, v)) { return error(GL_INVALID_OPERATION); } @@ -5852,7 +6174,13 @@ void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v) return error(GL_INVALID_OPERATION); } - if (!program->setUniform4fv(location, count, v)) + gl::ProgramBinary *programBinary = program->getProgramBinary(); + if (!programBinary) + { + return error(GL_INVALID_OPERATION); + } + + if (!programBinary->setUniform4fv(location, count, v)) { return error(GL_INVALID_OPERATION); } @@ -5898,7 +6226,13 @@ void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v) return error(GL_INVALID_OPERATION); } - if (!program->setUniform4iv(location, count, v)) + gl::ProgramBinary *programBinary = program->getProgramBinary(); + if (!programBinary) + { + return error(GL_INVALID_OPERATION); + } + + if (!programBinary->setUniform4iv(location, count, v)) { return error(GL_INVALID_OPERATION); } @@ -5938,7 +6272,13 @@ void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean trans return error(GL_INVALID_OPERATION); } - if (!program->setUniformMatrix2fv(location, count, value)) + gl::ProgramBinary *programBinary = program->getProgramBinary(); + if (!programBinary) + { + return error(GL_INVALID_OPERATION); + } + + if (!programBinary->setUniformMatrix2fv(location, count, value)) { return error(GL_INVALID_OPERATION); } @@ -5978,7 +6318,13 @@ void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean trans return error(GL_INVALID_OPERATION); } - if (!program->setUniformMatrix3fv(location, count, value)) + gl::ProgramBinary *programBinary = program->getProgramBinary(); + if (!programBinary) + { + return error(GL_INVALID_OPERATION); + } + + if (!programBinary->setUniformMatrix3fv(location, count, value)) { return error(GL_INVALID_OPERATION); } @@ -6018,7 +6364,13 @@ void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean trans return error(GL_INVALID_OPERATION); } - if (!program->setUniformMatrix4fv(location, count, value)) + gl::ProgramBinary *programBinary = program->getProgramBinary(); + if (!programBinary) + { + return error(GL_INVALID_OPERATION); + } + + if (!programBinary->setUniformMatrix4fv(location, count, value)) { return error(GL_INVALID_OPERATION); } @@ -6054,7 +6406,7 @@ void __stdcall glUseProgram(GLuint program) } } - if (program != 0 && !programObject->isLinked()) + if (program != 0 && !programObject->getProgramBinary()) { return error(GL_INVALID_OPERATION); } @@ -6463,6 +6815,79 @@ void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat } } +void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, + GLenum *binaryFormat, void *binary) +{ + EVENT("(GLenum program = 0x%X, bufSize = %s, length = 0x%0.8p, binaryFormat = 0x%0.8p, binary = 0x%0.8p)", + program, bufSize, length, binaryFormat, binary); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + gl::Program *programObject = context->getProgram(program); + + if (!programObject) + { + return error(GL_INVALID_OPERATION); + } + + gl::ProgramBinary *programBinary = programObject->getProgramBinary(); + + if (!programBinary) + { + return error(GL_INVALID_OPERATION); + } + + *binaryFormat = GL_PROGRAM_BINARY_ANGLE; + + if (length) + { + *length = 0; + } + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat, + const void *binary, GLint length) +{ + EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)", + program, binaryFormat, binary, length); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (binaryFormat != GL_PROGRAM_BINARY_ANGLE) + { + return error(GL_INVALID_ENUM); + } + + gl::Program *programObject = context->getProgram(program); + + if (!programObject) + { + return error(GL_INVALID_OPERATION); + } + + programObject->setProgramBinary(NULL); + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY); + } +} + __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname) { struct Extension @@ -6499,7 +6924,8 @@ __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char * {"glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)glVertexAttribDivisorANGLE}, {"glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawArraysInstancedANGLE}, {"glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawElementsInstancedANGLE}, - }; + {"glGetProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glGetProgramBinaryOES}, + {"glProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glProgramBinaryOES}, }; for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++) { diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.vcproj b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.vcproj index 7d2b649c2..3bc836399 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.vcproj +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.vcproj @@ -401,6 +401,10 @@ > </File> <File + RelativePath=".\ProgramBinary.cpp" + > + </File> + <File RelativePath=".\Query.cpp" > </File> @@ -491,6 +495,10 @@ > </File> <File + RelativePath=".\ProgramBinary.h" + > + </File> + <File RelativePath=".\Query.h" > </File> diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/mathutil.h b/Source/ThirdParty/ANGLE/src/libGLESv2/mathutil.h index 7ca2d9ffd..7bb22500f 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/mathutil.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/mathutil.h @@ -70,26 +70,6 @@ inline unsigned int unorm(float x) } } -inline RECT transformPixelRect(GLint x, GLint y, GLint w, GLint h, GLint surfaceHeight) -{ - RECT rect = {x, - surfaceHeight - y - h, - x + w, - surfaceHeight - y}; - return rect; -} - -inline int transformPixelYOffset(GLint yoffset, GLint h, GLint surfaceHeight) -{ - return surfaceHeight - yoffset - h; -} - -inline GLenum adjustWinding(GLenum winding) -{ - ASSERT(winding == GL_CW || winding == GL_CCW); - return winding == GL_CW ? GL_CCW : GL_CW; -} - inline bool supportsSSE2() { static bool checked = false; diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp index 6589eb121..a7c62d936 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -274,6 +274,17 @@ bool IsCompressed(GLenum format) } } +bool IsDepthTexture(GLenum format) +{ + if (format == GL_DEPTH_COMPONENT || + format == GL_DEPTH_STENCIL_OES) + { + return true; + } + + return false; +} + // Returns the size, in bytes, of a single texel in an Image int ComputePixelSize(GLenum format, GLenum type) { @@ -294,7 +305,11 @@ int ComputePixelSize(GLenum format, GLenum type) case GL_UNSIGNED_SHORT_4_4_4_4: case GL_UNSIGNED_SHORT_5_5_5_1: case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT: return sizeof(unsigned short); + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_24_8_OES: + return sizeof(unsigned int); case GL_FLOAT: switch (format) { @@ -333,53 +348,6 @@ bool IsInternalTextureTarget(GLenum target) return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target); } -// Verify that format/type are one of the combinations from table 3.4. -bool CheckTextureFormatType(GLenum format, GLenum type) -{ - switch (type) - { - case GL_UNSIGNED_BYTE: - switch (format) - { - case GL_RGBA: - case GL_BGRA_EXT: - case GL_RGB: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - return true; - - default: - return false; - } - - case GL_FLOAT: - case GL_HALF_FLOAT_OES: - switch (format) - { - case GL_RGBA: - case GL_RGB: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - return true; - - default: - return false; - } - - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_5_5_5_1: - return (format == GL_RGBA); - - case GL_UNSIGNED_SHORT_5_6_5: - return (format == GL_RGB); - - default: - return false; - } -} - GLenum ExtractFormat(GLenum internalformat) { switch (internalformat) @@ -407,6 +375,9 @@ GLenum ExtractFormat(GLenum internalformat) case GL_LUMINANCE16F_EXT: return GL_LUMINANCE; case GL_LUMINANCE_ALPHA16F_EXT: return GL_LUMINANCE_ALPHA; case GL_BGRA8_EXT: return GL_BGRA_EXT; + case GL_DEPTH_COMPONENT16: return GL_DEPTH_COMPONENT; + case GL_DEPTH_COMPONENT32_OES: return GL_DEPTH_COMPONENT; + case GL_DEPTH24_STENCIL8_OES: return GL_DEPTH_STENCIL_OES; default: return GL_NONE; // Unsupported } } @@ -438,6 +409,9 @@ GLenum ExtractType(GLenum internalformat) case GL_LUMINANCE16F_EXT: return GL_HALF_FLOAT_OES; case GL_LUMINANCE_ALPHA16F_EXT: return GL_HALF_FLOAT_OES; case GL_BGRA8_EXT: return GL_UNSIGNED_BYTE; + case GL_DEPTH_COMPONENT16: return GL_UNSIGNED_SHORT; + case GL_DEPTH_COMPONENT32_OES: return GL_UNSIGNED_INT; + case GL_DEPTH24_STENCIL8_OES: return GL_UNSIGNED_INT_24_8_OES; default: return GL_NONE; // Unsupported } } @@ -638,9 +612,6 @@ D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace) { D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X; - // Map a cube map texture target to the corresponding D3D surface index. Note that the - // Y faces are swapped because the Y coordinate to the texture lookup intrinsic functions - // are negated in the pixel shader. switch (cubeFace) { case GL_TEXTURE_CUBE_MAP_POSITIVE_X: @@ -650,10 +621,10 @@ D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace) face = D3DCUBEMAP_FACE_NEGATIVE_X; break; case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - face = D3DCUBEMAP_FACE_NEGATIVE_Y; + face = D3DCUBEMAP_FACE_POSITIVE_Y; break; case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - face = D3DCUBEMAP_FACE_POSITIVE_Y; + face = D3DCUBEMAP_FACE_NEGATIVE_Y; break; case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: face = D3DCUBEMAP_FACE_POSITIVE_Z; @@ -767,6 +738,7 @@ D3DFORMAT ConvertRenderbufferFormat(GLenum format) { switch (format) { + case GL_NONE: return D3DFMT_NULL; case GL_RGBA4: case GL_RGB5_A1: case GL_RGBA8_OES: return D3DFMT_A8R8G8B8; @@ -794,6 +766,10 @@ namespace dx2es unsigned int GetStencilSize(D3DFORMAT stencilFormat) { + if (stencilFormat == D3DFMT_INTZ) + { + return 8; + } switch(stencilFormat) { case D3DFMT_D24FS8: @@ -904,6 +880,10 @@ unsigned int GetBlueSize(D3DFORMAT colorFormat) unsigned int GetDepthSize(D3DFORMAT depthFormat) { + if (depthFormat == D3DFMT_INTZ) + { + return 24; + } switch (depthFormat) { case D3DFMT_D16_LOCKABLE: return 16; @@ -965,6 +945,16 @@ bool IsFloat16Format(D3DFORMAT surfaceFormat) return false; } +bool IsDepthTextureFormat(D3DFORMAT surfaceFormat) +{ + return (surfaceFormat == D3DFMT_INTZ); +} + +bool IsStencilTextureFormat(D3DFORMAT surfaceFormat) +{ + return (surfaceFormat == D3DFMT_INTZ); +} + GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type) { if (type == D3DMULTISAMPLE_NONMASKABLE) @@ -991,6 +981,10 @@ GLenum ConvertBackBufferFormat(D3DFORMAT format) GLenum ConvertDepthStencilFormat(D3DFORMAT format) { + if (format == D3DFMT_INTZ) + { + return GL_DEPTH24_STENCIL8_OES; + } switch (format) { case D3DFMT_D16: diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.h b/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.h index 88238dcb1..cf2241837 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -16,6 +16,9 @@ #include <string> +const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z'))); +const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N','U','L','L'))); + namespace gl { @@ -36,9 +39,9 @@ GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment) GLsizei ComputeCompressedPitch(GLsizei width, GLenum format); GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format); bool IsCompressed(GLenum format); +bool IsDepthTexture(GLenum format); bool IsCubemapTextureTarget(GLenum target); bool IsInternalTextureTarget(GLenum target); -bool CheckTextureFormatType(GLenum format, GLenum type); GLenum ExtractFormat(GLenum internalformat); GLenum ExtractType(GLenum internalformat); @@ -79,6 +82,8 @@ GLuint GetDepthSize(D3DFORMAT depthFormat); GLuint GetStencilSize(D3DFORMAT stencilFormat); bool IsFloat32Format(D3DFORMAT surfaceFormat); bool IsFloat16Format(D3DFORMAT surfaceFormat); +bool IsDepthTextureFormat(D3DFORMAT surfaceFormat); +bool IsStencilTextureFormat(D3DFORMAT surfaceFormat); GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type); diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog index f73f5142b..c94173fed 100644 --- a/Source/WTF/ChangeLog +++ b/Source/WTF/ChangeLog @@ -1,3 +1,63 @@ +2012-07-17 Gabor Ballabas <gaborb@inf.u-szeged.hu> + + [Qt][V8] Remove the V8 related codepaths and configuration + https://bugs.webkit.org/show_bug.cgi?id=90863 + + Reviewed by Simon Hausmann. + + * WTF.pri: + +2012-07-17 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r122834. + http://trac.webkit.org/changeset/122834 + https://bugs.webkit.org/show_bug.cgi?id=91492 + + it broke the chromium (Requested by kkristof on #webkit). + + * WTF.pri: + +2012-07-17 Gabor Ballabas <gaborb@inf.u-szeged.hu> + + [Qt][V8] Remove the V8 related codepaths and configuration + https://bugs.webkit.org/show_bug.cgi?id=90863 + + Reviewed by Simon Hausmann. + + * WTF.pri: + +2012-07-16 Hajime Morrita <morrita@chromium.org> + + WebCore needs WEBCORE_TESTING macro to mark methods being exported for testing. + https://bugs.webkit.org/show_bug.cgi?id=90764 + + Reviewed by Adam Barth. + + Added USE(EXPORT_MACROS_FOR_TESTING) and enabled it on GTK and Windows. + + * wtf/ExportMacros.h: + * wtf/Platform.h: + +2012-07-16 Filip Pizlo <fpizlo@apple.com> + + Unreviewed build fix. + + * wtf/FastMalloc.cpp: + (WTF::TCMalloc_ThreadCache::CreateCacheIfNecessary): + +2012-07-16 Adam Treat <atreat@rim.com> + + [BlackBerry] Use newer version of platform API to implement callOnMainThread + https://bugs.webkit.org/show_bug.cgi?id=91404 + + Reviewed by Yong Li. + + Right now we're using an outdated API that involves a virtual function call for no reason. + Use the new API that is much more direct and to the point. + + * wtf/blackberry/MainThreadBlackBerry.cpp: + (WTF::scheduleDispatchFunctionsOnMainThread): + 2012-07-14 Filip Pizlo <fpizlo@apple.com> Unreviewed, build fix. diff --git a/Source/WTF/WTF.pri b/Source/WTF/WTF.pri index 306a18012..024c7f69f 100644 --- a/Source/WTF/WTF.pri +++ b/Source/WTF/WTF.pri @@ -24,13 +24,6 @@ haveQt(5) { } } -v8 { - !haveQt(5): error("To build QtWebKit+V8 you need to use Qt 5") - DEFINES *= WTF_USE_V8=1 - INCLUDEPATH += $${ROOT_WEBKIT_DIR}/Source/WebKit/qt/v8/ForwardingHeaders - QT += v8-private -} - linux-*:contains(DEFINES, WTF_USE_GSTREAMER=1) { DEFINES += ENABLE_GLIB_SUPPORT=1 PKGCONFIG += glib-2.0 gio-2.0 diff --git a/Source/WTF/wtf/ExportMacros.h b/Source/WTF/wtf/ExportMacros.h index 20732b2a6..e784247c4 100644 --- a/Source/WTF/wtf/ExportMacros.h +++ b/Source/WTF/wtf/ExportMacros.h @@ -48,26 +48,40 @@ #define WTF_INTERNAL #endif -// See note in wtf/Platform.h for more info on EXPORT_MACROS. -#if USE(EXPORT_MACROS) - #if !PLATFORM(CHROMIUM) && OS(WINDOWS) -#define WTF_EXPORT __declspec(dllexport) -#define WTF_IMPORT __declspec(dllimport) -#define WTF_HIDDEN + +#define WTF_EXPORT_DECLARATION __declspec(dllexport) +#define WTF_IMPORT_DECLARATION __declspec(dllimport) +#define WTF_HIDDEN_DECLARATION + #elif defined(__GNUC__) && !defined(__CC_ARM) && !defined(__ARMCC__) -#define WTF_EXPORT __attribute__((visibility("default"))) -#define WTF_IMPORT WTF_EXPORT -#define WTF_HIDDEN __attribute__((visibility("hidden"))) + +#define WTF_EXPORT_DECLARATION __attribute__((visibility("default"))) +#define WTF_IMPORT_DECLARATION WTF_EXPORT_DECLARATION +#define WTF_HIDDEN_DECLARATION __attribute__((visibility("hidden"))) + #else -#define WTF_EXPORT -#define WTF_IMPORT -#define WTF_HIDDEN + +#define WTF_EXPORT_DECLARATION +#define WTF_IMPORT_DECLARATION +#define WTF_HIDDEN_DECLARATION + #endif +#if defined(BUILDING_WTF) || defined(STATICALLY_LINKED_WITH_WTF) || (PLATFORM(WX) && defined(BUILDING_JavaScriptCore)) +#define WTF_IS_LINKED_IN_SAME_BINARY 1 +#endif + +// See note in wtf/Platform.h for more info on EXPORT_MACROS. +#if USE(EXPORT_MACROS) + +#define WTF_EXPORT WTF_EXPORT_DECLARATION +#define WTF_IMPORT WTF_IMPORT_DECLARATION +#define WTF_HIDDEN WTF_IMPORT_DECLARATION + // FIXME: When all ports are using the export macros, we should replace // WTF_EXPORTDATA with WTF_EXPORT_PRIVATE macros. -#if defined(BUILDING_WTF) || defined(STATICALLY_LINKED_WITH_WTF) || (PLATFORM(WX) && defined(BUILDING_JavaScriptCore)) +#if defined(WTF_IS_LINKED_IN_SAME_BINARY) #define WTF_EXPORTDATA WTF_EXPORT #else #define WTF_EXPORTDATA WTF_IMPORT @@ -93,7 +107,25 @@ #endif // USE(EXPORT_MACROS) -#if defined(BUILDING_WTF) || defined(STATICALLY_LINKED_WITH_WTF) || (PLATFORM(WX) && defined(BUILDING_JavaScriptCore)) +// WTF_TESTING (and WEBCORE_TESTING in PlatformExportMacros.h) is used for +// exporting symbols which are referred from WebCoreTestSupport library. +// Since the set of APIs is common between ports, +// it is rather worth annotating inside the code than maintaining port specific export lists. +#if USE(EXPORT_MACROS_FOR_TESTING) + +#if defined(WTF_IS_LINKED_IN_SAME_BINARY) +#define WTF_TESTING WTF_EXPORT_DECLARATION +#else +#define WTF_TESTING WTF_IMPORT_DECLARATION +#endif + +#else // USE(EXPORT_MACROS_FOR_TESTING) + +#define WTF_TESTING + +#endif // USE(EXPORT_MACROS_FOR_TESTING) + +#if defined(WTF_IS_LINKED_IN_SAME_BINARY) #define WTF_EXPORT_PRIVATE WTF_EXPORT #else #define WTF_EXPORT_PRIVATE WTF_IMPORT diff --git a/Source/WTF/wtf/FastMalloc.cpp b/Source/WTF/wtf/FastMalloc.cpp index 0083f18d6..dddfcc699 100644 --- a/Source/WTF/wtf/FastMalloc.cpp +++ b/Source/WTF/wtf/FastMalloc.cpp @@ -4654,10 +4654,10 @@ extern "C" { malloc_introspection_t jscore_fastmalloc_introspection = { &FastMallocZone::enumerate, &FastMallocZone::goodSize, &FastMallocZone::check, &FastMallocZone::print, &FastMallocZone::log, &FastMallocZone::forceLock, &FastMallocZone::forceUnlock, &FastMallocZone::statistics -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 || OS(IOS) +#if OS(IOS) || __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 , 0 // zone_locked will not be called on the zone unless it advertises itself as version five or higher. #endif -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 || OS(IOS) +#if OS(IOS) || __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 , 0, 0, 0, 0 // These members will not be used unless the zone advertises itself as version seven or higher. #endif diff --git a/Source/WTF/wtf/Platform.h b/Source/WTF/wtf/Platform.h index fbf881a5e..c17f3e1bc 100644 --- a/Source/WTF/wtf/Platform.h +++ b/Source/WTF/wtf/Platform.h @@ -1082,6 +1082,10 @@ #define WTF_USE_EXPORT_MACROS 1 #endif +#if !defined(WTF_USE_EXPORT_MACROS_FOR_TESTING) && (PLATFORM(GTK) || PLATFORM(WIN)) +#define WTF_USE_EXPORT_MACROS_FOR_TESTING 1 +#endif + #if (PLATFORM(QT) && !OS(DARWIN)) || PLATFORM(GTK) || PLATFORM(EFL) #define WTF_USE_UNIX_DOMAIN_SOCKETS 1 #endif diff --git a/Source/WTF/wtf/ThreadSpecific.h b/Source/WTF/wtf/ThreadSpecific.h index 60c9907bd..f51ab4cf2 100644 --- a/Source/WTF/wtf/ThreadSpecific.h +++ b/Source/WTF/wtf/ThreadSpecific.h @@ -1,7 +1,6 @@ /* * Copyright (C) 2008 Apple Inc. All rights reserved. * Copyright (C) 2009 Jian Li <jianli@chromium.org> - * Copyright (C) 2012 Patrick Gansterer <paroga@paroga.com> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -103,33 +102,6 @@ private: }; #if USE(PTHREADS) - -typedef pthread_key_t ThreadSpecificKey; - -inline void ThreadSpecificKeyCreate(ThreadSpecificKey* key, void (*destructor)(void *)) -{ - int error = pthread_key_create(key, destructor); - if (error) - CRASH(); -} - -inline void ThreadSpecificKeyDelete(ThreadSpecificKey key) -{ - int error = pthread_key_delete(key); - if (error) - CRASH(); -} - -inline void ThreadSpecificSet(ThreadSpecificKey key, void* value) -{ - pthread_setspecific(key, value); -} - -inline void* ThreadSpecificGet(ThreadSpecificKey key) -{ - return pthread_getspecific(key); -} - template<typename T> inline ThreadSpecific<T>::ThreadSpecific() { @@ -167,14 +139,6 @@ const int kMaxTlsKeySize = 256; WTF_EXPORT_PRIVATE long& tlsKeyCount(); WTF_EXPORT_PRIVATE DWORD* tlsKeys(); -class ThreadSpecificKeyValue; -typedef ThreadSpecificKeyValue* ThreadSpecificKey; - -void ThreadSpecificKeyCreate(ThreadSpecificKey*, void (*)(void *)); -void ThreadSpecificKeyDelete(ThreadSpecificKey); -void ThreadSpecificSet(ThreadSpecificKey, void*); -void* ThreadSpecificGet(ThreadSpecificKey); - template<typename T> inline ThreadSpecific<T>::ThreadSpecific() : m_index(-1) diff --git a/Source/WTF/wtf/ThreadSpecificWin.cpp b/Source/WTF/wtf/ThreadSpecificWin.cpp index 61a594251..d72996a7a 100644 --- a/Source/WTF/wtf/ThreadSpecificWin.cpp +++ b/Source/WTF/wtf/ThreadSpecificWin.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2009 Jian Li <jianli@chromium.org> - * Copyright (C) 2012 Patrick Gansterer <paroga@paroga.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -20,72 +19,15 @@ */ #include "config.h" -#include "ThreadSpecific.h" -#include "StdLibExtras.h" -#include "ThreadingPrimitives.h" +#include "ThreadSpecific.h" -#if !USE(PTHREADS) +#if USE(PTHREADS) +#error This file should not be compiled by ports that do not use Windows native ThreadSpecific implementation. +#endif namespace WTF { -static Mutex& destructorsMutex() -{ - DEFINE_STATIC_LOCAL(Mutex, staticMutex, ()); - return staticMutex; -} - -class ThreadSpecificKeyValue { -public: - ThreadSpecificKeyValue(void (*destructor)(void *)) - : m_destructor(destructor) - { - m_tlsKey = TlsAlloc(); - if (m_tlsKey == TLS_OUT_OF_INDEXES) - CRASH(); - - MutexLocker locker(destructorsMutex()); - m_next = m_first; - m_first = this; - } - - ~ThreadSpecificKeyValue() - { - MutexLocker locker(destructorsMutex()); - ThreadSpecificKeyValue** next = &m_first; - while (*next != this) { - ASSERT(*next); - next = &(*next)->m_next; - } - *next = (*next)->m_next; - - TlsFree(m_tlsKey); - } - - void setValue(void* data) { TlsSetValue(m_tlsKey, data); } - void* value() { return TlsGetValue(m_tlsKey); } - - static void callDestructors() - { - MutexLocker locker(destructorsMutex()); - ThreadSpecificKeyValue* next = m_first; - while (next) { - if (void* data = next->value()) - next->m_destructor(data); - next = next->m_next; - } - } - -private: - void (*m_destructor)(void *); - DWORD m_tlsKey; - ThreadSpecificKeyValue* m_next; - - static ThreadSpecificKeyValue* m_first; -}; - -ThreadSpecificKeyValue* ThreadSpecificKeyValue::m_first = 0; - long& tlsKeyCount() { static long count; @@ -98,26 +40,6 @@ DWORD* tlsKeys() return keys; } -void ThreadSpecificKeyCreate(ThreadSpecificKey* key, void (*destructor)(void *)) -{ - *key = new ThreadSpecificKeyValue(destructor); -} - -void ThreadSpecificKeyDelete(ThreadSpecificKey key) -{ - delete key; -} - -void ThreadSpecificSet(ThreadSpecificKey key, void* data) -{ - key->setValue(data); -} - -void* ThreadSpecificGet(ThreadSpecificKey key) -{ - return key->value(); -} - void ThreadSpecificThreadExit() { for (long i = 0; i < tlsKeyCount(); i++) { @@ -126,10 +48,6 @@ void ThreadSpecificThreadExit() if (data) data->destructor(data); } - - ThreadSpecificKeyValue::callDestructors(); } } // namespace WTF - -#endif // !USE(PTHREADS) diff --git a/Source/WTF/wtf/blackberry/MainThreadBlackBerry.cpp b/Source/WTF/wtf/blackberry/MainThreadBlackBerry.cpp index 7284f4b44..ec7a364dd 100644 --- a/Source/WTF/wtf/blackberry/MainThreadBlackBerry.cpp +++ b/Source/WTF/wtf/blackberry/MainThreadBlackBerry.cpp @@ -19,7 +19,8 @@ #include "config.h" #include "MainThread.h" -#include <BlackBerryPlatformClient.h> +#include <BlackBerryPlatformExecutableMessage.h> +#include <BlackBerryPlatformMessageClient.h> namespace WTF { @@ -29,7 +30,7 @@ void initializeMainThreadPlatform() void scheduleDispatchFunctionsOnMainThread() { - BlackBerry::Platform::Client::get()->scheduleCallOnMainThread(dispatchFunctionsFromMainThread); + BlackBerry::Platform::webKitThreadMessageClient()->dispatchMessage(BlackBerry::Platform::createFunctionCallMessage(dispatchFunctionsFromMainThread)); } } // namespace WTF diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt index 603ce2196..953676684 100644 --- a/Source/WebCore/CMakeLists.txt +++ b/Source/WebCore/CMakeLists.txt @@ -547,6 +547,7 @@ SET(WebCore_SOURCES css/WebKitCSSRegionRule.cpp css/WebKitCSSSVGDocumentValue.cpp css/WebKitCSSTransformValue.cpp + css/WrapShapeFunctions.cpp dom/ActiveDOMObject.cpp dom/Attr.cpp @@ -929,6 +930,7 @@ SET(WebCore_SOURCES html/shadow/DetailsMarkerControl.cpp html/shadow/HTMLContentElement.cpp html/shadow/HTMLShadowElement.cpp + html/shadow/ImageInnerElement.cpp html/shadow/InsertionPoint.cpp html/shadow/MediaControls.cpp html/shadow/MediaControlRootElement.cpp @@ -2324,7 +2326,20 @@ IF (ENABLE_WEBGL) ${THIRDPARTY_DIR}/ANGLE/src/compiler/BuiltInFunctionEmulator.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/CodeGenGLSL.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/Compiler.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/Diagnostics.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/Diagnostics.h + ${THIRDPARTY_DIR}/ANGLE/src/compiler/DirectiveHandler.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/DirectiveHandler.h ${THIRDPARTY_DIR}/ANGLE/src/compiler/debug.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/depgraph/DependencyGraph.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/depgraph/DependencyGraph.h + ${THIRDPARTY_DIR}/ANGLE/src/compiler/depgraph/DependencyGraphBuilder.h + ${THIRDPARTY_DIR}/ANGLE/src/compiler/depgraph/DependencyGraphBuilder.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/depgraph/DependencyGraphOutput.h + ${THIRDPARTY_DIR}/ANGLE/src/compiler/depgraph/DependencyGraphOutput.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/depgraph/DependencyGraphTraverse.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/DetectDiscontinuity.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/DetectDiscontinuity.h ${THIRDPARTY_DIR}/ANGLE/src/compiler/DetectRecursion.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/ForLoopUnroll.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/glslang_lex.cpp @@ -2332,6 +2347,7 @@ IF (ENABLE_WEBGL) ${THIRDPARTY_DIR}/ANGLE/src/compiler/InfoSink.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/Initialize.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/InitializeDll.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/InitializeParseContext.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/Intermediate.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/intermOut.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/IntermTraverse.cpp @@ -2344,22 +2360,52 @@ IF (ENABLE_WEBGL) ${THIRDPARTY_DIR}/ANGLE/src/compiler/parseConst.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/ParseHelper.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/PoolAlloc.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/Pragma.h ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/atom.c ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/cpp.c ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/cppstruct.c ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/memory.c + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/DiagnosticsBase.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/Diagnostics.h + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/DirectiveHandlerBase.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/DirectiveHandler.h + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/DirectiveParser.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/DirectiveParser.h + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/ExpressionParser.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/ExpressionParser.h + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/Input.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/Input.h + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/Lexer.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/Lexer.h + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/Macro.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/Macro.h + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/MacroExpander.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/MacroExpander.h + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/Preprocessor.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/Preprocessor.h + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/SourceLocation.h + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/Token.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/Token.h + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/Tokenizer.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/new/Tokenizer.h ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/scanner.c ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/symbols.c ${THIRDPARTY_DIR}/ANGLE/src/compiler/preprocessor/tokens.c ${THIRDPARTY_DIR}/ANGLE/src/compiler/QualifierAlive.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/RemoveTree.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/RenameFunction.h ${THIRDPARTY_DIR}/ANGLE/src/compiler/SearchSymbol.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/ShaderLang.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/SymbolTable.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/timing/RestrictFragmentShaderTiming.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/timing/RestrictFragmentShaderTiming.h + ${THIRDPARTY_DIR}/ANGLE/src/compiler/timing/RestrictVertexShaderTiming.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/timing/RestrictVertexShaderTiming.h ${THIRDPARTY_DIR}/ANGLE/src/compiler/TranslatorESSL.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/TranslatorGLSL.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/TranslatorHLSL.cpp - ${THIRDPARTY_DIR}/ANGLE/src/compiler/UnfoldSelect.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/UnfoldShortCircuit.cpp + ${THIRDPARTY_DIR}/ANGLE/src/compiler/UnfoldShortCircuit.h ${THIRDPARTY_DIR}/ANGLE/src/compiler/util.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/ValidateLimitations.cpp ${THIRDPARTY_DIR}/ANGLE/src/compiler/VariableInfo.cpp diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 3bf650a22..59922b16e 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,2945 @@ +2012-07-18 Simon Hausmann <simon.hausmann@nokia.com> + + [ANGLE] On QT, use Bison and Flex during ANGLE build + https://bugs.webkit.org/show_bug.cgi?id=91108 + + Reviewed by Kenneth Rohde Christiansen. + + Add derived source generators for the two angle bison parsers and flex based lexers. + + * DerivedSources.pri: + * Target.pri: + +2012-07-18 Dominik Röttsches <dominik.rottsches@intel.com> + + [EFL][WK2] Too early assertion failure if default theme is not available + https://bugs.webkit.org/show_bug.cgi?id=91608 + + Reviewed by Kenneth Rohde Christiansen. + + After bug 90107 we're setting a default theme path, which leads to a + themeChanged() call initializing edje in createEdje() - if that theme + path is not available we run into a premature assertion failure. + We need to give the embedder a chance to override the default theme path + before failing - so only the usages of m_edje should be guarded with assertions. + + No new tests, no change in rendering behavior. + + * platform/efl/RenderThemeEfl.cpp: + (WebCore::RenderThemeEfl::themePartCacheEntryReset): Adding an assertion to ensure m_edje is present - so that all usages of m_edje are now guarded. + (WebCore::RenderThemeEfl::createEdje): Not hitting assertion if theme path doesn't contain the theme object file, allowing the embedder to override with a new path. + +2012-07-18 Vsevolod Vlasov <vsevik@chromium.org> + + IndexedDB: IDBLevelDBBackingStore compilation fails because of unused variable. + https://bugs.webkit.org/show_bug.cgi?id=91612 + + Reviewed by Pavel Feldman. + + Replaced ASSERT with ASSERT_UNUSED. + + * Modules/indexeddb/IDBLevelDBBackingStore.cpp: + (WebCore::IDBLevelDBBackingStore::getObjectStores): + +2012-07-18 Yoshifumi Inoue <yosin@chromium.org> + + REGRESSION(r117738) [Forms] Default step base should be 0 (=1970-01) for input type month + https://bugs.webkit.org/show_bug.cgi?id=91603 + + Reviewed by Kent Tamura. + + This patch restores default step base value to 0 (=1970-01) as before + r117738. + + No new tests. Existing test(fast/forms/month/month-stepup-stepdown-from-renderer.html) + covers this case, although it is disabled. + + * html/MonthInputType.cpp: + (WebCore::MonthInputType::createStepRange): Changed default value of + step base to defaultMonthStepBase instead of DateComponents::minimumMonth(). + +2012-07-18 Ryuan Choi <ryuan.choi@samsung.com> + + [EFL] Cursor is not drawn when opengl_x11 backend is choosen. + https://bugs.webkit.org/show_bug.cgi?id=89142 + + Reviewed by Simon Hausmann. + + If theme based cursor is not given, WebKit/Efl only uses Ecore_X based + cursor as a fallback after checked whether current engine is using EcoreX. + This patch adds opengl_x11 which is one of Ecore_X based engine in check + lists to draw fallback cursor. + + * platform/efl/EflScreenUtilities.cpp: + (WebCore::isUsingEcoreX): + +2012-07-18 Ryosuke Niwa <rniwa@webkit.org> + + REGRESSION(r122345): HTMLCollection::length() sometimes returns a wrong value + https://bugs.webkit.org/show_bug.cgi?id=91587 + + Reviewed by Benjamin Poulain. + + The bug was caused by my douchey code that set the length cache to be the *offset* + of the last item in a HTMLCollection. Clearly, the length of a collection that contains + the last item at offset n is n + 1. Fixed that. + + Also removed the call to setLengthCache in HTMLCollection::length since it must have set + by previous calls to itemBeforeOrAfterCachedItem already. This will allow us to catch + regressions like this in ports that use JSC bindings as well. + + Test: fast/dom/htmlcollection-length-after-item.html + + * html/HTMLCollection.cpp: + (WebCore::HTMLCollection::length): + (WebCore::HTMLCollection::itemBeforeOrAfterCachedItem): + +2012-07-18 Yoshifumi Inoue <yosin@chromium.org> + + Decimal::toString should not round integer value. + https://bugs.webkit.org/show_bug.cgi?id=91481 + + Reviewed by Kent Tamura. + + This patch makes Decimal::toString not to round an integer value + before converting string. + + Tests: WebKit/chromium/tests/DecimalTest.cpp: DecimalTest.toString + + * platform/Decimal.cpp: + (WebCore::Decimal::toString): When the value is an integer, we don't + round coefficient to be DBL_DIG(15) digits because double can + represent an integer without rounding error. + +2012-07-18 Luke Macpherson <macpherson@chromium.org> + + Fix null pointer dereference introduced by Changeset 121874. + https://bugs.webkit.org/show_bug.cgi?id=91578 + + Reviewed by Pavel Feldman. + + In http://trac.webkit.org/changeset/121874/trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp I introduced code that + dereferences the return value of ownerDocument() without doing a null check. This was a bad idea. + + No new tests. I don't have a repro case, but it is clear from reading the code for ownerDocument() that it can return null. + + * inspector/InspectorStyleSheet.cpp: + (WebCore::InspectorStyleSheet::ensureSourceData): + +2012-07-17 Yoshifumi Inoue <yosin@chromium.org> + + Decimal constructor with 99999999999999999 loses last digit + https://bugs.webkit.org/show_bug.cgi?id=91579 + + Reviewed by Kent Tamura. + + This patch changes maximum coefficient value handling in Decimal::EncodedData + constructor not to lose the last digit. It was used ">=" operator for + comparison instead of ">" operator. + + Tests: WebKit/chromium/tests/DecimalTest.cpp + + * platform/Decimal.cpp: + (WebCore::Decimal::EncodedData::EncodedData): Replace ">=" to ">" for + not getting rid of the last digit for maximum coefficient value. + +2012-07-17 Ilya Tikhonovsky <loislo@chromium.org> + + Unreviewed Web Inspector: followup fix for r122920. + + Add collected Loaders size to InspectorMemoryBlock + + * inspector/InspectorMemoryAgent.cpp: + (MemoryBlockName): + (WebCore): + +2012-07-17 Ilya Tikhonovsky <loislo@chromium.org> + + Web Inspector: show loaders memory consumption on the memory chart. + https://bugs.webkit.org/show_bug.cgi?id=90686 + + Reviewed by Pavel Feldman. + + Size of FrameLoader, DocumentLoader, ResourceLoader and their resources should be shown on the memory pie chart. + + It is covered by existing WebInspector performance tests infrastructure. + + * WebCore.exp.in: + * dom/MemoryInstrumentation.h: + (MemoryInstrumentation): + (WebCore::MemoryInstrumentation::addRawBuffer): + (WebCore::MemoryInstrumentation::addInstrumentedMemberImpl): + (WebCore): + (WebCore::MemoryClassInfo::addInstrumentedHashSet): + (WebCore::MemoryClassInfo::addRawBuffer): + (WebCore::MemoryInstrumentation::addInstrumentedHashSet): + (WebCore::MemoryInstrumentation::addVector): + * inspector/InspectorMemoryAgent.cpp: + (WebCore): + (WebCore::domTreeInfo): + * loader/DocumentLoader.cpp: + (WebCore::DocumentLoader::reportMemoryUsage): + (WebCore): + * loader/DocumentLoader.h: + (WebCore): + (DocumentLoader): + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::reportMemoryUsage): + (WebCore): + * loader/FrameLoader.h: + (WebCore): + (FrameLoader): + * loader/ResourceLoader.cpp: + (WebCore::ResourceLoader::reportMemoryUsage): + (WebCore): + * loader/ResourceLoader.h: + (WebCore): + (ResourceLoader): + * page/Frame.cpp: + (WebCore::Frame::reportMemoryUsage): + (WebCore): + * page/Frame.h: + (WebCore): + (Frame): + * platform/SharedBuffer.cpp: + (WebCore::SharedBuffer::reportMemoryUsage): + (WebCore): + * platform/SharedBuffer.h: + (WebCore): + (SharedBuffer): + +2012-07-17 Kent Tamura <tkent@chromium.org> + + Fix an assertion failure in CalendarPickerElement::hostInput(). + https://bugs.webkit.org/show_bug.cgi?id=91568 + + Reviewed by Hajime Morita. + + Test: fast/forms/date/calendar-picker-type-change-onclick.html + + * html/shadow/CalendarPickerElement.cpp: + (WebCore::CalendarPickerElement::defaultEventHandler): + It's possible that this function is called when the element is detached + from the document tree. + +2012-07-17 Kent Tamura <tkent@chromium.org> + + Form state: Make a new class handling HashMap<FormElementKey, Deque<>> + https://bugs.webkit.org/show_bug.cgi?id=91480 + + Reviewed by Hajime Morita. + + This is a preparation of Bug 91209, "Form state restore: Need to + identify a from by its content." + + Make a new class which is responsible to handle "HashMap<FormElementKey, + Deque<FormControlState>, FormElementKeyHash, FormElementKeyHashTraits>." + Also, move the FormElementKey class declaration and related structs from + FormController.h to FormController.cpp because FormElementKey is used + only in FormController.cpp. + + No new tests. Just a refactoring. + + * html/FormController.cpp: + (WebCore::FormElementKey): Moeved from FormController.h. + (WebCore::FormElementKey::FormElementKey): + Moved from the bottom of FormController.cpp + (WebCore::FormElementKey::~FormElementKey): ditto. + (WebCore::FormElementKey::operator=): ditto. + (WebCore::FormElementKey::ref): ditto. + (WebCore::FormElementKey::deref): ditto. + (WebCore::operator==): Moved from FormController.h + (FormElementKeyHash): ditto. + (WebCore::FormElementKeyHash::equal): ditto. + (WebCore::FormElementKeyHash::hash): + Moved from the bottom of FormController.cpp + (WebCore::FormElementKeyHashTraits::constructDeletedValue): + Moved from FormController.h + (WebCore::FormElementKeyHashTraits::isDeletedValue): ditto. + + (WebCore::SavedFormState): Added. + (WebCore::SavedFormState::isEmpty): + (WebCore::SavedFormState::SavedFormState): Added. The constructor. + (WebCore::SavedFormState::create): Added. A factory function. + (WebCore::SavedFormState::appendControlState): + Moved some code from FormController::setStateForNewFormElements. + (WebCore::SavedFormState::takeControlState): + Moved some code from FormController::takeStateForFormElement. + + (WebCore::FormController::setStateForNewFormElements): + - Creates SavedFormState if needed. + - Uses SavedFormState::appendControlState. + (WebCore::FormController::takeStateForFormElement): + Uses SavedFormState. + * html/FormController.h: + (FormController): + +2012-07-17 MORITA Hajime <morrita@google.com> + + [Shadow DOM] Some distribution invalidation can drop necessary reattachment. + https://bugs.webkit.org/show_bug.cgi?id=88843 + + Reviewed by Dimitri Glazkov. + + Following scenario caused this problem: + + - Inserting a Text node as a shadow child triggers invalidateDistribution(), + which doen't reattach the shadow's host element. + - Then inserting a <content> element after that triggers another invalidateDistribution(), + which should reattach its host because <content> can affect not only distribution of new nodes, + but also existing distribution. + - Since the first invalidateDistribution() has marked the distribution as invalidated, + the second invalidateDistribution() call returns early without any reattachment, + even though it needs one. + + This change adds InvalidationType parameter to invalidateDistribution(), which asks ElementShadow to + reattach the host regardless of its validity state. InsertionPoint::insertedInto() uses + this flag to ensure that its insertion always results a reattachment. + + Test: fast/dom/shadow/content-after-style.html + + * dom/ElementShadow.cpp: + (WebCore::ElementShadow::addShadowRoot): Passes InvalidationType. + (WebCore::ElementShadow::removeAllShadowRoots): Passes InvalidationType. + (WebCore::ElementShadow::invalidateDistribution): Added a InvalidationType parameter. + * dom/ElementShadow.h: + * html/shadow/InsertionPoint.cpp: + (WebCore::InsertionPoint::insertedInto): Passes InvalidationType. + +2012-07-17 Jon Lee <jonlee@apple.com> + + Teach CodeGenerator to support for static, readonly, attributes + https://bugs.webkit.org/show_bug.cgi?id=88920 + <rdar://problem/11650330> + + Reviewed by Oliver Hunt. + + Update the parser to be able to accept the static keyword for attribute. We will treat static attributes + like custom static functions. They call the implementing class directly, and pass in the ExecState as a script context. + + * bindings/scripts/CodeGeneratorJS.pm: + (GetAttributeGetterName): Factor out the construction of the attribute getter function name. + (GetAttributeSetterName): Factor out the construction of the attribute setter function name. + (GenerateHeader): Determine that a class has read-write properties only if there is a read-write attribute that + is not static. + (GenerateAttributesHashTable): Skip static attributes in the object hash table. They will be added to the constructor + hash table. + (GenerateImplementation): Look for static attributes to add to the constructor hash table. Make a call to the static + function in the class. + * bindings/scripts/IDLParser.pm: + (ParseInterface): Update the processing because of the regex change. + * bindings/scripts/IDLStructure.pm: Update the attribute regex. + * bindings/scripts/test/JS/JSTestObj.cpp: Update test results. + * bindings/scripts/test/JS/JSTestObj.h: Update test results. + * bindings/scripts/test/TestObj.idl: Add test cases. + +2012-07-17 Kenichi Ishibashi <bashi@chromium.org> + + [Chromium] Rename HarfBuzzFace to HarfBuzzNGFace + https://bugs.webkit.org/show_bug.cgi?id=91458 + + Reviewed by Tony Chang. + + There are HarfbuzzFace class (for old-harfbuzz) and HarfBuzzFace (for harfbuzz-ng) class. The difference is too subtle. Make them more distinct. + + No new tests. No changes in behavior. + + * WebCore.gyp/WebCore.gyp: Rename HarfBuzzFace to HarfBuzzNGFace. + * WebCore.gypi: Ditto. + * platform/graphics/FontPlatformData.h: Ditto. + (FontPlatformData): + * platform/graphics/cocoa/FontPlatformDataCocoa.mm: Ditto. + (WebCore::FontPlatformData::harfbuzzFace): + * platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.cpp: Ditto. + (WebCore::FontPlatformData::harfbuzzFace): + * platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.h: Ditto. + (FontPlatformData): + * platform/graphics/harfbuzz/ng/HarfBuzzNGFaceCoreText.cpp: Renamed from Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzFaceCoreText.cpp. + (WebCore): + (WebCore::floatToHarfBuzzPosition): + (WebCore::getGlyph): + (WebCore::getGlyphHorizontalAdvance): + (WebCore::getGlyphHorizontalOrigin): + (WebCore::getGlyphExtents): + (WebCore::harfbuzzCoreTextGetFontFuncs): + (WebCore::releaseTableData): + (WebCore::harfbuzzCoreTextGetTable): + (WebCore::HarfBuzzNGFace::createFace): + (WebCore::HarfBuzzNGFace::createFont): + (WebCore::HarfBuzzShaper::createGlyphBufferAdvance): + * platform/graphics/harfbuzz/ng/HarfBuzzNGFaceSkia.cpp: Renamed from Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzFaceSkia.cpp. + (WebCore): + (WebCore::SkiaScalarToHarfbuzzPosition): + (WebCore::SkiaGetGlyphWidthAndExtents): + (WebCore::harfbuzzGetGlyph): + (WebCore::harfbuzzGetGlyphHorizontalAdvance): + (WebCore::harfbuzzGetGlyphHorizontalOrigin): + (WebCore::harfbuzzGetGlyphExtents): + (WebCore::harfbuzzSkiaGetFontFuncs): + (WebCore::harfbuzzSkiaGetTable): + (WebCore::destroyPaint): + (WebCore::HarfBuzzNGFace::createFace): + (WebCore::HarfBuzzNGFace::createFont): + (WebCore::HarfBuzzShaper::createGlyphBufferAdvance): + * platform/graphics/harfbuzz/ng/HarfBuzzNGFace.cpp: Renamed from Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzFace.cpp. + (WebCore): + (WebCore::harfbuzzFaceCache): + (WebCore::HarfBuzzNGFace::HarfBuzzNGFace): + (WebCore::HarfBuzzNGFace::~HarfBuzzNGFace): + * platform/graphics/harfbuzz/ng/HarfBuzzNGFace.h: Renamed from Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzFace.h. + (WebCore): + (HarfBuzzNGFace): + (WebCore::HarfBuzzNGFace::create): + * platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp: + (WebCore::HarfBuzzShaper::shapeHarfBuzzRuns): + +2012-07-17 Kinuko Yasuda <kinuko@chromium.org> + + Record metrics to measure the usage of Blob([ArrayBuffer]) to eventually deprecate it + https://bugs.webkit.org/show_bug.cgi?id=90534 + + Reviewed by Jian Li. + + We are removing ArrayBuffer support in Blob constructor (in favor of + ArrayBufferView) but before doing that we should record its use relative to ArrayBufferView. + http://dev.w3.org/2006/webapi/FileAPI/#dfn-Blob + + No new tests as this has no functional changes. + + * fileapi/WebKitBlobBuilder.cpp: + (WebCore::WebKitBlobBuilder::append): + +2012-07-17 Joshua Bell <jsbell@chromium.org> + + IndexedDB: Key generator state not maintained across connections + https://bugs.webkit.org/show_bug.cgi?id=91456 + + Reviewed by Tony Chang. + + Explicitly store key generator state for each object store in the backing store, + rather than deriving it from the maximum key in the data (which violates the spec + if data is deleted). + + This change eliminates a (fragile) per-store cache of the value to simplify the + code. A cache could be re-introduced, requiring an "onbeforecommit" hook for + object stores, but it seems cleaner to save that for a follow-up patch. + + Test: storage/indexeddb/key-generator.html + + * Modules/indexeddb/IDBBackingStore.h: New APIs for getting/setting generator states. + (IDBBackingStore): + * Modules/indexeddb/IDBLevelDBBackingStore.cpp: + (WebCore::IDBLevelDBBackingStore::getObjectStores): Read generator state (but currently ignored). + (WebCore::IDBLevelDBBackingStore::createObjectStore): Write generator state. + (WebCore): + (WebCore::IDBLevelDBBackingStore::getKeyGeneratorCurrentNumber): + (WebCore::IDBLevelDBBackingStore::maybeUpdateKeyGeneratorCurrentNumber): Update, optionally + checking to see if the new value is greater than the old. (If caller got the value via + getKeyGeneratorCurrentNumber it is safe to skip the check.) + * Modules/indexeddb/IDBLevelDBBackingStore.h: + (IDBLevelDBBackingStore): + * Modules/indexeddb/IDBLevelDBCoding.cpp: + * Modules/indexeddb/IDBLevelDBCoding.h: + * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp: + (WebCore::IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl): Ditch the cache. + (WebCore::IDBObjectStoreBackendImpl::put): No need for abort task. + (WebCore::IDBObjectStoreBackendImpl::putWithIndexKeys): Ditto. + (WebCore::IDBObjectStoreBackendImpl::putInternal): Use the newfangled APIs below. + (WebCore::IDBObjectStoreBackendImpl::generateKey): + (WebCore::IDBObjectStoreBackendImpl::updateKeyGenerator): + * Modules/indexeddb/IDBObjectStoreBackendImpl.h: + (IDBObjectStoreBackendImpl): + +2012-07-17 Joshua Bell <jsbell@chromium.org> + + IndexedDB: Key generator state not maintained across connections + https://bugs.webkit.org/show_bug.cgi?id=91456 + + Reviewed by Tony Chang. + + Explicitly store key generator state for each object store in the backing store, + rather than deriving it from the maximum key in the data (which violates the spec + if data is deleted). + + This change eliminates a (fragile) per-store cache of the value to simplify the + code. A cache could be re-introduced, requiring an "onbeforecommit" hook for + object stores, but it seems cleaner to save that for a follow-up patch. + + Test: storage/indexeddb/key-generator.html + + * Modules/indexeddb/IDBBackingStore.h: New APIs for getting/setting generator states. + (IDBBackingStore): + * Modules/indexeddb/IDBLevelDBBackingStore.cpp: + (WebCore::IDBLevelDBBackingStore::getObjectStores): Read generator state (but currently ignored). + (WebCore::IDBLevelDBBackingStore::createObjectStore): Write generator state. + (WebCore): + (WebCore::IDBLevelDBBackingStore::getKeyGeneratorCurrentNumber): + (WebCore::IDBLevelDBBackingStore::maybeUpdateKeyGeneratorCurrentNumber): Update, optionally + checking to see if the new value is greater than the old. (If caller got the value via + getKeyGeneratorCurrentNumber it is safe to skip the check.) + * Modules/indexeddb/IDBLevelDBBackingStore.h: + (IDBLevelDBBackingStore): + * Modules/indexeddb/IDBLevelDBCoding.cpp: + * Modules/indexeddb/IDBLevelDBCoding.h: + * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp: + (WebCore::IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl): Ditch the cache. + (WebCore::IDBObjectStoreBackendImpl::put): No need for abort task. + (WebCore::IDBObjectStoreBackendImpl::putWithIndexKeys): Ditto. + (WebCore::IDBObjectStoreBackendImpl::putInternal): Use the newfangled APIs below. + (WebCore::IDBObjectStoreBackendImpl::generateKey): + (WebCore::IDBObjectStoreBackendImpl::updateKeyGenerator): + * Modules/indexeddb/IDBObjectStoreBackendImpl.h: + (IDBObjectStoreBackendImpl): + +2012-07-17 Alec Flett <alecflett@chromium.org> + + IndexedDB: createIndex should throw INVALID_ACCESS_ERR instead of NOT_SUPPORTED_ERR + https://bugs.webkit.org/show_bug.cgi?id=91553 + + Reviewed by Tony Chang. + + Update createIndex to throw an INVALID_ACCESS_ERR + as per the IndexedDB spec. + + No new tests: existing tests have been updated + + * Modules/indexeddb/IDBDatabaseException.cpp: + (WebCore): + * Modules/indexeddb/IDBDatabaseException.h: + * Modules/indexeddb/IDBObjectStore.cpp: + (WebCore::IDBObjectStore::createIndex): + +2012-07-17 Adam Barth <abarth@webkit.org> + + DragImageChromiumMac.cpp is never compiled and can be removed + https://bugs.webkit.org/show_bug.cgi?id=91545 + + Reviewed by Tony Chang. + + This file would only be compiled on chromium-mac, but it's excluded + from that build. This is likely left over from the CG configuration. + + * WebCore.gyp/WebCore.gyp: + * WebCore.gypi: + * platform/chromium/DragImageChromiumMac.cpp: Removed. + +2012-07-17 Roger Fong <roger_fong@apple.com> + + Assertion failure/crash on Windows when using a font in an SVG + element with an unresaonbly large font size + https://bugs.webkit.org/show_bug.cgi?id=91273 + Radar: <rdar://problem/8355401> + + Reviewed by Tim Horton. + + When using a font in an SVG element with an unreasonably large + font size in Windows, WebKit crashes. The problem has to do with + font sizes overflowing into negative values in the Windows specific code. + The fix is to cap the font sizes to something reasonable when the font style is getting processed. + The fix will apply to both CSS and SVG so that behaviour is consistent. + + Test: svg/text/font-size-too-large-crash.svg + + * css/StyleBuilder.cpp: + (WebCore::ApplyPropertyFontSize::applyValue): + This is where the font size capping now occurs. Caps size to 1000000. + Both CSS and SVG reach the font size capping code here. + + * css/StyleResolver.cpp: + (WebCore::StyleResolver::collectMatchingRulesForList): + Capping here removed, moved to StyleBuilder.cpp. + +2012-07-17 David Barr <davidbarr@chromium.org> + + Add parsing and style application for css3-images image-orientation + https://bugs.webkit.org/show_bug.cgi?id=89624 + + Reviewed by Tony Chang. + + The css3-images module is at candidate recommendation. + http://www.w3.org/TR/2012/CR-css3-images-20120417/#the-image-orientation + + Test: fast/css/image-orientation/image-orientation.html + + * css/CSSComputedStyleDeclaration.cpp: Add computed style for image-orientation. + (WebCore): Add CSSPropertyImageOrientation to computedProperties. + (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue): Map CSSPropertyImageOrientation using cast operator from PrimitiveValueMappings. + * css/CSSParser.cpp: Add parsing rule for image-orientation. + (WebCore::CSSParser::parseValue): Parse the value of CSSPropertyImageOrientation as an angle. + * css/CSSPrimitiveValueMappings.h: Add mappings between CSSPrimitiveValue and ImageOrientationEnum. + (WebCore): Add conditional include for ImageOrientation.h. + (WebCore::CSSPrimitiveValue::CSSPrimitiveValue): Map the natural orientations to angles. + (WebCore::CSSPrimitiveValue::operator ImageOrientationEnum): Round angles away from zero to quarter turns and map to the natural orientations. + * css/CSSProperty.cpp: Add CSSPropertyImageOrientation. + (WebCore::CSSProperty::isInheritedProperty): Map CSSPropertyImageOrientation inherited. + * css/CSSPropertyNames.in: Add image-orientation. + * css/StyleBuilder.cpp: Add style application logic for CSSPropertyImageOrientation. + (WebCore::StyleBuilder::StyleBuilder): Map CSSPropertyImageOrientation to RenderStyle::imageOrientation with type ImageOrientationEnum. + * css/StyleResolver.cpp: Handle CSSPropertyImageOrientation. + (WebCore::StyleResolver::applyProperty): Expect CSSPropertyImageOrientation to be handled by StyleBuilder. + * rendering/style/RenderStyle.h: Add imageOrientation, setImageOrientation and initialImageOrientation. + * rendering/style/StyleRareInheritedData.cpp: Add m_imageOrientation. + (WebCore::StyleRareInheritedData::StyleRareInheritedData): Add m_imageOrientation to default and copy contructors. + (WebCore::StyleRareInheritedData::operator==): Include m_imageOrientation in comparison. + * rendering/style/StyleRareInheritedData.h: Add m_imageOrientation. + (StyleRareInheritedData): Add 4-bit field m_imageOrientation, mapping to ImageOrientationEnum. + +2012-07-17 Adrienne Walker <enne@google.com> + + REGRESSION(r122215) - RenderObject::willRenderImage crashes on null view() + https://bugs.webkit.org/show_bug.cgi?id=91525 + + Reviewed by Julien Chaffraix. + + Fix by doing an early out check. This is intended to fix the crash in + http://crbug.com/137161. + + No new test, because unfortunately a layout test is ill-suited to + reproing this kind of Document creation/destruction bug. + + * rendering/RenderObject.cpp: + (WebCore::RenderObject::willRenderImage): + +2012-07-17 Emil A Eklund <eae@chromium.org> + + vertical-align: middle causes overflow with subpixel layout + https://bugs.webkit.org/show_bug.cgi?id=91464 + + Reviewed by Eric Seidel. + + Using vertical-align: middle in combination with an overflow value other + than visible can cause the overflow height to be computed incorrectly. + + Test: fast/sub-pixel/vertical-align-middle-overflow.html + + * rendering/RootInlineBox.cpp: + (WebCore::RootInlineBox::verticalPositionForBox): + Round verticalPosition after calculation instead of flooring the result + of the xHeight calculation. By flooring it the resulting value is in + effect rounded up which can cause the height of the box to grow by one. + By rounding the resulting value thevertical position is more accurate and + the off by one error is avoided. + +2012-07-17 Philip Rogers <pdr@google.com> + + Move zero-length-subpaths from RenderSVGShape to RenderSVGPath + https://bugs.webkit.org/show_bug.cgi?id=90716 + + Reviewed by Nikolas Zimmermann. + + Previously zero-length-subpath code was present in RenderSVGShape but it is + only needed in RenderSVGPath. This patch moves the zero-length-subpath code + to RenderSVGPath. + + In this change, we gain: + 1) Ellipses, Circles, and Rects will no longer carry an empty Vector nor + checks for zero-length subpaths which (per the spec) they cannot have. + 2) RenderSVGShape, the superclass of all shape rendering, has been + drastically simplified by removing 70 lines of code that only applies + to Path rendering. This generally aids in code understandability. + + The patch is primarily a straightforward code move but useStrokeStyleToFill + needs further explanation: + Zero-length-subpaths are drawn using rectangular and circular paths which + are filled. + Previously in RenderSVGShape::fillAndStrokePath, strokePath was called for + the main path with ApplyToStrokeMode and then strokePath was called for + each zero-length-subpath with ApplyToFillMode. + ApplyToFillMode had the effect of setting the context's stroke style to + the fill style so zero-length-subpaths were "filled" with the stroke style. + After this patch, the context is only setup once (which is faster!) using + ApplyToStrokeMode so we manually set the stroke style to the fill style + using useStrokeStyleToFill. + + No new tests, just a refactoring. + + * rendering/svg/RenderSVGPath.cpp: + (WebCore::RenderSVGPath::updateShapeFromElement): + (WebCore): + (WebCore::RenderSVGPath::calculateUpdatedStrokeBoundingBox): + (WebCore::useStrokeStyleToFill): + (WebCore::RenderSVGPath::strokeShape): + (WebCore::RenderSVGPath::shapeDependentStrokeContains): + (WebCore::RenderSVGPath::shouldStrokeZeroLengthSubpath): + (WebCore::RenderSVGPath::zeroLengthLinecapPath): + (WebCore::RenderSVGPath::zeroLengthSubpathRect): + (WebCore::RenderSVGPath::updateZeroLengthSubpaths): + * rendering/svg/RenderSVGPath.h: + (RenderSVGPath): + * rendering/svg/RenderSVGShape.cpp: + (WebCore::RenderSVGShape::updateShapeFromElement): + (WebCore::RenderSVGShape::strokeShape): + (WebCore::RenderSVGShape::strokeContains): + (WebCore): + (WebCore::RenderSVGShape::fillShape): + (WebCore::RenderSVGShape::fillAndStrokeShape): + (WebCore::RenderSVGShape::paint): + (WebCore::RenderSVGShape::calculateStrokeBoundingBox): + * rendering/svg/RenderSVGShape.h: + (WebCore::RenderSVGShape::hasPath): + (WebCore::RenderSVGShape::hasNonScalingStroke): + (RenderSVGShape): + (WebCore::RenderSVGShape::strokeBoundingBox): + +2012-07-17 Ryosuke Niwa <rniwa@webkit.org> + + invalidateNodeListCachesInAncestors walks up ancestors even when an attribute that doesn't invalidate node lists changes + https://bugs.webkit.org/show_bug.cgi?id=91530 + + Reviewed by Ojan Vafai. + + The bug was caused by invalidateNodeListCachesInAncestors not calling Document::shouldInvalidateNodeListCaches with + attrName. Done that. + + This chance revealed a bug in shouldInvalidateTypeOnAttributeChange that we weren't checking form attribute changes for + RadioNodeList and HTMLCollection, so fixed the bug. + + Also renamed Document::clearNodeListCaches to invalidateNodeListCaches to match the name convention used elsewhere, + and added a new version of DynamicNodeListCacheBase::invalidateCache that takes attrName to reduce the code duplication. + + Test: fast/forms/elements-invalidate-on-form-attribute-invalidation.html + + * dom/Document.cpp: + (WebCore::Document::invalidateNodeListCaches): + * dom/Document.h: + (Document): + * dom/DynamicNodeList.h: + (WebCore::DynamicNodeListCacheBase::invalidateCache): + (WebCore::DynamicNodeListCacheBase::shouldInvalidateTypeOnAttributeChange): + * dom/Node.cpp: + (WebCore::Node::invalidateNodeListCachesInAncestors): + (WebCore::NodeListsNodeData::invalidateCaches): + +2012-07-17 Max Vujovic <mvujovic@adobe.com> + + Update ANGLE in WebKit + https://bugs.webkit.org/show_bug.cgi?id=89039 + + Reviewed by Dean Jackson and Mark Rowe. + + Update ANGLE to r1170, with the following modifications: + + (1) Use Bison 2.3 instead of Bison 2.4.2 to generate ExpressionParser.cpp and + glslang_tab.cpp. I had to modify ExpressionParser.y to make it compatible with Bison + 2.3. The changes have been contributed back to ANGLE in r1224. + + (2) Continue to recognize QNX as POSIX in ANGLE. This has been contributed back to ANGLE + in r1223. + + (3) Rename ANGLE/src/compiler/preprocessor/new/Diagnostic.cpp to DiagnosticBase.cpp. + Rename ANGLE/src/compiler/preprocessor/new/DirectiveHandler.cpp to DirectiveHandlerBase.cpp. + + With the introduction of ANGLE's new preprocessor, there were two files named Diagnostic.cpp + in ANGLE under different folders. This caused problems on the QT build when their object + files, both named Diagnostic.o, tried to go in the same folder. Renaming one of them to + DiagnosticBase.cpp avoids this conflict. The same situation occurred with + DirectiveHandler.cpp. I will work on contributing this change back to ANGLE for future + updates. + + (4) Add the following lines to glslang.y and ExpressionParser.y: + #define YYENABLE_NLS 0 + #define YYLTYPE_IS_TRIVIAL 1 + + Bison 2.3 doesn't first check that these macros are defined before reading their value, + which causes the QT build to fail. + + We work around this issue in the same way in CSSGrammar.y. + + I will work on contributing this change back to ANGLE. + + No new tests. No change in behavior. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * Target.pri: + +2012-07-17 Stephen Chenney <schenney@chromium.org> + + Crash in SVGStopElement::stopColorIncludingOpacity + https://bugs.webkit.org/show_bug.cgi?id=90814 + + Reviewed by Dirk Schulze. + + No new tests as there should be no change in functionality. + + * svg/SVGStopElement.cpp: + (WebCore::SVGStopElement::stopColorIncludingOpacity): Added a check for null + renderer and style. It is hard to see how this is happening because + the code is only invoked if the parent gradient has a renderer, and it seems + the stop element should always have a renderer when the parent has a renderer. + Still, it obviously can happen and does so frequently enough to generate multiple + Chromium crash reports per day. The fix is marked with a FIXME, as we expect to + remove this code entirely soon. + +2012-07-17 Emil A Eklund <eae@chromium.org> + + Incorrect offset used for scrollWidth/Height calculation + https://bugs.webkit.org/show_bug.cgi?id=91461 + + Reviewed by Eric Seidel. + + Due to a different offset being used to calculate the scrollWidth/Height + and pixelSnappedClientWidth/Height the scroll value can be off by one in + same cases. This can causes scrollbars to appear even when there is no + overflow. + + Test: fast/sub-pixel/block-with-margin-overflow.html + + * rendering/RenderBox.cpp: + (WebCore::RenderBox::scrollWidth): + Change location offset passed to snapSizeToPixel to include x() to match + offset used by pixelSnappedClientWidth. + + (WebCore::RenderBox::scrollHeight): + Change location offset passed to snapSizeToPixel to include y() to match + offset used by pixelSnappedClientHeight. + + * rendering/RenderLayer.cpp: + (WebCore::RenderLayer::clampScrollOffset): + Change calculation to use pixelSnappedClientWidth/Height as it is + subtracted from the pixel snapped scrollWidth/Height values. + + (WebCore::RenderLayer::scrollWidth): + (WebCore::RenderLayer::scrollHeight): + Change RenderLayer versions of scrollWidth/Height to include x()/y() as + per the RenderBox versions. + +2012-07-17 Hans Muller <hmuller@adobe.com> + + Rename CSS Exclusions CSSWrapShape class properties to match Exclusion shape function parameters + https://bugs.webkit.org/show_bug.cgi?id=89669 + + Reviewed by Dirk Schulze. + + Renamed left,top properties in the exclusion shape types to better match the specification + http://dev.w3.org/csswg/css3-exclusions/#shapes-from-svg-syntax: + + WrapShapeRectangle, CSSWrapShapeRectangle - left,top should be x, y + WrapShapeCircle, CSSWrapShapeCircle - left,top should be centerX, centerY + WrapShapeEllipse, CSSWrapShapeEllipse - left,top should be centerX, centerY + + No new tests or tests revisions were needed, the existing tests cover these APIs. + + * css/CSSParser.cpp: + (WebCore::CSSParser::parseExclusionShapeRectangle): + (WebCore::CSSParser::parseExclusionShapeCircle): + (WebCore::CSSParser::parseExclusionShapeEllipse): + * css/CSSWrapShapes.cpp: + (WebCore::CSSWrapShapeRectangle::cssText): + (WebCore::CSSWrapShapeCircle::cssText): + (WebCore::CSSWrapShapeEllipse::cssText): + * css/CSSWrapShapes.h: + (WebCore::CSSWrapShapeRectangle::x): + (WebCore::CSSWrapShapeRectangle::y): + (WebCore::CSSWrapShapeRectangle::setX): + (WebCore::CSSWrapShapeRectangle::setY): + (CSSWrapShapeRectangle): + (WebCore::CSSWrapShapeCircle::centerX): + (WebCore::CSSWrapShapeCircle::centerY): + (WebCore::CSSWrapShapeCircle::setCenterX): + (WebCore::CSSWrapShapeCircle::setCenterY): + (CSSWrapShapeCircle): + (WebCore::CSSWrapShapeEllipse::centerX): + (WebCore::CSSWrapShapeEllipse::centerY): + (WebCore::CSSWrapShapeEllipse::setCenterX): + (WebCore::CSSWrapShapeEllipse::setCenterY): + (CSSWrapShapeEllipse): + * css/WrapShapeFunctions.cpp: + (WebCore::valueForWrapShape): + (WebCore::wrapShapeForValue): + * rendering/style/WrapShapes.h: + (WebCore::WrapShapeRectangle::x): + (WebCore::WrapShapeRectangle::y): + (WebCore::WrapShapeRectangle::setX): + (WebCore::WrapShapeRectangle::setY): + (WrapShapeRectangle): + (WebCore::WrapShapeCircle::centerX): + (WebCore::WrapShapeCircle::centerY): + (WebCore::WrapShapeCircle::setCenterX): + (WebCore::WrapShapeCircle::setCenterY): + (WrapShapeCircle): + (WebCore::WrapShapeEllipse::centerX): + (WebCore::WrapShapeEllipse::centerY): + (WebCore::WrapShapeEllipse::setCenterX): + (WebCore::WrapShapeEllipse::setCenterY): + (WrapShapeEllipse): + +2012-07-16 Pavel Feldman <pfeldman@chromium.org> + + Web Inspector: implement search / replace in source files (behind experiment flag) + https://bugs.webkit.org/show_bug.cgi?id=91394 + + Reviewed by Vsevolod Vlasov. + + This change adds "loop" parameter to the go to next / previous search + adds a UI component + for search / replace of text in the sources panel. New UI component is behind the experiment. + + * English.lproj/localizedStrings.js: + * inspector/front-end/ConsolePanel.js: + (WebInspector.ConsolePanel.prototype.performSearch): + (WebInspector.ConsolePanel.prototype.jumpToNextSearchResult): + (WebInspector.ConsolePanel.prototype.jumpToPreviousSearchResult): + * inspector/front-end/ElementsPanel.js: + (WebInspector.ElementsPanel.prototype.jumpToNextSearchResult): + (WebInspector.ElementsPanel.prototype.jumpToPreviousSearchResult): + * inspector/front-end/ExtensionPanel.js: + (WebInspector.ExtensionPanel.prototype.performSearch): + (WebInspector.ExtensionPanel.prototype.jumpToNextSearchResult): + (WebInspector.ExtensionPanel.prototype.jumpToPreviousSearchResult): + * inspector/front-end/JavaScriptSourceFrame.js: + (WebInspector.JavaScriptSourceFrame.prototype.afterTextChanged): + (WebInspector.JavaScriptSourceFrame.prototype.beforeTextChanged): + * inspector/front-end/NetworkPanel.js: + (WebInspector.NetworkLogView.prototype._sortItems): + (WebInspector.NetworkLogView.prototype._updateFilter): + (WebInspector.NetworkLogView.prototype.performSearch): + (WebInspector.NetworkLogView.prototype.jumpToPreviousSearchResult): + (WebInspector.NetworkLogView.prototype.jumpToNextSearchResult): + (WebInspector.NetworkPanel.prototype.performSearch): + * inspector/front-end/Panel.js: + (WebInspector.Panel.prototype.performSearch): + (WebInspector.Panel.prototype.jumpToNextSearchResult): + (WebInspector.Panel.prototype.jumpToPreviousSearchResult): + (WebInspector.Panel.prototype.canSearchAndReplace): + (WebInspector.Panel.prototype.replaceSelectionWith): + (WebInspector.Panel.prototype.replaceAllWith): + * inspector/front-end/ProfilesPanel.js: + (WebInspector.ProfilesPanel.prototype.jumpToNextSearchResult): + (WebInspector.ProfilesPanel.prototype.jumpToPreviousSearchResult): + * inspector/front-end/ResourcesPanel.js: + (WebInspector.ResourcesPanel.prototype.jumpToNextSearchResult): + (WebInspector.ResourcesPanel.prototype.jumpToPreviousSearchResult): + * inspector/front-end/ScriptsPanel.js: + (WebInspector.ScriptsPanel.prototype.performSearch.finishedCallback): + (WebInspector.ScriptsPanel.prototype.performSearch): + (WebInspector.ScriptsPanel.prototype.jumpToNextSearchResult): + (WebInspector.ScriptsPanel.prototype.jumpToPreviousSearchResult): + (WebInspector.ScriptsPanel.prototype.canSearchAndReplace): + (WebInspector.ScriptsPanel.prototype.replaceSelectionWith): + (WebInspector.ScriptsPanel.prototype.replaceAllWith): + * inspector/front-end/SearchController.js: + (WebInspector.SearchController): + (WebInspector.SearchController.prototype.cancelSearch): + (WebInspector.SearchController.prototype.disableSearchUntilExplicitAction): + (WebInspector.SearchController.prototype.handleShortcut): + (WebInspector.SearchController.prototype.activePanelChanged.performPanelSearch): + (WebInspector.SearchController.prototype.activePanelChanged): + (WebInspector.SearchController.prototype._updateSearchNavigationButtonState): + (WebInspector.SearchController.prototype.showSearchField): + (WebInspector.SearchController.prototype._onKeyDown): + (WebInspector.SearchController.prototype._onInput): + (WebInspector.SearchController.prototype._onNextButtonSearch): + (WebInspector.SearchController.prototype._onPrevButtonSearch): + (WebInspector.SearchController.prototype._performSearch): + (WebInspector.SearchController.prototype._toggleReplaceVisibility): + (WebInspector.SearchController.prototype._replace): + (WebInspector.SearchController.prototype._replaceAll): + * inspector/front-end/Settings.js: + (WebInspector.ExperimentsSettings): + * inspector/front-end/SourceFrame.js: + (WebInspector.SourceFrame.createSearchRegex): + (WebInspector.SourceFrame.prototype.beforeTextChanged): + (WebInspector.SourceFrame.prototype.replaceSearchMatchWith): + (WebInspector.SourceFrame.prototype.replaceAllWith): + (WebInspector.TextEditorDelegateForSourceFrame.prototype.beforeTextChanged): + (WebInspector.TextEditorDelegateForSourceFrame.prototype.commitEditing): + * inspector/front-end/StylesPanel.js: + (WebInspector.StyleSourceFrame.prototype.afterTextChanged): + * inspector/front-end/TextEditor.js: + (WebInspector.TextEditor.prototype._commitEditing): + * inspector/front-end/TextEditorModel.js: + (WebInspector.TextEditorModel.endsWithBracketRegex.): + * inspector/front-end/inspector.css: + (.search-replace): + (.search-replace:focus): + (.toolbar-search-navigation-controls): + (.toolbar-search-navigation.enabled): + (.toolbar-search): + (.toolbar-search input[type="checkbox"]): + (.toolbar-search button): + (.toolbar-search button:active): + (.toolbar-search-control): + (.toolbar-replace-control): + (.toolbar-search-navigation.enabled:active): + (.toolbar-search-navigation.toolbar-search-navigation-prev): + (.toolbar-search-navigation.toolbar-search-navigation-prev.enabled:active): + (.toolbar-search-navigation.toolbar-search-navigation-next): + (.toolbar-search-navigation.toolbar-search-navigation-next.enabled:active): + (.drawer-header-close-button): + (.inspector-footer): + +2012-07-17 Gabor Ballabas <gaborb@inf.u-szeged.hu> + + [Qt][V8] Remove the V8 related codepaths and configuration + https://bugs.webkit.org/show_bug.cgi?id=90863 + + Reviewed by Simon Hausmann. + + No new tests because no new functionality. + + * DerivedSources.pri: + * Target.pri: + * WebCore.gypi: + * WebCore.pri: + * bindings/v8/ScriptCachedFrameData.cpp: + * bindings/v8/ScriptCachedFrameData.h: + * bindings/v8/ScriptController.cpp: + * bindings/v8/ScriptController.h: + (ScriptController): + * bindings/v8/ScriptControllerQt.cpp: Removed. + * bindings/v8/V8GCController.cpp: + (WebCore::V8GCController::checkMemoryUsage): + * bindings/v8/custom/V8InspectorFrontendHostCustom.cpp: + (WebCore::histogramEnumeration): + (WebCore::V8InspectorFrontendHost::recordActionTakenCallback): + (WebCore::V8InspectorFrontendHost::recordPanelShownCallback): + (WebCore::V8InspectorFrontendHost::recordSettingChangedCallback): + * config.h: + +2012-07-17 Zoltan Horvath <zoltan@webkit.org> + + [QT] REGRESSION (r122720): svg/filters/feSpecularLight-premultiplied.svg + https://bugs.webkit.org/show_bug.cgi?id=91390 + + Reviewed by Zoltan Herczeg. + + Fix the regression by using the proper imagetype conversion in ImageBuffer::platformTransformColorSpace. + + The test is unskipped. + + * platform/graphics/qt/ImageBufferQt.cpp: + (WebCore::ImageBuffer::platformTransformColorSpace): + +2012-07-17 Vivek Galatage <vivekgalatage@gmail.com> + + Web Inspector: refactor InspectorController::connectFrontend() to accept InspectorFrontendChannel. + https://bugs.webkit.org/show_bug.cgi?id=91196 + + Reviewed by Pavel Feldman. + + Refactoring InspectorClients. InspectorClient::openInspectorFrontend + now returning the InspectorFrontendChannel. Also refactored + InspectorController::connectFrontend() to receive + InspectorFrontendChannel. + + No new test as code refactoring done. + + * inspector/InspectorClient.h: + (WebCore): + (InspectorClient): + * inspector/InspectorController.cpp: + (WebCore::InspectorController::InspectorController): + (WebCore::InspectorController::connectFrontend): + (WebCore::InspectorController::show): + (WebCore::InspectorController::reconnectFrontend): + * inspector/InspectorController.h: + (WebCore): + (InspectorController): + * loader/EmptyClients.h: + (WebCore::EmptyInspectorClient::openInspectorFrontend): + (WebCore::EmptyInspectorClient::hideHighlight): + +2012-07-17 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r122834. + http://trac.webkit.org/changeset/122834 + https://bugs.webkit.org/show_bug.cgi?id=91492 + + it broke the chromium (Requested by kkristof on #webkit). + + * DerivedSources.pri: + * Target.pri: + * WebCore.pri: + * bindings/v8/ScriptCachedFrameData.cpp: + (WebCore): + (WebCore::ScriptCachedFrameData::ScriptCachedFrameData): + (WebCore::ScriptCachedFrameData::domWindow): + (WebCore::ScriptCachedFrameData::restore): + (WebCore::ScriptCachedFrameData::clear): + * bindings/v8/ScriptCachedFrameData.h: + (WebCore): + (ScriptCachedFrameData): + (WebCore::ScriptCachedFrameData::~ScriptCachedFrameData): + * bindings/v8/ScriptController.cpp: + * bindings/v8/ScriptController.h: + (ScriptController): + * bindings/v8/ScriptControllerQt.cpp: Copied from Source/WebCore/bindings/v8/ScriptCachedFrameData.cpp. + (WebCore): + (WebCore::ScriptController::qtScriptEngine): + * bindings/v8/V8GCController.cpp: + (WebCore::V8GCController::checkMemoryUsage): + * bindings/v8/custom/V8InspectorFrontendHostCustom.cpp: + (WebCore): + (WebCore::V8InspectorFrontendHost::recordActionTakenCallback): + (WebCore::V8InspectorFrontendHost::recordPanelShownCallback): + (WebCore::V8InspectorFrontendHost::recordSettingChangedCallback): + * config.h: + +2012-07-17 Gabor Ballabas <gaborb@inf.u-szeged.hu> + + [Qt][V8] Remove the V8 related codepaths and configuration + https://bugs.webkit.org/show_bug.cgi?id=90863 + + Reviewed by Simon Hausmann. + + No new tests, because there is no new functionality. + + * DerivedSources.pri: + * Target.pri: + * WebCore.pri: + * bindings/v8/ScriptCachedFrameData.cpp: + * bindings/v8/ScriptCachedFrameData.h: + * bindings/v8/ScriptController.cpp: + * bindings/v8/ScriptController.h: + (ScriptController): + * bindings/v8/ScriptControllerQt.cpp: Removed. + * bindings/v8/V8GCController.cpp: + (WebCore::V8GCController::checkMemoryUsage): + * bindings/v8/custom/V8InspectorFrontendHostCustom.cpp: + (WebCore::histogramEnumeration): + (WebCore::V8InspectorFrontendHost::recordActionTakenCallback): + (WebCore::V8InspectorFrontendHost::recordPanelShownCallback): + (WebCore::V8InspectorFrontendHost::recordSettingChangedCallback): + * config.h: + +2012-07-17 Kwang Yul Seo <skyul@company100.net> + + "in body" insertion mode, "any other end tag" step 2.1 is updated + https://bugs.webkit.org/show_bug.cgi?id=91473 + + Reviewed by Eric Seidel. + + The HTML5 spec is updated to change the 'end tag' processing to not imply + its own end tag, since that makes no sense. Step 2.1 now says + "Generate implied end tags, except for elements with the same tag name as the token." + Modified to follow the updated spec. Also removed the first FIXME because now + ElementRecord can't be deleted by the preceeding call. + + This patch does not actually change the behavior because of the previous + check (aborts if generateImpliedEndTags has already popped the node for the token), + so no new tests. + + * html/parser/HTMLTreeBuilder.cpp: + (WebCore::HTMLTreeBuilder::processAnyOtherEndTagForInBody): + +2012-07-17 Shinya Kawanaka <shinyak@chromium.org> + + [Regression] Infinite loop in document.elementFromPoint + https://bugs.webkit.org/show_bug.cgi?id=90820 + + Reviewed by Nikolas Zimmermann. + + Node::shadowAncestorNode returns the caller node itself for SVGElement. However, + since we have already implemented event retargeting algorithm in Shadow DOM, we don't have to + take a special care of SVGElement for Node.shadowAncestorNode() now. + + This patch will removes the special care code and fixes infinite loop in document.elementFromPoint(). + + Test: svg/hittest/svg-use-element-from-point.html + + * dom/Node.cpp: + (WebCore::Node::shadowAncestorNode): + +2012-07-17 Shinya Kawanaka <shinyak@chromium.org> + + Shadow DOM for img element + https://bugs.webkit.org/show_bug.cgi?id=90532 + + Reviewed by Hajime Morita. + + This patch adds Shadow DOM support for img element. + + According to the Shadow DOM spec, img element should behave like having a user agent Shadow DOM. + However, if we add Shadow DOM to img by default, it will cause performance regression and memory bloat. + + So, we would like to postpone adding a Shadow DOM to img until when we really need it. In other words, + we add our User Agent Shadow DOM to img just before a user adds Author Shadow DOM. + + The User Agent Shadow DOM for img has only one element, which displays an image. If img has + a Shadow DOM, img will behave like <span style="display: inline-block"> by default. The display style can + be chagned using CSS though. + + This patch also adds ImageLoaderClient. The element we render an image and the element we take an argument + from were the same, however not they might be different. We would like to encapsulate the fact into + ImageLoaderClient. + + Tests: fast/dom/shadow/shadowdom-for-image-alt-update.html + fast/dom/shadow/shadowdom-for-image-alt.html + fast/dom/shadow/shadowdom-for-image-content.html + fast/dom/shadow/shadowdom-for-image-dynamic.html + fast/dom/shadow/shadowdom-for-image-event-click.html + fast/dom/shadow/shadowdom-for-image-in-shadowdom.html + fast/dom/shadow/shadowdom-for-image-map.html + fast/dom/shadow/shadowdom-for-image-style.html + fast/dom/shadow/shadowdom-for-image-with-multiple-shadow.html + fast/dom/shadow/shadowdom-for-image-with-width-and-height.html + fast/dom/shadow/shadowdom-for-image.html + + * CMakeLists.txt: + * GNUmakefile.list.am: + * Target.pri: + * WebCore.gypi: + * WebCore.vcproj/WebCore.vcproj: + * WebCore.xcodeproj/project.pbxproj: + * css/html.css: + (img): + * html/HTMLImageElement.cpp: + (WebCore::ImageElement::setImageIfNecessary): + (WebCore): + (WebCore::ImageElement::createRendererForImage): + (WebCore::HTMLImageElement::willAddAuthorShadowRoot): When we don't have a user agent Shadow DOM yet + we add it. + (WebCore::HTMLImageElement::createShadowSubtree): + (WebCore::HTMLImageElement::imageElement): + (WebCore::HTMLImageElement::parseAttribute): + (WebCore::HTMLImageElement::createRenderer): If a user agent Shadow DOM is attached, we create + Renderer from style, instead of creating RenderImage. + (WebCore::HTMLImageElement::attach): + (WebCore::HTMLImageElement::innerElement): + * html/HTMLImageElement.h: + (WebCore): + (ImageElement): + (HTMLImageElement): + (WebCore::HTMLImageElement::sourceElement): + (WebCore::HTMLImageElement::refSourceElement): + (WebCore::HTMLImageElement::derefSourceElement): + (WebCore::HTMLImageElement::imageRenderer): + (WebCore::HTMLImageElement::imageLoader): + (WebCore::isHTMLImageElement): + (WebCore::toHTMLImageElement): + * html/HTMLImageLoader.cpp: + (WebCore::HTMLImageLoader::HTMLImageLoader): + (WebCore::HTMLImageLoader::dispatchLoadEvent): + (WebCore::HTMLImageLoader::sourceURI): + (WebCore::HTMLImageLoader::notifyFinished): + * html/HTMLImageLoader.h: + (HTMLImageLoader): + * html/HTMLInputElement.h: + * html/HTMLObjectElement.h: + * html/HTMLPlugInElement.h: + * html/HTMLTagNames.in: + * html/HTMLVideoElement.h: + * html/shadow/ImageInnerElement.cpp: Added. + (WebCore): + (WebCore::ImageInnerElement::ImageInnerElement): + (WebCore::ImageInnerElement::hostImage): + (WebCore::ImageInnerElement::imageLoader): + (WebCore::ImageInnerElement::attach): + (WebCore::ImageInnerElement::createRenderer): + * html/shadow/ImageInnerElement.h: Added. + (WebCore): + (ImageInnerElement): + (WebCore::ImageInnerElement::imageRenderer): + (WebCore::ImageInnerElement::create): + (WebCore::isImageInnerElement): + (WebCore::toImageInnerElement): + * loader/ImageLoader.cpp: + (WebCore::ImageLoader::ImageLoader): + (WebCore::ImageLoader::~ImageLoader): + (WebCore): + (WebCore::ImageLoader::document): + (WebCore::ImageLoader::updateFromElement): + (WebCore::ImageLoader::notifyFinished): + (WebCore::ImageLoader::renderImageResource): + (WebCore::ImageLoader::updatedHasPendingLoadEvent): + (WebCore::ImageLoader::dispatchPendingBeforeLoadEvent): + (WebCore::ImageLoader::dispatchPendingLoadEvent): + (WebCore::ImageLoader::dispatchPendingErrorEvent): + * loader/ImageLoader.h: + (WebCore): + (ImageLoader): + (WebCore::ImageLoader::client): + * loader/ImageLoaderClient.h: Added. + (WebCore): + (ImageLoaderClient): Provides the necessary interfaces to ImageLoader. + (WebCore::ImageLoaderClient::~ImageLoaderClient): + (ImageLoaderClientBase): + (WebCore::ImageLoaderClientBase::sourceElement): + (WebCore::ImageLoaderClientBase::imageElement): + (WebCore::ImageLoaderClientBase::refSourceElement): + (WebCore::ImageLoaderClientBase::derefSourceElement): + * rendering/RenderImage.cpp: + (WebCore::RenderImage::paintIntoRect): + (WebCore::RenderImage::imageMap): + (WebCore::RenderImage::updateAltText): + (WebCore::RenderImage::hostImageElement): + (WebCore): + * rendering/RenderImage.h: + (WebCore): + (RenderImage): + * rendering/RenderObject.cpp: + (WebCore::RenderObject::shouldRespectImageOrientation): + * svg/SVGImageElement.h: + (SVGImageElement): + * svg/SVGImageLoader.cpp: + (WebCore::SVGImageLoader::SVGImageLoader): + (WebCore::SVGImageLoader::dispatchLoadEvent): + (WebCore::SVGImageLoader::sourceURI): + * svg/SVGImageLoader.h: + (SVGImageLoader): + +2012-07-17 Kent Tamura <tkent@chromium.org> + + Internals: Remove injectPagePopupController() + https://bugs.webkit.org/show_bug.cgi?id=91471 + + Reviewed by Hajime Morita. + + r122558 introduced injectPagePopupController(), however we'd like to + avoid adding such JavaScript binding code. We can avoid it by exposing a + PagePopupController for a mock and injecting the following code to the + popup document: + + <script>window.pagePopupController = window.internals.pagePopupController</script> + + No new tests. This is a kind of refactoring. + + * testing/InternalSettings.cpp: + (WebCore::InternalSettings::pagePopupController): + Added. Accessor for PagePopupControler owned by the MockPagePopupDriver. + * testing/InternalSettings.h: + (InternalSettings): Declare pagePopupController() for Internals::pagePopupController(). + * testing/Internals.cpp: + (WebCore::Internals::pagePopupController): + Added. This uses InternalSettings::pagePopupController(). + * testing/Internals.h: + (Internals): Declare pagePopupController() for Internals.idl. + * testing/Internals.idl: Declare pagePopupController. + + * testing/MockPagePopupDriver.cpp: + Moved m_pagePopupController from MockPagePopup to MockPagePopupDriver. + (WebCore::MockPagePopup::MockPagePopup): + Added a script element to prepare window.pagePopupController. + Removed a callsite of injectPagePopupController(). + (WebCore::MockPagePopupDriver::openPagePopup): + (WebCore::MockPagePopupDriver::closePagePopup): + * testing/MockPagePopupDriver.h: + (WebCore::MockPagePopupDriver::pagePopupController): + Accessor for a PagePopupController object. + (MockPagePopupDriver): Add RefPtr<PagePopupController> data member. + + * testing/v8/WebCoreTestSupport.cpp: Remove injectPagePopupController(). + * testing/v8/WebCoreTestSupport.h: ditto. + +2012-07-17 Ryuan Choi <ryuan.choi@samsung.com> + + [EFL] Move codes related to theme setting from Widget to RenderTheme + https://bugs.webkit.org/show_bug.cgi?id=89842 + + Reviewed by Kenneth Rohde Christiansen. + + WebKit/Efl uses custom theme for Scrollbar, RenderTheme and Cursor. + However, theme information itself is in WidgetEfl so it is accessed by + calling recursive function. + Because theme is managed by each page, this patch moves codes related to + theme from WidgetEfl to RenderThemeEfl which is contained by page. + + * platform/Widget.h: Removed functions related to theme. + * platform/efl/RenderThemeEfl.cpp: + (WebCore::RenderThemeEfl::setThemePath): Added to set theme path. + (WebCore::RenderThemeEfl::createEdje): Updated method to use RenderThemeEfl's theme. + (WebCore::RenderThemeEfl::RenderThemeEfl): + * platform/efl/RenderThemeEfl.h: + (WebCore::RenderThemeEfl::themePath): Added to get theme path + * platform/efl/ScrollbarEfl.cpp: Updated method to use RenderThemeEfl's theme. + (ScrollbarEfl::setParent): + * platform/efl/WidgetEfl.cpp: Removed codes related theme. + (WidgetPrivate): + +2012-07-17 Shinya Kawanaka <shinyak@chromium.org> + + HTMLMediaElement should not use Element::ensureShadowRoot() + https://bugs.webkit.org/show_bug.cgi?id=77936 + + Reviewed by Hajime Morita. + + a video element and an audio element add UserAgentShadowRoot dynamically, and they assume that it's the oldest ShadowRoot. + However an AuthorShadowRoot could be added by a user before a video element and an audio element add UserAgentShadowRoot. + It breaks the assumption that the UserAgentShadowRoot is the oldest. + + If the UserAgentShadowRoot is not the oldest, the AuthorShadowRoot a page author added might be ignored. + Since the timing to add UserAgentShadowRoot is not known by a user, the fact that UserAgentShadorRoot is + not the oldest will cause inconsistent behavior. + + Adding AuthorShadowRoot to a video element and an audio element is allowed by this patch. + + Test: fast/dom/shadow/shadowdom-for-media.html + + * dom/ShadowRoot.cpp: + (WebCore::allowsAuthorShadowRoot): + * html/HTMLMediaElement.cpp: + (WebCore::HTMLMediaElement::createShadowSubtree): + (WebCore): + (WebCore::HTMLMediaElement::willAddAuthorShadowRoot): + (WebCore::HTMLMediaElement::createMediaControls): + * html/HTMLMediaElement.h: + (HTMLMediaElement): + +2012-07-16 Daniel Bates <dbates@webkit.org> + + Attempt to fix the Chromium Mac build after <http://trac.webkit.org/changeset/122802> + (https://bugs.webkit.org/show_bug.cgi?id=91451) + + Remove unused private instance variable AbsoluteQuadsGeneratorContext::m_wasFixed. + This instance variable has remained unused since it was added in + <http://trac.webkit.org/changeset/116718> (https://bugs.webkit.org/show_bug.cgi?id=85725). + + I'm unclear as to why the Chromium Mac build began to complain about this + unused instance variable following <http://trac.webkit.org/changeset/122802>, since this + code has been in the tree for a while and we previously instantiated AbsoluteQuadsGeneratorContext + with wasFixed (even though it wasn't used). Regardless, we should remove the unused + instance variable AbsoluteQuadsGeneratorContext::m_wasFixed. + + * rendering/RenderInline.cpp: + (WebCore): Remove AbsoluteQuadsGeneratorContext::m_wasFixed. + (WebCore::RenderInline::absoluteQuads): + +2012-07-16 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Add RegisterProtocolHandlerClient to the Modules/protocolhandler + https://bugs.webkit.org/show_bug.cgi?id=90940 + + Reviewed by Hajime Morita. + + As a step to let protocol handler be moved to the modules, RegisterProtocolHandlerClient needs + to be added to the Modules/protocolhandler. Because ChromeClient has some virtual functions for + protocol handlers, virtual functions should be moved to RegisterProtocolHandlerClient. + + In addition, NavigatorRegisterProtocolHandler should be supplementable. + + No new tests. Covered by existing tests. + + * GNUmakefile.list.am: + * Modules/protocolhandler/NavigatorRegisterProtocolHandler.cpp: + (WebCore::NavigatorRegisterProtocolHandler::from): + (WebCore::NavigatorRegisterProtocolHandler::create): + (WebCore): + (WebCore::NavigatorRegisterProtocolHandler::registerProtocolHandler): + (WebCore::customHandlersStateString): + (WebCore::NavigatorRegisterProtocolHandler::isProtocolHandlerRegistered): + (WebCore::NavigatorRegisterProtocolHandler::unregisterProtocolHandler): + (WebCore::NavigatorRegisterProtocolHandler::supplementName): + (WebCore::provideRegisterProtocolHandlerTo): + * Modules/protocolhandler/NavigatorRegisterProtocolHandler.h: + (WebCore): + (NavigatorRegisterProtocolHandler): + (WebCore::NavigatorRegisterProtocolHandler::NavigatorRegisterProtocolHandler): + (WebCore::NavigatorRegisterProtocolHandler::client): + * Modules/protocolhandler/RegisterProtocolHandlerClient.h: Added. + (WebCore): + (RegisterProtocolHandlerClient): + * WebCore.gypi: + * loader/EmptyClients.h: + * page/ChromeClient.h: + (ChromeClient): + * platform/network/soup/CookieJarSoup.cpp: + (WebCore::setCookies): + (WebCore::getRawCookies): + +2012-07-16 Pete Williamson <petewil@google.com> + + Changed the behavior of iconURLs to always recalculate the list. + https://bugs.webkit.org/show_bug.cgi?id=88665 + + Reviewed by Kent Tamura. + + As it turns out, it can contain stale URLs in the case that some script + manipulates the DOM, which breaks scripts trying to reset the favicon + URL. Also added a method in Internals to allow tests to get the list of + icon + + Tests: fast/dom/icon-url-change.html + fast/dom/icon-url-list.html + + * WebCore.exp.in: export Document::iconURLs on the mac for the Internals class + * dom/Document.cpp: + (WebCore::Document::iconURLs): Changed the method to recalculate the iconURL list every time + (WebCore::Document::addIconURL): we no longer need to add to the internal list since we recalculate it + (WebCore::Document::setUseSecureKeyboardEntryWhenActive): removed extra whitespace + * dom/Document.h: + (Document): removed the addIconURL method which is no longer used + * html/HTMLLinkElement.cpp: + (WebCore::HTMLLinkElement::iconType): exposed the icon type with an accessor + (WebCore): + (WebCore::HTMLLinkElement::iconSizes): exposed the icon sizes with an accessor + * html/HTMLLinkElement.h: + (HTMLLinkElement): declared the icon type and size accessors + * testing/Internals.cpp: + (WebCore::Internals::iconURLs): made a method to be used by unit tests for inspecting the icon URL list + (WebCore): + * testing/Internals.h: + (Internals): declared the method for unit testing the icon URL list + * testing/Internals.idl: exported the Document::iconURLs function + +2012-07-16 Hajime Morrita <morrita@chromium.org> + + WebCore needs WEBCORE_TESTING macro to mark methods being exported for testing. + https://bugs.webkit.org/show_bug.cgi?id=90764 + + Reviewed by Adam Barth. + + Defined WEBCORE_TESTING based on USE(EXPORT_MACROS_FOR_TESTING) and + applied it to FrameDestructionObserver. + + * bindings/js/JSDOMGlobalObject.h: Removed conflicting symbols + * page/FrameDestructionObserver.h: Added WEBKIT_TESTING + (FrameDestructionObserver): + * platform/PlatformExportMacros.h: + +2012-07-16 Kiran Muppala <cmuppala@apple.com> + + REGRESSION: RenderInline::absoluteQuads produces incorrect results for fixed position. + https://bugs.webkit.org/show_bug.cgi?id=91451 + + Reviewed by Simon Fraser. + + RenderInline::absoluteQuads relies on copies of RenderGeometryMap, + created indirectly by passing AbsoluteQuadsGeneratorContext object by + value. These copies are unsafe because the individual transform steps + within the geometry map include a owned poitner to their respective + transform. + + Modify the callee methods to take context by reference and disable + copy constructor for RenderGeometryMap. + + Test: fast/inline/inline-fixed-position-boundingbox.html + + * rendering/RenderGeometryMap.h: + (WebCore::RenderGeometryMapStep::RenderGeometryMapStep): Add missing + m_offset to copy constructor initialization list. + (RenderGeometryMap): Disable copy constructor. + * rendering/RenderInline.cpp: Pass context object by reference. + (WebCore::RenderInline::generateLineBoxRects): + (WebCore::RenderInline::generateCulledLineBoxRects): + (WebCore::RenderInline::absoluteRects): + (WebCore::RenderInline::absoluteQuads): + (WebCore::RenderInline::linesBoundingBox): + (WebCore::RenderInline::culledInlineVisualOverflowBoundingBox): + (WebCore::RenderInline::addFocusRingRects): + * rendering/RenderInline.h: + (RenderInline::generateLineBoxRects): Update method declarations to + show pass by reference context parameter. + (RenderInline::generateCulledLineBoxRects): Ditto. + +2012-07-16 Hayato Ito <hayato@chromium.org> + + Some events should be always stopped at shadow boundary. + https://bugs.webkit.org/show_bug.cgi?id=90436 + + Reviewed by Ryosuke Niwa. + + The spec is here: + https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#events-that-are-always-stopped + + Test: fast/dom/shadow/events-stopped-at-shadow-boundary.html + + * dom/EventDispatcher.cpp: + (WebCore::EventDispatcher::determineDispatchBehavior): + +2012-07-16 Yoshifumi Inoue <yosin@chromium.org> + + REGRESSION(r119948): [Form] HTMLInputElement.valueAsNumber for input type "month" should return number of month since January 1970 + https://bugs.webkit.org/show_bug.cgi?id=91211 + + Reviewed by Kent Tamura. + + This patch changes BaseDateAndTimeInputType::valueAsDouble() to call + virtual function parseToNumber() which "month" input type overrides + instead of non-virtual function parseToDouble() which returns number + of milliseconds. + + No new tests. Existing test (fast/form/month/input-valueasnumber-month.html) coverts this, although it is disabled. + + * html/BaseDateAndTimeInputType.cpp: + (WebCore::BaseDateAndTimeInputType::valueAsDouble): Changed to call parseToNumber(). + (WebCore::BaseDateAndTimeInputType::parseToNumber): Changed to what parseToDouble() did. + * html/BaseDateAndTimeInputType.h: + (BaseDateAndTimeInputType): Remove parseToDouble(). + +2012-07-16 Adrienne Walker <enne@google.com> + + [chromium] Turn off ScrollbarLayerChromium for Windows due to bad alpha values + https://bugs.webkit.org/show_bug.cgi?id=91438 + + Reviewed by Kenneth Russell. + + r120509 turned on blending for scrollbar thumbs. Unfortunately for + Windows XP scrollbar thumbs, their alpha channel is bogus and so the + thumb ends up being completely transparent. This should ultimately be + fixed in Chromium theme code, but in the meantime this patch turns + off the use of ScrollbarLayerChromium. + + This change makes Windows scrollbars fall back to using normal + ContentLayerChromiums and being painted all in one layer on the main + thread rather than being painted separately and composited on the + compositor thread. + + * page/scrolling/chromium/ScrollingCoordinatorChromium.cpp: + (WebCore::createScrollbarLayer): + +2012-07-16 Koji Ishii <kojiishi@gmail.com> + + Vertical alternate glyph (GSUB) support for OpenTypeVerticalData + https://bugs.webkit.org/show_bug.cgi?id=81389 + + Reviewed by Tony Chang. + + This patch adds support for reading 'GSUB' OpenType table to get + vertical alternate glyphs. + http://www.microsoft.com/typography/otspec/gsub.htm + + Like bug 81326, this code isn't on any code path yet. + + Tests: WebKit/chromium/tests/OpenTypeVerticalDataTest.cpp + + * platform/graphics/opentype/OpenTypeTypes.h: + (WebCore::OpenType::validateTable): Moved from OpenTypeVerticalData.cpp for unit tests. + (OpenType): + (TableBase): Ditto. + (WebCore::OpenType::TableBase::isValidEnd): + (WebCore::OpenType::TableBase::validatePtr): + (WebCore::OpenType::TableBase::validateOffset): + * platform/graphics/opentype/OpenTypeVerticalData.cpp: + (OpenType): Added several OpenType tables used by 'GSUB' table. + (CoverageTable): + (Coverage1Table): + (Coverage2Table): + (RangeRecord): + (SubstitutionSubTable): + (WebCore::OpenType::SubstitutionSubTable::coverage): + (SingleSubstitution2SubTable): + (LookupTable): + (WebCore::OpenType::LookupTable::getSubstitutions): + (LookupList): + (WebCore::OpenType::LookupList::lookup): + (FeatureTable): + (WebCore::OpenType::FeatureTable::getGlyphSubstitutions): + (FeatureList): + (FeatureRecord): + (WebCore::OpenType::FeatureList::feature): + (LangSysTable): + (WebCore::OpenType::LangSysTable::feature): + (ScriptTable): + (LangSysRecord): + (WebCore::OpenType::ScriptTable::defaultLangSys): + (ScriptList): + (ScriptRecord): + (WebCore::OpenType::ScriptList::script): + (WebCore::OpenType::ScriptList::defaultScript): + (WebCore::OpenType::ScriptList::defaultLangSys): + (GSUBTable): + (WebCore::OpenType::GSUBTable::scriptList): + (WebCore::OpenType::GSUBTable::featureList): + (WebCore::OpenType::GSUBTable::lookupList): + (WebCore::OpenType::GSUBTable::defaultLangSys): + (WebCore::OpenType::GSUBTable::feature): + (WebCore::OpenType::GSUBTable::getVerticalGlyphSubstitutions): + (WebCore::OpenTypeVerticalData::OpenTypeVerticalData): + (WebCore::OpenTypeVerticalData::loadMetrics): Split code to load metrics from ctor. + (WebCore::OpenTypeVerticalData::loadVerticalGlyphSubstitutions): Load the vertical alternate Glyph substitution table. + (WebCore): + (WebCore::OpenTypeVerticalData::substituteWithVerticalGlyphs): Substitute Glyph IDs with vertical alternate Glyph IDs. + * platform/graphics/opentype/OpenTypeVerticalData.h: + (OpenTypeVerticalData): Added m_verticalGlyphMap. + +2012-07-16 Vincent Scheib <scheib@chromium.org> + + Fix spelling of EnforceIFrameAllowFullScreenRequirement and ExemptIFrameAllowFullScreenRequirement. + https://bugs.webkit.org/show_bug.cgi?id=91437 + + Reviewed by Adrienne Walker. + + Document contained spelling errors of 'FulScreen' instead of 'FullScreen' + for the FullScreenCheckType enumeration. + + No test changes needed. + + * dom/Document.cpp: + (WebCore::Document::requestFullScreenForElement): + * dom/Document.h: + * dom/Element.cpp: + (WebCore::Element::webkitRequestFullscreen): + (WebCore::Element::webkitRequestFullScreen): + * html/HTMLMediaElement.cpp: + (WebCore::HTMLMediaElement::enterFullscreen): + * html/shadow/MediaControlElements.cpp: + (WebCore::MediaControlFullscreenButtonElement::defaultEventHandler): + +2012-07-16 MORITA Hajime <morrita@google.com> + + Comment on WebCore::HTMLMediaElement::childShouldCreateRenderer() should explain why + https://bugs.webkit.org/show_bug.cgi?id=91174 + + Reviewed by Kent Tamura. + + Clarified the explanation. + + * html/HTMLMediaElement.cpp: + (WebCore::HTMLMediaElement::childShouldCreateRenderer): + +2012-07-16 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r120033. + http://trac.webkit.org/changeset/120033 + https://bugs.webkit.org/show_bug.cgi?id=91454 + + Broke background gradients (Requested by smfr on #webkit). + + * platform/graphics/GeneratorGeneratedImage.cpp: + (WebCore::GeneratorGeneratedImage::draw): + +2012-07-16 Joshua Bell <jsbell@chromium.org> + + IndexedDB: Implement spec updates to IDBTransaction.error + https://bugs.webkit.org/show_bug.cgi?id=91409 + + Reviewed by Tony Chang. + + The Indexed DB spec was updated to resolve some edge cases around the + IDBTransaction.error attribute. It was agreed that accessing error should + never throw, error should be null if the transaction is not finished or + abort() was explicitly called, an appropriate error should be returned if + a commit failed, and a generic AbortError should be used if a request + callback throws. These cases are now handled per spec, except that a reason + is not provided for the commit failure (it's always UnknownError). + + Test: storage/indexeddb/transaction-error.html + storage/indexeddb/transaction-abort.html + + * Modules/indexeddb/IDBRequest.cpp: + (WebCore::IDBRequest::dispatchEvent): Refactor some nested if() blocks; don't + re-abort the transaction if dispatching in response to an abort. + (WebCore::IDBRequest::uncaughtExceptionInEventHandler): Abort transaction + only if not already aborting, and set it's error to AbortError. + * Modules/indexeddb/IDBTransaction.cpp: + (WebCore::IDBTransaction::onAbort): Set error if abort triggered by back end. + * Modules/indexeddb/IDBTransaction.h: + (WebCore::IDBTransaction::db): Move impl to header file. + (WebCore::IDBTransaction::error): Move impl to header file, simplify. + (IDBTransaction): + * Modules/indexeddb/IDBTransaction.idl: The error attribute no longer throws. + +2012-07-16 Joshua Bell <jsbell@chromium.org> + + IndexedDB: Implement spec updates to IDBTransaction.error + https://bugs.webkit.org/show_bug.cgi?id=91409 + + Reviewed by Tony Chang. + + The Indexed DB spec was updated to resolve some edge cases around the + IDBTransaction.error attribute. It was agreed that accessing error should + never throw, error should be null if the transaction is not finished or + abort() was explicitly called, an appropriate error should be returned if + a commit failed, and a generic AbortError should be used if a request + callback throws. These cases are now handled per spec, except that a reason + is not provided for the commit failure (it's always UnknownError). + + Test: storage/indexeddb/transaction-error.html + storage/indexeddb/transaction-abort.html + + * Modules/indexeddb/IDBRequest.cpp: + (WebCore::IDBRequest::dispatchEvent): Refactor some nested if() blocks; don't + re-abort the transaction if dispatching in response to an abort. + (WebCore::IDBRequest::uncaughtExceptionInEventHandler): Abort transaction + only if not already aborting, and set it's error to AbortError. + * Modules/indexeddb/IDBTransaction.cpp: + (WebCore::IDBTransaction::onAbort): Set error if abort triggered by back end. + * Modules/indexeddb/IDBTransaction.h: + (WebCore::IDBTransaction::db): Move impl to header file. + (WebCore::IDBTransaction::error): Move impl to header file, simplify. + (IDBTransaction): + * Modules/indexeddb/IDBTransaction.idl: The error attribute no longer throws. + +2012-07-16 Alec Flett <alecflett@chromium.org> + + IndexedDB: Introduce putWithIndexKeys and calculate them in the renderer + https://bugs.webkit.org/show_bug.cgi?id=90923 + + Reviewed by Darin Fisher. + + Refactor IndexWriter to depend only on IDBIndexMetadata and on + (databaseId, objectStoreId, indexId) so that it can talk directly + to the backing store, and also eventually be moved into the renderer. + + This also introduces IDBObjectStoreBackendInterface::putWithIndexKeys + as a replacement for IDBObjectStoreBackendInterface::put, already + stubbed out in the chromium port. It will fully replace put() + after both chromium and webkit sides have reached alignment. + + No new tests as this is just a refactor and existing tests cover + correctness. + + * Modules/indexeddb/IDBCursor.cpp: + (WebCore::IDBCursor::setValueReady): + * Modules/indexeddb/IDBIndexBackendImpl.cpp: + * Modules/indexeddb/IDBIndexBackendImpl.h: + * Modules/indexeddb/IDBObjectStore.h: + (IDBObjectStore): + * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp: + (WebCore::IDBObjectStoreBackendImpl::put): + (WebCore): + (WebCore::IDBObjectStoreBackendImpl::putWithIndexKeys): + (WebCore::IDBObjectStoreBackendImpl::putInternal): + (WebCore::IDBObjectStoreBackendImpl::populateIndex): + * Modules/indexeddb/IDBObjectStoreBackendImpl.h: + (IDBObjectStoreBackendImpl): + * Modules/indexeddb/IDBObjectStoreBackendInterface.h: + * Modules/indexeddb/IDBRequest.cpp: + (WebCore::IDBRequest::onSuccess): + +2012-07-16 Adrienne Walker <enne@google.com> + + [chromium] Unify compositor quad transforms into content space + https://bugs.webkit.org/show_bug.cgi?id=91350 + + Reviewed by Kenneth Russell. + + For the purpose of simplification and as a first step towards removing + any transform that takes a centered rect, remove the ability of layers + to override the quad transform. All quads and quad transforms operate + on content space with the origin in the top left. + + The gutter quads used to use the root layer (that doesn't draw + content) as the layer to create the shared quad state from. This is + now created manually as a layer without bounds should never in general + need a shared quad state created for it. + + No change in functionality; tested by existing layout and unit tests. + + * platform/graphics/chromium/cc/CCIOSurfaceLayerImpl.cpp: + (WebCore::CCIOSurfaceLayerImpl::appendQuads): + * platform/graphics/chromium/cc/CCLayerImpl.cpp: + (WebCore::CCLayerImpl::createSharedQuadState): + * platform/graphics/chromium/cc/CCLayerImpl.h: + (CCLayerImpl): + * platform/graphics/chromium/cc/CCRenderPass.cpp: + (WebCore::CCRenderPass::appendQuadsToFillScreen): + * platform/graphics/chromium/cc/CCSolidColorLayerImpl.cpp: + (WebCore::CCSolidColorLayerImpl::appendQuads): + * platform/graphics/chromium/cc/CCSolidColorLayerImpl.h: + (CCSolidColorLayerImpl): + * platform/graphics/chromium/cc/CCTextureLayerImpl.cpp: + (WebCore::CCTextureLayerImpl::appendQuads): + * platform/graphics/chromium/cc/CCTiledLayerImpl.cpp: + * platform/graphics/chromium/cc/CCTiledLayerImpl.h: + (CCTiledLayerImpl): + * platform/graphics/chromium/cc/CCVideoLayerImpl.cpp: + (WebCore::CCVideoLayerImpl::appendQuads): + +2012-07-16 Adrienne Walker <enne@google.com> + + [chromium] Unify compositor quad transforms into content space + https://bugs.webkit.org/show_bug.cgi?id=91350 + + Reviewed by Kenneth Russell. + + For the purpose of simplification and as a first step towards removing + any transform that takes a centered rect, remove the ability of layers + to override the quad transform. All quads and quad transforms operate + on content space with the origin in the top left. + + The gutter quads used to use the root layer (that doesn't draw + content) as the layer to create the shared quad state from. This is + now created manually as a layer without bounds should never in general + need a shared quad state created for it. + + No change in functionality; tested by existing layout and unit tests. + + * platform/graphics/chromium/cc/CCIOSurfaceLayerImpl.cpp: + (WebCore::CCIOSurfaceLayerImpl::appendQuads): + * platform/graphics/chromium/cc/CCLayerImpl.cpp: + (WebCore::CCLayerImpl::createSharedQuadState): + * platform/graphics/chromium/cc/CCLayerImpl.h: + (CCLayerImpl): + * platform/graphics/chromium/cc/CCRenderPass.cpp: + (WebCore::CCRenderPass::appendQuadsToFillScreen): + * platform/graphics/chromium/cc/CCSolidColorLayerImpl.cpp: + (WebCore::CCSolidColorLayerImpl::appendQuads): + * platform/graphics/chromium/cc/CCSolidColorLayerImpl.h: + (CCSolidColorLayerImpl): + * platform/graphics/chromium/cc/CCTextureLayerImpl.cpp: + (WebCore::CCTextureLayerImpl::appendQuads): + * platform/graphics/chromium/cc/CCTiledLayerImpl.cpp: + * platform/graphics/chromium/cc/CCTiledLayerImpl.h: + (CCTiledLayerImpl): + * platform/graphics/chromium/cc/CCVideoLayerImpl.cpp: + (WebCore::CCVideoLayerImpl::appendQuads): + +2012-07-16 Joshua Bell <jsbell@chromium.org> + + IndexedDB: Resolve test and IDL FIXMEs for a handful of landed patches + https://bugs.webkit.org/show_bug.cgi?id=91423 + + Reviewed by Tony Chang. + + IDBObjectStore.createIndex() had a hack to handle a null keyPath argument for the + DOMString[] overload and treat it as the string "null". Now that IDL arrays are not + nullable by default following r121817 this hack can be removed and the binding layer + will automagically coerce to DOMString. + + Test: storage/indexeddb/keypath-basics.html + + * Modules/indexeddb/IDBObjectStore.cpp: + (WebCore::IDBObjectStore::createIndex): Remove special case for null in DOMString[] overload. + * Modules/indexeddb/IDBObjectStore.idl: Remove Nullable suffix from DOMString[] overload + so that the DOMString overload will match null. + +2012-07-16 Bear Travis <betravis@adobe.com> + + Resolve CSS Exclusions shapeInside, shapeOutside properties to Length based WrapShape classes + https://bugs.webkit.org/show_bug.cgi?id=89670 + + Reviewed by Dirk Schulze. + + Layout of CSS Exclusions requires length based WrapShape classes, + rather than the existing CSSValue based CSSWrapShape classes. This + patch adds length based WrapShape analogs to the CSSWrapShapes, and + modifies RenderStyle to use a WrapShape instead of a CSSWrapShape. + The translation between WrapShape and CSSWrapShape classes + is handled by helper functions in the new WrapShapeFunctions files. + StyleBuilder resolves CSSWrapShapes to WrapShapes for layout use. + CSSComputedStyleDeclaration translates WrapShapes to CSSWrapShapes + for style use. + + There are existing tests that cover the style serialization / resolution + in fast/exclusions/parsing-wrap-shape-inside.html and + fast/exclusions/parsing/wrap-shape-outside.html + + Test: fast/exclusions/parsing-wrap-shape-lengths.html + + * CMakeLists.txt: Build system changes for adding new files + * GNUmakefile.list.am: Ditto + * Target.pri: Ditto + * WebCore.gypi: Ditto + * WebCore.vcproj/WebCore.vcproj: Ditto + * WebCore.xcodeproj/project.pbxproj: Ditto + * css/CSSComputedStyleDeclaration.cpp: Translate WrapShapes back to CSSWrapShapes + (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue): + * css/CSSWrapShapes.h: Mostly changing functions to be const + (WebCore::CSSWrapShapeRectangle::type): + (WebCore::CSSWrapShapeCircle::type): + (WebCore::CSSWrapShapeEllipse::type): + (WebCore::CSSWrapShapePolygon::getXAt): + (WebCore::CSSWrapShapePolygon::getYAt): + (WebCore::CSSWrapShapePolygon::values): + (WebCore::CSSWrapShapePolygon::type): + * css/StyleBuilder.cpp: Resolve CSSWrapShapes to WrapShapes + (WebCore): + (WebCore::ApplyPropertyWrapShape::setValue): + (WebCore::ApplyPropertyWrapShape::applyValue): + (WebCore::ApplyPropertyWrapShape::createHandler): + * css/WrapShapeFunctions.cpp: Added. + (WebCore): + (WebCore::valueForWrapShape): + (WebCore::convertToLength): + (WebCore::wrapShapeForValue): + * css/WrapShapeFunctions.h: Added. + (WebCore): + * rendering/style/RenderStyle.h: + * rendering/style/StyleRareNonInheritedData.h: + (StyleRareNonInheritedData): + * rendering/style/WrapShapes.h: Added. + (WebCore): + (WrapShape): + (WebCore::WrapShape::~WrapShape): + (WebCore::WrapShape::WrapShape): + (WrapShapeRectangle): + (WebCore::WrapShapeRectangle::create): + (WebCore::WrapShapeRectangle::left): + (WebCore::WrapShapeRectangle::top): + (WebCore::WrapShapeRectangle::width): + (WebCore::WrapShapeRectangle::height): + (WebCore::WrapShapeRectangle::cornerRadiusX): + (WebCore::WrapShapeRectangle::cornerRadiusY): + (WebCore::WrapShapeRectangle::setLeft): + (WebCore::WrapShapeRectangle::setTop): + (WebCore::WrapShapeRectangle::setWidth): + (WebCore::WrapShapeRectangle::setHeight): + (WebCore::WrapShapeRectangle::setCornerRadiusX): + (WebCore::WrapShapeRectangle::setCornerRadiusY): + (WebCore::WrapShapeRectangle::type): + (WebCore::WrapShapeRectangle::WrapShapeRectangle): + (WrapShapeCircle): + (WebCore::WrapShapeCircle::create): + (WebCore::WrapShapeCircle::left): + (WebCore::WrapShapeCircle::top): + (WebCore::WrapShapeCircle::radius): + (WebCore::WrapShapeCircle::setLeft): + (WebCore::WrapShapeCircle::setTop): + (WebCore::WrapShapeCircle::setRadius): + (WebCore::WrapShapeCircle::type): + (WebCore::WrapShapeCircle::WrapShapeCircle): + (WrapShapeEllipse): + (WebCore::WrapShapeEllipse::create): + (WebCore::WrapShapeEllipse::top): + (WebCore::WrapShapeEllipse::left): + (WebCore::WrapShapeEllipse::radiusX): + (WebCore::WrapShapeEllipse::radiusY): + (WebCore::WrapShapeEllipse::setTop): + (WebCore::WrapShapeEllipse::setLeft): + (WebCore::WrapShapeEllipse::setRadiusX): + (WebCore::WrapShapeEllipse::setRadiusY): + (WebCore::WrapShapeEllipse::type): + (WebCore::WrapShapeEllipse::WrapShapeEllipse): + (WrapShapePolygon): + (WebCore::WrapShapePolygon::create): + (WebCore::WrapShapePolygon::windRule): + (WebCore::WrapShapePolygon::values): + (WebCore::WrapShapePolygon::getXAt): + (WebCore::WrapShapePolygon::getYAt): + (WebCore::WrapShapePolygon::setWindRule): + (WebCore::WrapShapePolygon::appendPoint): + (WebCore::WrapShapePolygon::type): + (WebCore::WrapShapePolygon::WrapShapePolygon): + +2012-07-16 Simon Fraser <simon.fraser@apple.com> + + Fix compositing layers in columns when in paginated mode + https://bugs.webkit.org/show_bug.cgi?id=91425 + + Reviewed by Dave Hyatt. + + Enhance a hack that was added to allow composited layers to + display in columns to work for paginated mode, where the + RenderView is renderer with columns. + + Test: compositing/columns/composited-in-paginated.html + + * rendering/RenderLayer.cpp: + (WebCore::RenderLayer::updateLayerPosition): + +2012-07-16 Emil A Eklund <eae@chromium.org> + + Inconsistent rounding in table layout causes background color to bleed through + https://bugs.webkit.org/show_bug.cgi?id=91410 + + Reviewed by Eric Seidel. + + At certain zoom levels a rounding error in the table layout code cases + the table background color to bleed through between cells. Tables layout + happens on pixel bounds however the paint offset wasn't correctly rounded. + + Test: fast/sub-pixel/table-rows-no-gaps.html + + * rendering/RenderTable.cpp: + (WebCore::RenderTable::paintObject): + Round paintOffset before passing it to the paint method of the children. + +2012-07-16 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r122739. + http://trac.webkit.org/changeset/122739 + https://bugs.webkit.org/show_bug.cgi?id=91424 + + Broke mac builds (Requested by rniwa on #webkit). + + * inspector/CodeGeneratorInspector.py: + (flatten_list): + +2012-07-16 Dana Jansens <danakj@chromium.org> + + [chromium] Remove non-ephemeral data from RenderSurface as it duplicates data from the owning layer + https://bugs.webkit.org/show_bug.cgi?id=91418 + + Reviewed by Adrienne Walker. + + This removes the filters and masks from render surfaces, and makes them + used directly from the owning layer. Also removes skipsDraw from + surfaces as it was just not used at all. + + Covered by existing tests. + + * platform/graphics/chromium/LayerChromium.h: + (WebCore::LayerChromium::filters): + (WebCore::LayerChromium::backgroundFilters): + (WebCore::LayerChromium::hasMask): + (WebCore::LayerChromium::hasReplica): + (WebCore::LayerChromium::replicaHasMask): + (LayerChromium): + * platform/graphics/chromium/RenderSurfaceChromium.cpp: + (WebCore::RenderSurfaceChromium::RenderSurfaceChromium): + * platform/graphics/chromium/RenderSurfaceChromium.h: + (RenderSurfaceChromium): + * platform/graphics/chromium/cc/CCLayerImpl.h: + (WebCore::CCLayerImpl::hasMask): + (WebCore::CCLayerImpl::hasReplica): + (WebCore::CCLayerImpl::replicaHasMask): + (CCLayerImpl): + * platform/graphics/chromium/cc/CCLayerTreeHost.cpp: + (WebCore::CCLayerTreeHost::calculateMemoryForRenderSurfaces): + * platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp: + (WebCore::calculateDrawTransformsInternal): + * platform/graphics/chromium/cc/CCOcclusionTracker.cpp: + (WebCore::::finishedRenderTarget): + (WebCore::reduceOcclusionBelowSurface): + (WebCore::::leaveToRenderTarget): + * platform/graphics/chromium/cc/CCRenderPass.cpp: + (WebCore::CCRenderPass::appendQuadsForRenderSurfaceLayer): + * platform/graphics/chromium/cc/CCRenderSurface.cpp: + (WebCore::CCRenderSurface::drawableContentRect): + (WebCore::CCRenderSurface::appendQuads): + * platform/graphics/chromium/cc/CCRenderSurface.h: + (CCRenderSurface): + +2012-07-16 Beth Dakin <bdakin@apple.com> + + https://bugs.webkit.org/show_bug.cgi?id=91299 + Paginated views should restrict available height to column height + -and corresponding- + <rdar://problem/11152108> + + Reviewed by Dan Bernstein. + + Now that RenderViews can have columns, availableLogicalHeight needs to consider + that column height, much like how availableLogicalWidth already considers column + width. + + availableLogicalHeight is newly virtual, like the already-virtual + availableLogicalWidth. + * rendering/RenderBox.h: + (RenderBox): + + Check with the columnHeight. + * rendering/RenderView.cpp: + (WebCore): + (WebCore::RenderView::availableLogicalHeight): + * rendering/RenderView.h: + + setPagination now takes pageLength as an optional parameter. + * testing/InternalSettings.cpp: + (WebCore::InternalSettings::setPagination): + * testing/InternalSettings.h: + (WebCore::InternalSettings::setPagination): + (InternalSettings): + * testing/InternalSettings.idl: + * testing/Internals.cpp: + (WebCore::Internals::setPagination): + * testing/Internals.h: + (WebCore::Internals::setPagination): + (Internals): + * testing/Internals.idl: + +2012-07-16 Dana Jansens <danakj@chromium.org> + + [chromium] Remove targetRenderSurface concept, give layers a renderTarget which is the layer whose coordinate space they draw into + https://bugs.webkit.org/show_bug.cgi?id=91288 + + Reviewed by Adrienne Walker. + + Always use pointers to layers when discussing render targets instead of + pointing directly to a RenderSurface. + + Covered by existing tests. + + * platform/graphics/chromium/LayerChromium.cpp: + (WebCore::LayerChromium::LayerChromium): + (WebCore::LayerChromium::createRenderSurface): + * platform/graphics/chromium/LayerChromium.h: + (WebCore::LayerChromium::renderTarget): + (WebCore::LayerChromium::setRenderTarget): + (LayerChromium): + * platform/graphics/chromium/RenderSurfaceChromium.cpp: + * platform/graphics/chromium/RenderSurfaceChromium.h: + * platform/graphics/chromium/ScrollbarLayerChromium.cpp: + (WebCore::ScrollbarLayerChromium::setTexturePriorities): + * platform/graphics/chromium/TiledLayerChromium.cpp: + (WebCore::TiledLayerChromium::setTexturePrioritiesInRect): + * platform/graphics/chromium/cc/CCLayerImpl.cpp: + (WebCore::CCLayerImpl::CCLayerImpl): + (WebCore::CCLayerImpl::createRenderSurface): + (WebCore::CCLayerImpl::dumpLayerProperties): + * platform/graphics/chromium/cc/CCLayerImpl.h: + (WebCore::CCLayerImpl::renderTarget): + (WebCore::CCLayerImpl::setRenderTarget): + (CCLayerImpl): + * platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp: + (WebCore::calculateLayerScissorRect): + (WebCore::calculateSurfaceScissorRect): + (WebCore::calculateVisibleContentRect): + (WebCore::computeScrollCompensationForThisLayer): + (WebCore::calculateDrawTransformsInternal): + (WebCore::pointIsClippedBySurfaceOrClipRect): + * platform/graphics/chromium/cc/CCOcclusionTracker.cpp: + (WebCore::::enterLayer): + (WebCore::::leaveLayer): + (WebCore::::enterRenderTarget): + (WebCore::::finishedRenderTarget): + (WebCore): + (WebCore::reduceOcclusionBelowSurface): + (WebCore::::leaveToRenderTarget): + (WebCore::::markOccludedBehindLayer): + (WebCore::::occluded): + (WebCore::::unoccludedContentRect): + (WebCore::::unoccludedContributingSurfaceContentRect): + (WebCore::::layerScissorRectInTargetSurface): + * platform/graphics/chromium/cc/CCOcclusionTracker.h: + (CCOcclusionTrackerBase): + (WebCore::CCOcclusionTrackerBase::StackObject::StackObject): + (StackObject): + * platform/graphics/chromium/cc/CCQuadCuller.cpp: + (WebCore::CCQuadCuller::appendSurface): + * platform/graphics/chromium/cc/CCRenderSurface.cpp: + * platform/graphics/chromium/cc/CCRenderSurface.h: + (CCRenderSurface): + +2012-07-16 Florin Malita <fmalita@chromium.org> + + SVGAnimationElement::currentValuesForValuesAnimation crash + https://bugs.webkit.org/show_bug.cgi?id=91326 + + Reviewed by Simon Fraser. + + SVGSMILElement::progress() assumes that seekToIntervalCorrespondingToTime() always + lands inside a defined interval, but one can force arbitrary time offsets using + setCurrentTime(). This patch adds logic for handling non-interval time offsets + gracefully. + + Test: svg/animations/smil-setcurrenttime-crash.svg + + * svg/animation/SVGSMILElement.cpp: + (WebCore::SVGSMILElement::progress): + +2012-07-16 Joshua Netterfield <jnetterfield@rim.com> + + [BlackBerry] Upstream WebGL Code + https://bugs.webkit.org/show_bug.cgi?id=91143 + + Reviewed by Rob Buis. + + This patch includes BlackBerry-specific fixes for anti-aliasing, logging, and shader compilation. + + No new tests, because there is no new functionality. + + * platform/graphics/GraphicsContext3D.h: Add a value for TI Imagination chipsets on BlackBerry platforms + * platform/graphics/blackberry/GraphicsContext3DBlackBerry.cpp: Multiple downstream changes + (WebCore::GraphicsContext3D::GraphicsContext3D): + (WebCore::GraphicsContext3D::reshapeFBOs): + (WebCore): + (WebCore::GraphicsContext3D::logFrameBufferStatus): + (WebCore::GraphicsContext3D::readPixelsIMG): BlackBerry-specific fix for Imagination hardware. + (WebCore::GraphicsContext3D::paintsIntoCanvasBuffer): + (WebCore::GraphicsContext3D::platformTexture): + (WebCore::GraphicsContext3D::platformGraphicsContext3D): + (WebCore::GraphicsContext3D::paintToCanvas): + * platform/graphics/opengl/Extensions3DOpenGL.h: Remove unnecessary whitespace. + (Extensions3DOpenGL): + * platform/graphics/opengl/Extensions3DOpenGLCommon.cpp: + (WebCore::Extensions3DOpenGLCommon::getTranslatedShaderSourceANGLE): Hack to fix ANGLE-generated code on BlackBerry platforms. + * platform/graphics/opengl/Extensions3DOpenGLCommon.h: + (Extensions3DOpenGLCommon): + * platform/graphics/opengl/Extensions3DOpenGLES.cpp: I am not in a position to change system headers from correct to incorrect. + (WebCore::Extensions3DOpenGLES::renderbufferStorageMultisample): + (WebCore::Extensions3DOpenGLES::supportsExtension): + * platform/graphics/opengl/Extensions3DOpenGLES.h: I am not in a position to change system headers from correct to incorrect. + (Extensions3DOpenGLES): + * platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp: Add a BlackBerry-specific anti-aliasing fix. + (WebCore::GraphicsContext3D::paintRenderingResultsToCanvas): + (WebCore::GraphicsContext3D::prepareTexture): + (WebCore::GraphicsContext3D::bindFramebuffer): + (WebCore::GraphicsContext3D::compileShader): + (WebCore::GraphicsContext3D::copyTexImage2D): + (WebCore::GraphicsContext3D::copyTexSubImage2D): + (WebCore): + * platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp: + (WebCore): + +2012-07-16 Tony Chang <tony@chromium.org> + + Position grid items by row/column index + https://bugs.webkit.org/show_bug.cgi?id=91293 + + Reviewed by Ojan Vafai. + + Do some initial grid positioning. Only handle the simple case where tracks are + fixed values and don't properly size the grid items. This gives us something to + work with and starts implementing the "Grid Track Sizing Algorithm": + http://dev.w3.org/csswg/css3-grid-layout/#grid-track-sizing-algorithm0 + + Test: fast/css-grid-layout/place-cell-by-index.html + + * rendering/RenderGrid.cpp: + (RenderGrid::GridTrack): Data structure for holding the track size. UsedBreadth matches the terminology + used in the spec. + (WebCore::RenderGrid::layoutBlock): Pull in some boiler plate code and put the + grid specific code in layoutGridItems. + (WebCore::RenderGrid::computedUsedBreadthOfGridTracks): Implement part of the grid track sizing algorithm. + (WebCore::RenderGrid::layoutGridItems): Compute the size of grid tracks, layout and position children. + (WebCore::RenderGrid::findChildLogicalPosition): Map track sizes to the actual position of the child. + * rendering/RenderGrid.h: + * rendering/style/RenderStyle.h: Just return a copy of Length rather than a reference to Length. This seems + more consistent with other getters that return a Length. + +2012-07-16 Sami Kyostila <skyostil@chromium.org> + + [chromium] Only apply page scale delta to root scroll layer + https://bugs.webkit.org/show_bug.cgi?id=91374 + + Reviewed by Adrienne Walker. + + When the user pinch-zooms the web page though the Chromium compositor, the + per-layer page scale delta is used to keep track of the difference between the + page scale on the compositor thread versus the main thread. On the next + commit to the main thread these values are reset to 1. + + When calculating layer positions, the compositor applies a layer's page scale + delta both to the layer itself as well as all of its children. Since we are + currently updating the page scale delta on all scrollable layers, this results + in scrollable child layers getting scaled multiple times. + + This patch changes the compositor to only apply the page scale delta on the + root scroll layer. + + New unit test: CCLayerTreeHostImplTest.pageScaleDeltaAppliedToRootScrollLayerOnly + + * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp: + (WebCore::CCLayerTreeHostImpl::setPageScaleFactorAndLimits): + (WebCore::CCLayerTreeHostImpl::setPageScaleDelta): + +2012-07-16 Kihong Kwon <kihong.kwon@samsung.com> + + Remove setController from BatteryClient + https://bugs.webkit.org/show_bug.cgi?id=90944 + + Reviewed by Adam Barth. + + BatteryClient doesn't need to keep m_controller, + because BatteryController can be accessed using BatteryController::from(). + Remove BatteryClient::setController function. + + No new tests. Covered by existing tests. + + * Modules/battery/BatteryClient.h: + * Modules/battery/BatteryController.cpp: + (WebCore::BatteryController::BatteryController): + +2012-07-16 Mike West <mkwst@chromium.org> + + Invalid `script-nonce` directives should block script execution. + https://bugs.webkit.org/show_bug.cgi?id=91353 + + Reviewed by Adam Barth. + + If the `script-nonce` Content Security Policy directive contains an + invalid value, we should fail loudly, throwing a warning to the console + and denying execution of script on the page. The is in line with the + current state of the experimental CSP 1.1 Editors Draft[1]. + + [1]: https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#script-nonce--experimental + + Test: http/tests/security/contentSecurityPolicy/1.1/scriptnonce-invalidnonce.html + + * page/ContentSecurityPolicy.cpp: + (WebCore::CSPDirectiveList::checkNonceAndReportViolation): + Check against null rather than empty for early exit, otherwise + only compare nonces if the stored nonce isn't empty. + (WebCore::CSPDirectiveList::parseScriptNonce): + Assign the empty string if nonce is invalid. + +2012-07-16 Min Qin <qinmin@chromium.org> + + [Android] remove RenderThemeChromiumAndroid::paintMediaFullscreenButton() + https://bugs.webkit.org/show_bug.cgi?id=91291 + + Reviewed by Adam Barth. + + The recent media control refactoring added paintMediaFullscreenButton() in RenderThemeChromiumSkia. + Since RenderThemeChromiumAndroid inherits from that class, we don't need to redefine this function. + No test needed as this change just removes an unnecessary override. + + * rendering/RenderThemeChromiumAndroid.cpp: + * rendering/RenderThemeChromiumAndroid.h: + +2012-07-16 Peter Rybin <peter.rybin@gmail.com> + + Web Inspector: CodeGeneratorInspector.py: fix output write logic to support incremental build + https://bugs.webkit.org/show_bug.cgi?id=90642 + + Reviewed by Yury Semikhatsky. + + A small intermediate writer is added. It handles comparing old and new source before actual writing. + + * inspector/CodeGeneratorInspector.py: + (flatten_list): + (SmartOutput): + (SmartOutput.__init__): + (SmartOutput.write): + (SmartOutput.close): + +2012-07-16 Dana Jansens <danakj@chromium.org> + + [chromium] Incorrect assertion: Replicas will cause a RenderPass to be removed twice + https://bugs.webkit.org/show_bug.cgi?id=91328 + + Reviewed by Adrienne Walker. + + We asserted that we would never attempt to remove a render pass that had + already been removed. This was incorrect as a surface with a replica has + two quads and both may cause us to attempt its removal. We must handle + this case gracefully. + + Test: CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit + + * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp: + (WebCore::CCLayerTreeHostImpl::CullRenderPassesWithNoQuads::shouldRemoveRenderPass): + +2012-07-16 Ilya Tikhonovsky <loislo@chromium.org> + + Web Inspector: native memory: fix instrumentation for string members + https://bugs.webkit.org/show_bug.cgi?id=91384 + + Reviewed by Pavel Feldman. + + It was possible to report a string member via addMember instead of addString. + This patch is fixing the problem and adding a link time guard. + + Covered by existing inspector performance tests infrastructure. + + * dom/ElementAttributeData.h: + (WebCore::ElementAttributeData::reportMemoryUsage): + * dom/MemoryInstrumentation.h: + (WebCore): + (WebCore::MemoryClassInfo::addString): + * dom/QualifiedName.h: + (WebCore::QualifiedName::QualifiedNameImpl::reportMemoryUsage): + +2012-07-16 Zoltan Horvath <zoltan@webkit.org> + + Unreviewed. Remove unnecessary executable bits after r122720. + + * platform/graphics/ImageSource.h: + * platform/graphics/qt/ImageBufferQt.cpp: + * platform/graphics/qt/ImageDecoderQt.cpp: + * platform/graphics/qt/ImageQt.cpp: + * platform/graphics/qt/StillImageQt.h: + * platform/graphics/qt/TransparencyLayer.h: + +2012-07-16 Zoltan Horvath <zoltan@webkit.org> + + [Qt] Change NativeImagePtr from QPixmap* to QImage* + https://bugs.webkit.org/show_bug.cgi?id=88785 + + Reviewed by Simon Hausmann. + + Since we use raster engine there is no difference between QPixmap and QImage, so we are going + to use QImage everywhere where it is possible. This refactoring contains the change of the + NativeImagePtr typedef from QPixmap* to QImage* and covers the related modifications. + + Part of the change is similar to Viatcheslav Ostapenko's internal work. + + Covered by existing tests. + + * bridge/qt/qt_pixmapruntime.cpp: + (JSC::Bindings::QtPixmapAssignToElementMethod::invoke): + (JSC::Bindings::QtPixmapInstance::variantFromObject): + * platform/DragImage.h: + (WebCore): + * platform/graphics/GraphicsContext.h: + (GraphicsContext): + * platform/graphics/Image.h: + (Image): + * platform/graphics/ImageSource.h: + (WebCore): + * platform/graphics/gstreamer/ImageGStreamer.h: + * platform/graphics/gstreamer/ImageGStreamerQt.cpp: + (ImageGStreamer::ImageGStreamer): + * platform/graphics/qt/GraphicsContext3DQt.cpp: + (WebCore::GraphicsContext3D::getImageData): + * platform/graphics/qt/GraphicsContextQt.cpp: + (WebCore::GraphicsContext::pushTransparencyLayerInternal): + (WebCore::GraphicsContext::beginPlatformTransparencyLayer): + (WebCore::GraphicsContext::endPlatformTransparencyLayer): + * platform/graphics/qt/ImageBufferDataQt.h: + (ImageBufferData): + * platform/graphics/qt/ImageBufferQt.cpp: + (WebCore::ImageBufferData::ImageBufferData): + (WebCore::ImageBuffer::copyImage): + (WebCore::ImageBuffer::clip): + (WebCore::ImageBuffer::platformTransformColorSpace): + (WebCore::getImageData): + (WebCore::ImageBuffer::putByteArray): + (WebCore::encodeImage): + (WebCore::ImageBuffer::toDataURL): + * platform/graphics/qt/ImageDecoderQt.cpp: + (WebCore::ImageFrame::asNewNativeImage): + * platform/graphics/qt/ImageQt.cpp: + (graphics): + (loadResourceImage): + (WebCore::Image::loadPlatformResource): + (WebCore::Image::setPlatformResource): + (WebCore::Image::drawPattern): + (WebCore::BitmapImage::BitmapImage): + (WebCore::BitmapImage::draw): + (WebCore::BitmapImage::checkForSolidColor): + (WebCore::BitmapImage::create): + * platform/graphics/qt/NativeImageQt.h: Added. + (WebCore): + (NativeImageQt): + (WebCore::NativeImageQt::defaultFormatForAlphaEnabledImages): + (WebCore::NativeImageQt::defaultFormatForOpaqueImages): + * platform/graphics/qt/PatternQt.cpp: + (WebCore::Pattern::createPlatformPattern): + * platform/graphics/qt/StillImageQt.cpp: + (WebCore::StillImage::StillImage): + (WebCore::StillImage::~StillImage): + (WebCore::StillImage::currentFrameHasAlpha): + (WebCore::StillImage::size): + (WebCore::StillImage::nativeImageForCurrentFrame): + (WebCore::StillImage::draw): + * platform/graphics/qt/StillImageQt.h: + (WebCore::StillImage::create): + (WebCore::StillImage::createForRendering): + (StillImage): + * platform/graphics/qt/TransparencyLayer.h: + (WebCore::TransparencyLayer::TransparencyLayer): + (TransparencyLayer): + * platform/graphics/texmap/TextureMapperGL.cpp: + * platform/graphics/surfaces/qt/GraphicsSurfaceQt.cpp: + (WebCore::GraphicsSurface::createReadOnlyImage): + * platform/qt/ClipboardQt.cpp: + (WebCore::ClipboardQt::createDragImage): + (WebCore::ClipboardQt::declareAndWriteDragImage): + * platform/qt/CursorQt.cpp: + (WebCore::createCustomCursor): + * platform/qt/DragImageQt.cpp: + (WebCore::createDragImageFromImage): + * platform/qt/PasteboardQt.cpp: + (WebCore::Pasteboard::writeImage): + +2012-07-16 Ilya Tikhonovsky <loislo@chromium.org> + + Web Inspector: moving forward to the better memory instrumentation API + https://bugs.webkit.org/show_bug.cgi?id=91259 + + Reviewed by Pavel Feldman. + + I'm trying to remove unnecessary complexity of the API + reportInstrumentedObject and reportInstrumentedPointer will be replaced with addInstrumentedMember + The same will happen with reportPointer, reportObject pair. + Also info.report* will be replaced with info.add* + + * bindings/js/ScriptWrappable.h: + (WebCore::ScriptWrappable::reportMemoryUsage): + * bindings/v8/DOMDataStore.cpp: + (WebCore::DOMDataStore::reportMemoryUsage): + * bindings/v8/IntrusiveDOMWrapperMap.h: + (WebCore::ChunkedTable::reportMemoryUsage): + * bindings/v8/ScriptProfiler.cpp: + (WebCore::ScriptProfiler::collectBindingMemoryInfo): + * bindings/v8/ScriptWrappable.h: + (WebCore::ScriptWrappable::reportMemoryUsage): + * bindings/v8/V8Binding.cpp: + (WebCore::V8BindingPerIsolateData::reportMemoryUsage): + (WebCore::StringCache::reportMemoryUsage): + * bindings/v8/V8DOMMap.h: + * css/StylePropertySet.h: + (WebCore::StylePropertySet::reportMemoryUsage): + * dom/CharacterData.cpp: + (WebCore::CharacterData::reportMemoryUsage): + * dom/ContainerNode.h: + (WebCore::ContainerNode::reportMemoryUsage): + * dom/Document.cpp: + (WebCore::Document::reportMemoryUsage): + * dom/Element.h: + (WebCore::Element::reportMemoryUsage): + * dom/ElementAttributeData.h: + (WebCore::ElementAttributeData::reportMemoryUsage): + * dom/MemoryInstrumentation.h: + (WebCore::MemoryInstrumentation::addInstrumentedMember): + (MemoryInstrumentation): + (WebCore::MemoryInstrumentation::addMember): + (WebCore::MemoryInstrumentation::OwningTraits::addInstrumentedMember): + (WebCore::MemoryInstrumentation::OwningTraits::addMember): + (WebCore::MemoryInstrumentation::addInstrumentedMemberImpl): + (WebCore::MemoryInstrumentation::addMemberImpl): + (WebCore::MemoryClassInfo::addInstrumentedMember): + (WebCore::MemoryClassInfo::addMember): + (WebCore::MemoryClassInfo::addHashMap): + (WebCore::MemoryClassInfo::addHashSet): + (WebCore::MemoryClassInfo::addListHashSet): + (WebCore::MemoryClassInfo::addVector): + (WebCore::MemoryClassInfo::addString): + (WebCore::MemoryInstrumentation::addHashMap): + (WebCore::MemoryInstrumentation::addHashSet): + (WebCore::MemoryInstrumentation::addListHashSet): + (WebCore::MemoryInstrumentation::addVector): + * dom/Node.cpp: + (WebCore::Node::reportMemoryUsage): + * dom/QualifiedName.h: + (WebCore::QualifiedName::QualifiedNameImpl::reportMemoryUsage): + (WebCore::QualifiedName::reportMemoryUsage): + * inspector/InspectorMemoryAgent.cpp: + (WebCore): + * platform/TreeShared.h: + (WebCore::TreeShared::reportMemoryUsage): + +2012-07-16 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r122714. + http://trac.webkit.org/changeset/122714 + https://bugs.webkit.org/show_bug.cgi?id=91380 + + It broke mac compilation (Requested by loislo on #webkit). + + * bindings/js/ScriptWrappable.h: + (WebCore::ScriptWrappable::reportMemoryUsage): + * bindings/v8/DOMDataStore.cpp: + (WebCore::DOMDataStore::reportMemoryUsage): + * bindings/v8/IntrusiveDOMWrapperMap.h: + (WebCore::ChunkedTable::reportMemoryUsage): + * bindings/v8/ScriptProfiler.cpp: + (WebCore::ScriptProfiler::collectBindingMemoryInfo): + * bindings/v8/ScriptWrappable.h: + (WebCore::ScriptWrappable::reportMemoryUsage): + * bindings/v8/V8Binding.cpp: + (WebCore::V8BindingPerIsolateData::reportMemoryUsage): + (WebCore::StringCache::reportMemoryUsage): + * bindings/v8/V8DOMMap.h: + * css/StylePropertySet.h: + (WebCore::StylePropertySet::reportMemoryUsage): + * dom/CharacterData.cpp: + (WebCore::CharacterData::reportMemoryUsage): + * dom/ContainerNode.h: + (WebCore::ContainerNode::reportMemoryUsage): + * dom/Document.cpp: + (WebCore::Document::reportMemoryUsage): + * dom/Element.h: + (WebCore::Element::reportMemoryUsage): + * dom/ElementAttributeData.h: + (WebCore::ElementAttributeData::reportMemoryUsage): + * dom/MemoryInstrumentation.h: + (WebCore::MemoryInstrumentation::reportObject): + (MemoryInstrumentation): + (WebCore::MemoryInstrumentation::reportPointer): + (WebCore::MemoryClassInfo::reportInstrumentedPointer): + (WebCore::MemoryClassInfo::reportInstrumentedObject): + (WebCore::MemoryClassInfo::reportPointer): + (WebCore::MemoryClassInfo::reportObject): + (WebCore::MemoryClassInfo::reportHashMap): + (WebCore::MemoryClassInfo::reportHashSet): + (WebCore::MemoryClassInfo::reportListHashSet): + (WebCore::MemoryClassInfo::reportVector): + (MemoryClassInfo): + (WebCore::MemoryClassInfo::reportString): + (WebCore): + (WebCore::MemoryInstrumentation::reportInstrumentedPointer): + (WebCore::MemoryInstrumentation::reportInstrumentedObject): + (WebCore::MemoryInstrumentation::reportHashMap): + (WebCore::MemoryInstrumentation::reportHashSet): + (WebCore::MemoryInstrumentation::reportListHashSet): + (WebCore::MemoryInstrumentation::reportVector): + * dom/Node.cpp: + (WebCore::Node::reportMemoryUsage): + * dom/QualifiedName.h: + (WebCore::QualifiedName::QualifiedNameImpl::reportMemoryUsage): + (WebCore::QualifiedName::reportMemoryUsage): + * inspector/InspectorMemoryAgent.cpp: + (WebCore): + * platform/TreeShared.h: + (WebCore::TreeShared::reportMemoryUsage): + +2012-07-16 Ilya Tikhonovsky <loislo@chromium.org> + + Web Inspector: moving forward to the better memory instrumentation API + https://bugs.webkit.org/show_bug.cgi?id=91259 + + Reviewed by Pavel Feldman. + + I'm trying to remove unnecessary complexity of the API + reportInstrumentedObject and reportInstrumentedPointer will be replaced with addInstrumentedMember + The same will happen with reportPointer, reportObject pair. + Also info.report* will be replaced with info.add* + + * bindings/js/ScriptWrappable.h: + (WebCore::ScriptWrappable::reportMemoryUsage): + * bindings/v8/DOMDataStore.cpp: + (WebCore::DOMDataStore::reportMemoryUsage): + * bindings/v8/IntrusiveDOMWrapperMap.h: + (WebCore::ChunkedTable::reportMemoryUsage): + * bindings/v8/ScriptProfiler.cpp: + (WebCore::ScriptProfiler::collectBindingMemoryInfo): + * bindings/v8/ScriptWrappable.h: + (WebCore::ScriptWrappable::reportMemoryUsage): + * bindings/v8/V8Binding.cpp: + (WebCore::V8BindingPerIsolateData::reportMemoryUsage): + (WebCore::StringCache::reportMemoryUsage): + * bindings/v8/V8DOMMap.h: + * css/StylePropertySet.h: + (WebCore::StylePropertySet::reportMemoryUsage): + * dom/CharacterData.cpp: + (WebCore::CharacterData::reportMemoryUsage): + * dom/ContainerNode.h: + (WebCore::ContainerNode::reportMemoryUsage): + * dom/Document.cpp: + (WebCore::Document::reportMemoryUsage): + * dom/Element.h: + (WebCore::Element::reportMemoryUsage): + * dom/ElementAttributeData.h: + (WebCore::ElementAttributeData::reportMemoryUsage): + * dom/MemoryInstrumentation.h: + (WebCore::MemoryInstrumentation::addInstrumentedMember): + (MemoryInstrumentation): + (WebCore::MemoryInstrumentation::addMember): + (WebCore::MemoryInstrumentation::OwningTraits::addInstrumentedMember): + (WebCore::MemoryInstrumentation::OwningTraits::addMember): + (WebCore::MemoryInstrumentation::addInstrumentedMemberImpl): + (WebCore::MemoryInstrumentation::addMemberImpl): + (WebCore::MemoryClassInfo::addInstrumentedMember): + (WebCore::MemoryClassInfo::addMember): + (WebCore::MemoryClassInfo::addHashMap): + (WebCore::MemoryClassInfo::addHashSet): + (WebCore::MemoryClassInfo::addListHashSet): + (WebCore::MemoryClassInfo::addVector): + (WebCore::MemoryClassInfo::addString): + (WebCore::MemoryInstrumentation::addHashMap): + (WebCore::MemoryInstrumentation::addHashSet): + (WebCore::MemoryInstrumentation::addListHashSet): + (WebCore::MemoryInstrumentation::addVector): + * dom/Node.cpp: + (WebCore::Node::reportMemoryUsage): + * dom/QualifiedName.h: + (WebCore::QualifiedName::QualifiedNameImpl::reportMemoryUsage): + (WebCore::QualifiedName::reportMemoryUsage): + * inspector/InspectorMemoryAgent.cpp: + (WebCore): + * platform/TreeShared.h: + (WebCore::TreeShared::reportMemoryUsage): + +2012-07-16 Ilya Tikhonovsky <loislo@chromium.org> + + Web Inspector: native memory instrumentation: extract instrumentation methods into MemoryClassInfo + https://bugs.webkit.org/show_bug.cgi?id=91227 + + Reviewed by Pavel Feldman. + + void Node::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const + { + MemoryClassInfo<Node> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + info.visitBaseClass<ScriptWrappable>(this); + + info.addMember(m_notInstrumentedPointer); // automatically detects poniter/reference + info.addInstrumentedMember(m_next); + info.addHashSet<MemoryInstrumentation::NonClass>(m_aHash); // NonClass value_type (report only size of internal template structures) + info.addHashSet<MemoryInstrumentation::NotInstrumentedClass>(m_aHashSet); // not instrumented value_type (use sizeof) + info.addHashSet<MemoryInstrumentation::InstrumentedClass>(m_aHashSet); // instrumented value_type (call visit) + } + + The change is covered by existing tests for native memory snapshot. + + * bindings/v8/DOMDataStore.cpp: + (WebCore::DOMDataStore::reportMemoryUsage): + * bindings/v8/IntrusiveDOMWrapperMap.h: + (WebCore::ChunkedTable::reportMemoryUsage): + * bindings/v8/ScriptWrappable.h: + (WebCore::ScriptWrappable::reportMemoryUsage): + * bindings/v8/V8Binding.cpp: + (WebCore::V8BindingPerIsolateData::reportMemoryUsage): + (WebCore::StringCache::reportMemoryUsage): + * bindings/v8/V8DOMMap.h: + * css/StylePropertySet.h: + (WebCore::StylePropertySet::reportMemoryUsage): + * dom/CharacterData.cpp: + (WebCore::CharacterData::reportMemoryUsage): + * dom/ContainerNode.h: + (WebCore::ContainerNode::reportMemoryUsage): + * dom/Document.cpp: + (WebCore::Document::reportMemoryUsage): + * dom/Element.h: + (WebCore::Element::reportMemoryUsage): + * dom/ElementAttributeData.h: + (WebCore::ElementAttributeData::reportMemoryUsage): + * dom/MemoryInstrumentation.h: + (MemoryInstrumentation): + (WebCore::MemoryObjectInfo::objectType): + (WebCore::MemoryObjectInfo::objectSize): + (WebCore::MemoryObjectInfo::memoryInstrumentation): + (MemoryObjectInfo): + (WebCore::MemoryObjectInfo::reportObjectInfo): + (WebCore): + (MemoryClassInfo): + (WebCore::MemoryClassInfo::MemoryClassInfo): + (WebCore::MemoryClassInfo::visitBaseClass): + (WebCore::MemoryClassInfo::reportInstrumentedPointer): + (WebCore::MemoryClassInfo::reportInstrumentedObject): + (WebCore::MemoryClassInfo::reportPointer): + (WebCore::MemoryClassInfo::reportObject): + (WebCore::MemoryClassInfo::reportHashMap): + (WebCore::MemoryClassInfo::reportHashSet): + (WebCore::MemoryClassInfo::reportListHashSet): + (WebCore::MemoryClassInfo::reportVector): + (WebCore::MemoryClassInfo::reportString): + * dom/Node.cpp: + (WebCore::Node::reportMemoryUsage): + * dom/QualifiedName.h: + (WebCore::QualifiedName::QualifiedNameImpl::reportMemoryUsage): + (WebCore::QualifiedName::reportMemoryUsage): + * platform/TreeShared.h: + (WebCore::TreeShared::reportMemoryUsage): + +2012-07-15 Carlos Garcia Campos <cgarcia@igalia.com> + + Unreviewed. Fix make distcheck. + + * GNUmakefile.am: Add missing idl directory. + * GNUmakefile.list.am: Add missing files to compilation. + +2012-07-16 Eugene Klyuchnikov <eustas.big@gmail.com> + + Web Inspector: Implement message loop instrumentation for timeline + https://bugs.webkit.org/show_bug.cgi?id=88325 + + Reviewed by Pavel Feldman. + + Message loop instrumentation will show when the render thread is busy. + + * inspector/front-end/Settings.js: + (WebInspector.ExperimentsSettings): + Added new experiment. + * inspector/front-end/TimelineGrid.js: + (WebInspector.TimelineGrid.prototype.get dividersLabelBarElement): + Exposed label bar element. + * inspector/front-end/TimelinePanel.js: + (WebInspector.TimelinePanel): + (WebInspector.TimelinePanel.prototype._resetPanel): + Cleanups recorded tasks. + (WebInspector.TimelinePanel.prototype._refresh): + Updates CPU bar. + (WebInspector.TimelinePanel.prototype._refreshRecords): + Ditto. + (WebInspector.TimelinePanel.prototype._refreshCpuBars.compareEndTime): + Ditto. + (WebInspector.TimelinePanel.prototype._refreshCpuBars): + Ditto. + (WebInspector.TimelinePanel.prototype._enableMainThreadMonitoringExperiment): + Adds CPU bar to UI. + (WebInspector.TimelinePanel.prototype._showPopover): + Fix NPE. + (WebInspector.TimelineCalculator.prototype.computeTime): + Utility for position to time conversion. + (WebInspector.TimelineCalculator.prototype.setDisplayWindow): + Remenbers clientWidth. + * inspector/front-end/TimelinePresentationModel.js: + (WebInspector.TimelinePresentationModel.categories): + Define CPU bar colors. + * inspector/front-end/timelinePanel.css: + (.timeline-cpu-bars): + CPU bar styles. + (.timeline-cpu-bars-label): + Ditto. + +2012-07-16 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r122681. + http://trac.webkit.org/changeset/122681 + https://bugs.webkit.org/show_bug.cgi?id=91363 + + Patch introduces crashes in debug builds for GTK and EFL ports + (Requested by zdobersek on #webkit). + + * platform/ScrollableArea.cpp: + (WebCore::ScrollableArea::scrollPositionChanged): + +2012-07-16 Luke Macpherson <macpherson@chromium.org> + + Compilation failure in StyleResolver.cpp (clang) + https://bugs.webkit.org/show_bug.cgi?id=89892 + + Reviewed by Ryosuke Niwa. + + Patch adds assertions that unreachable code is in fact not reached. + + Covered by fast/css/variables tests. + + * css/CSSParser.cpp: + (WebCore::CSSParser::parseValue): + * css/StyleResolver.cpp: + (WebCore::StyleResolver::collectMatchingRulesForList): + +2012-07-15 Mike Lawther <mikelawther@chromium.org> + + Fix calculation of rgba's alpha in CSS custom text + https://bugs.webkit.org/show_bug.cgi?id=91355 + + Reviewed by Ryosuke Niwa. + + Alpha values are stored as an 8 bit value. To convert this to a float in the + range [0,1], we need to divide by 255, not 256. + + Test: fast/css/rgba-custom-text.html + + * css/CSSPrimitiveValue.cpp: + (WebCore::CSSPrimitiveValue::customCssText): + +2012-07-15 Jason Liu <jason.liu@torchmobile.com.cn> + + [BlackBerry] We shouldn't call didFinishLoading for the old request when a new request has been sent by notifyAuthReceived. + https://bugs.webkit.org/show_bug.cgi?id=90962 + + Reviewed by Rob Buis. + + We start a new NetworkJob with credentials after receiving 401/407 status. + We should not release resources in webcore when the old job is closed because + they are needed by the new one. + We should do as 3XX. + + No new tests. No change in behaviour. + + * platform/network/blackberry/NetworkJob.cpp: + (WebCore::NetworkJob::NetworkJob): + (WebCore::NetworkJob::notifyAuthReceived): + (WebCore::NetworkJob::shouldReleaseClientResource): + (WebCore::NetworkJob::handleRedirect): + * platform/network/blackberry/NetworkJob.h: + (NetworkJob): + +2012-07-15 Ryosuke Niwa <rniwa@webkit.org> + + REGRESSION(r122660): Cannot iterate over HTMLCollection that contains non-child descendent nodes in some conditions + https://bugs.webkit.org/show_bug.cgi?id=91334 + + Reviewed by Ojan Vafai. + + The bug was caused by using lastChild() as the starting node for traversePreviousNode. Since it's the inverse of + Node::traverseNextNode(), which visits nodes in pre order, we must start our search from the last descendent node, + which is visited traverseNextNode immediately before reaching the root node. + + Test: fast/dom/htmlcollection-backwards-subtree-iteration.html + + * html/HTMLCollection.cpp: + (WebCore::lastDescendent): + (WebCore): + (WebCore::itemBeforeOrAfter): + +2012-07-15 Joseph Pecoraro <pecoraro@apple.com> + + Windowless WebView not firing JavaScript load event if there is a media element + https://bugs.webkit.org/show_bug.cgi?id=91331 + + Reviewed by Eric Carlson. + + In prepareForLoad we start deferring the load event. If we fall into this + clause where the page can not start loading media we bail, potentially + indefinitely waiting until we can start loading media. Since we can not + be certain this will ever happen, we should stop deferring the page's + load event. + + Test: WebKit1.WindowlessWebViewWithMedia TestWebKitAPI test. The only + way this path was reachable right now is on the mac port. + + * html/HTMLMediaElement.cpp: + (WebCore::HTMLMediaElement::loadInternal): + +2012-07-15 Dan Bernstein <mitz@apple.com> + + <rdar://problem/11875795> REGRESSION (tiled drawing): Page’s scroll bars flash with each character you type in a textarea (affects Wikipedia and YouTube) + https://bugs.webkit.org/show_bug.cgi?id=91348 + + Reviewed by Anders Carlsson. + + * platform/ScrollableArea.cpp: + (WebCore::ScrollableArea::scrollPositionChanged): Added an early return if the scroll position + did not, in fact, change. This avoids the call to ScrollAnimator::notifyContentAreaScrolled, + which is what causes the scroll bars to flash. + 2012-07-14 Eric Carlson <eric.carlson@apple.com> Enable AVCF hardware video decoding diff --git a/Source/WebCore/Configurations/Version.xcconfig b/Source/WebCore/Configurations/Version.xcconfig index dc5e3d7c9..bd1758334 100644 --- a/Source/WebCore/Configurations/Version.xcconfig +++ b/Source/WebCore/Configurations/Version.xcconfig @@ -22,7 +22,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. MAJOR_VERSION = 537; -MINOR_VERSION = 1; +MINOR_VERSION = 2; TINY_VERSION = 0; FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION); diff --git a/Source/WebCore/DerivedSources.pri b/Source/WebCore/DerivedSources.pri index 2f93c4ae0..2c29c8f52 100644 --- a/Source/WebCore/DerivedSources.pri +++ b/Source/WebCore/DerivedSources.pri @@ -462,12 +462,6 @@ IDL_BINDINGS += \ $$PWD/xml/XPathEvaluator.idl \ $$PWD/xml/XSLTProcessor.idl -v8 { - IDL_BINDINGS += \ - $$PWD/Modules/indexeddb/IDBVersionChangeEvent.idl \ - $$PWD/Modules/indexeddb/IDBVersionChangeRequest.idl -} - contains(DEFINES, ENABLE_SVG=1) { IDL_BINDINGS += \ $$PWD/svg/SVGAElement.idl \ @@ -624,14 +618,11 @@ contains(DEFINES, ENABLE_VIDEO_TRACK=1) { $$PWD/html/track/TrackEvent.idl \ } -v8: wrapperFactoryArg = --wrapperFactoryV8 -else: wrapperFactoryArg = --wrapperFactory - mathmlnames.output = MathMLNames.cpp mathmlnames.input = MATHML_NAMES mathmlnames.depends = $$PWD/mathml/mathattrs.in mathmlnames.script = $$PWD/dom/make_names.pl -mathmlnames.commands = perl -I$$PWD/bindings/scripts $$mathmlnames.script --tags $$PWD/mathml/mathtags.in --attrs $$PWD/mathml/mathattrs.in --extraDefines \"$${DEFINES}\" --preprocessor \"$${QMAKE_MOC} -E\" --factory $$wrapperFactoryArg --outputDir ${QMAKE_FUNC_FILE_OUT_PATH} +mathmlnames.commands = perl -I$$PWD/bindings/scripts $$mathmlnames.script --tags $$PWD/mathml/mathtags.in --attrs $$PWD/mathml/mathattrs.in --extraDefines \"$${DEFINES}\" --preprocessor \"$${QMAKE_MOC} -E\" --factory --wrapperFactory --outputDir ${QMAKE_FUNC_FILE_OUT_PATH} mathmlnames.extra_sources = MathMLElementFactory.cpp GENERATORS += mathmlnames @@ -640,13 +631,9 @@ svgnames.output = SVGNames.cpp svgnames.input = SVG_NAMES svgnames.depends = $$PWD/svg/svgattrs.in svgnames.script = $$PWD/dom/make_names.pl -svgnames.commands = perl -I$$PWD/bindings/scripts $$svgnames.script --tags $$PWD/svg/svgtags.in --attrs $$PWD/svg/svgattrs.in --extraDefines \"$${DEFINES}\" --preprocessor \"$${QMAKE_MOC} -E\" --factory $$wrapperFactoryArg --outputDir ${QMAKE_FUNC_FILE_OUT_PATH} +svgnames.commands = perl -I$$PWD/bindings/scripts $$svgnames.script --tags $$PWD/svg/svgtags.in --attrs $$PWD/svg/svgattrs.in --extraDefines \"$${DEFINES}\" --preprocessor \"$${QMAKE_MOC} -E\" --factory --wrapperFactory --outputDir ${QMAKE_FUNC_FILE_OUT_PATH} svgnames.extra_sources = SVGElementFactory.cpp -v8 { - svgnames.extra_sources += V8SVGElementWrapperFactory.cpp -} else { svgnames.extra_sources += JSSVGElementWrapperFactory.cpp -} GENERATORS += svgnames # GENERATOR 5-D: @@ -703,11 +690,9 @@ GENERATORS += preprocessIdls # GENERATOR 1: Generate .h and .cpp from IDLs generateBindings.input = IDL_BINDINGS generateBindings.script = $$PWD/bindings/scripts/generate-bindings.pl -v8: generator = V8 -else: generator = JS generateBindings.commands = perl -I$$PWD/bindings/scripts $$generateBindings.script \ --defines \"$${FEATURE_DEFINES_JAVASCRIPT}\" \ - --generator $$generator \ + --generator JS \ --include $$PWD/Modules/filesystem \ --include $$PWD/Modules/geolocation \ --include $$PWD/Modules/indexeddb \ @@ -727,25 +712,14 @@ generateBindings.commands = perl -I$$PWD/bindings/scripts $$generateBindings.scr --outputDir ${QMAKE_FUNC_FILE_OUT_PATH} \ --supplementalDependencyFile ${QMAKE_FUNC_FILE_OUT_PATH}/$$SUPPLEMENTAL_DEPENDENCY_FILE \ --preprocessor \"$${QMAKE_MOC} -E\" ${QMAKE_FILE_NAME} -v8 { - generateBindings.output = V8${QMAKE_FILE_BASE}.cpp - generateBindings.depends = ${QMAKE_FUNC_FILE_OUT_PATH}/$$SUPPLEMENTAL_DEPENDENCY_FILE \ - $$PWD/bindings/scripts/CodeGenerator.pm \ - $$PWD/bindings/scripts/CodeGeneratorV8.pm \ - $$PWD/bindings/scripts/IDLParser.pm \ - $$PWD/bindings/scripts/IDLStructure.pm \ - $$PWD/bindings/scripts/InFilesParser.pm \ - $$PWD/bindings/scripts/preprocessor.pm -} else { - generateBindings.output = JS${QMAKE_FILE_BASE}.cpp - generateBindings.depends = ${QMAKE_FUNC_FILE_OUT_PATH}/$$SUPPLEMENTAL_DEPENDENCY_FILE \ - $$PWD/bindings/scripts/CodeGenerator.pm \ - $$PWD/bindings/scripts/CodeGeneratorJS.pm \ - $$PWD/bindings/scripts/IDLParser.pm \ - $$PWD/bindings/scripts/IDLStructure.pm \ - $$PWD/bindings/scripts/InFilesParser.pm \ - $$PWD/bindings/scripts/preprocessor.pm -} +generateBindings.output = JS${QMAKE_FILE_BASE}.cpp +generateBindings.depends = ${QMAKE_FUNC_FILE_OUT_PATH}/$$SUPPLEMENTAL_DEPENDENCY_FILE \ + $$PWD/bindings/scripts/CodeGenerator.pm \ + $$PWD/bindings/scripts/CodeGeneratorJS.pm \ + $$PWD/bindings/scripts/IDLParser.pm \ + $$PWD/bindings/scripts/IDLStructure.pm \ + $$PWD/bindings/scripts/InFilesParser.pm \ + $$PWD/bindings/scripts/preprocessor.pm GENERATORS += generateBindings # GENERATOR 2: inspector idl compiler @@ -810,13 +784,9 @@ htmlnames.output = HTMLNames.cpp htmlnames.input = HTML_NAMES htmlnames.script = $$PWD/dom/make_names.pl htmlnames.depends = $$PWD/html/HTMLAttributeNames.in -htmlnames.commands = perl -I$$PWD/bindings/scripts $$htmlnames.script --tags $$PWD/html/HTMLTagNames.in --attrs $$PWD/html/HTMLAttributeNames.in --extraDefines \"$${DEFINES}\" --preprocessor \"$${QMAKE_MOC} -E\" --factory $$wrapperFactoryArg --outputDir ${QMAKE_FUNC_FILE_OUT_PATH} +htmlnames.commands = perl -I$$PWD/bindings/scripts $$htmlnames.script --tags $$PWD/html/HTMLTagNames.in --attrs $$PWD/html/HTMLAttributeNames.in --extraDefines \"$${DEFINES}\" --preprocessor \"$${QMAKE_MOC} -E\" --factory --wrapperFactory --outputDir ${QMAKE_FUNC_FILE_OUT_PATH} htmlnames.extra_sources = HTMLElementFactory.cpp -v8 { - htmlnames.extra_sources += V8HTMLElementWrapperFactory.cpp -} else { - htmlnames.extra_sources += JSHTMLElementWrapperFactory.cpp -} +htmlnames.extra_sources += JSHTMLElementWrapperFactory.cpp GENERATORS += htmlnames # GENERATOR 5-B: @@ -932,11 +902,35 @@ webkitversion.clean = ${QMAKE_FUNC_FILE_OUT_PATH}/WebKitVersion.h webkitversion.add_output_to_sources = false GENERATORS += webkitversion -# Stolen from JavaScriptCore, needed for YARR -v8 { - retgen.output = RegExpJitTables.h - retgen.script = $$PWD/../JavaScriptCore/create_regex_tables - retgen.input = retgen.script - retgen.commands = python $$retgen.script > ${QMAKE_FILE_OUT} - GENERATORS += retgen +# Generator 12: Angle parsers +contains(DEFINES, WTF_USE_3D_GRAPHICS=1) { + + ANGLE_DIR = $$replace(PWD, "WebCore", "ThirdParty/ANGLE") + + ANGLE_FLEX_SOURCES = \ + $$ANGLE_DIR/src/compiler/glslang.l \ + $$ANGLE_DIR/src/compiler/preprocessor/new/Tokenizer.l + + angleflex.output = ${QMAKE_FILE_BASE}_lex.cpp + angleflex.input = ANGLE_FLEX_SOURCES + angleflex.commands = flex --noline --nounistd --outfile=${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} + *g++*: angleflex.variable_out = ANGLE_SOURCES + GENERATORS += angleflex + + ANGLE_BISON_SOURCES = \ + $$ANGLE_DIR/src/compiler/glslang.y \ + $$ANGLE_DIR/src/compiler/preprocessor/new/ExpressionParser.y + + anglebison_decl.output = ${QMAKE_FILE_BASE}_tab.h + anglebison_decl.input = ANGLE_BISON_SOURCES + anglebison_decl.commands = bison --no-lines --skeleton=yacc.c --defines=${QMAKE_FILE_OUT} --output=${QMAKE_FUNC_FILE_OUT_PATH}$${QMAKE_DIR_SEP}${QMAKE_FILE_OUT_BASE}.cpp ${QMAKE_FILE_IN} + anglebison_decl.variable_out = GENERATED_FILES + GENERATORS += anglebison_decl + + anglebison_impl.input = ANGLE_BISON_SOURCES + anglebison_impl.commands = $$escape_expand(\\n) + anglebison_impl.depends = ${QMAKE_FILE_BASE}_tab.h + anglebison_impl.output = ${QMAKE_FILE_BASE}_tab.cpp + *g++*: anglebison_impl.variable_out = ANGLE_SOURCES + GENERATORS += anglebison_impl } diff --git a/Source/WebCore/English.lproj/localizedStrings.js b/Source/WebCore/English.lproj/localizedStrings.js index 6ab4bc3da..9edc64141 100644 --- a/Source/WebCore/English.lproj/localizedStrings.js +++ b/Source/WebCore/English.lproj/localizedStrings.js @@ -715,8 +715,12 @@ localizedStrings["Local modifications..."] = "Local modifications..."; localizedStrings["apply original content"] = "apply original content"; localizedStrings["apply revision content"] = "apply revision content"; localizedStrings["revert"] = "revert"; +localizedStrings["CPU"] = "CPU"; localizedStrings["CPU Time"] = "CPU Time"; localizedStrings["Encoded Data Length"] = "Encoded Data Length"; localizedStrings["%d Bytes"] = "%d Bytes"; localizedStrings["Time End"] = "Time End"; localizedStrings["Find"] = "Find"; +localizedStrings["Replace"] = "Replace"; +localizedStrings["Replace All"] = "Replace All"; +localizedStrings["Skip"] = "Skip"; diff --git a/Source/WebCore/GNUmakefile.am b/Source/WebCore/GNUmakefile.am index 18465f9f1..aa102c8c1 100644 --- a/Source/WebCore/GNUmakefile.am +++ b/Source/WebCore/GNUmakefile.am @@ -1051,6 +1051,7 @@ EXTRA_DIST += \ $(shell ls $(srcdir)/Source/WebCore/Modules/indexeddb/*.idl) \ $(shell ls $(srcdir)/Source/WebCore/Modules/mediastream/*.idl) \ $(shell ls $(srcdir)/Source/WebCore/Modules/notifications/*.idl) \ + $(shell ls $(srcdir)/Source/WebCore/Modules/protocolhandler/*.idl) \ $(shell ls $(srcdir)/Source/WebCore/Modules/webaudio/*.idl) \ $(shell ls $(srcdir)/Source/WebCore/Modules/webdatabase/*.idl) \ $(shell ls $(srcdir)/Source/WebCore/Modules/websockets/*.idl) \ diff --git a/Source/WebCore/GNUmakefile.list.am b/Source/WebCore/GNUmakefile.list.am index c79f8db82..3eb943991 100644 --- a/Source/WebCore/GNUmakefile.list.am +++ b/Source/WebCore/GNUmakefile.list.am @@ -1209,6 +1209,7 @@ webcore_modules_sources += \ Source/WebCore/Modules/notifications/WorkerContextNotifications.h \ Source/WebCore/Modules/protocolhandler/NavigatorRegisterProtocolHandler.cpp \ Source/WebCore/Modules/protocolhandler/NavigatorRegisterProtocolHandler.h \ + Source/WebCore/Modules/protocolhandler/RegisterProtocolHandlerClient.h \ Source/WebCore/Modules/webdatabase/AbstractDatabase.cpp \ Source/WebCore/Modules/webdatabase/AbstractDatabase.h \ Source/WebCore/Modules/webdatabase/ChangeVersionWrapper.cpp \ @@ -1798,6 +1799,8 @@ webcore_sources += \ Source/WebCore/css/WebKitCSSShaderValue.h \ Source/WebCore/css/WebKitCSSTransformValue.cpp \ Source/WebCore/css/WebKitCSSTransformValue.h \ + Source/WebCore/css/WrapShapeFunctions.cpp \ + Source/WebCore/css/WrapShapeFunctions.h \ Source/WebCore/dom/ActiveDOMObject.cpp \ Source/WebCore/dom/ActiveDOMObject.h \ Source/WebCore/dom/Attr.cpp \ @@ -2585,6 +2588,8 @@ webcore_sources += \ Source/WebCore/html/shadow/HTMLContentElement.h \ Source/WebCore/html/shadow/InsertionPoint.cpp \ Source/WebCore/html/shadow/InsertionPoint.h \ + Source/WebCore/html/shadow/ImageInnerElement.cpp \ + Source/WebCore/html/shadow/ImageInnerElement.h \ Source/WebCore/html/shadow/MediaControls.cpp \ Source/WebCore/html/shadow/MediaControls.h \ Source/WebCore/html/shadow/MediaControlElements.cpp \ @@ -2914,6 +2919,7 @@ webcore_sources += \ Source/WebCore/loader/icon/PageURLRecord.h \ Source/WebCore/loader/ImageLoader.cpp \ Source/WebCore/loader/ImageLoader.h \ + Source/WebCore/loader/ImageLoaderClient.h \ Source/WebCore/loader/LinkLoader.h \ Source/WebCore/loader/LinkLoader.cpp \ Source/WebCore/loader/LinkLoaderClient.h \ @@ -3062,6 +3068,9 @@ webcore_sources += \ Source/WebCore/page/PageGroup.h \ Source/WebCore/page/PageGroupLoadDeferrer.cpp \ Source/WebCore/page/PageGroupLoadDeferrer.h \ + Source/WebCore/page/PagePopup.h \ + Source/WebCore/page/PagePopupClient.h \ + Source/WebCore/page/PagePopupDriver.h \ Source/WebCore/page/PageSerializer.cpp \ Source/WebCore/page/PageSerializer.h \ Source/WebCore/page/PageVisibilityState.cpp \ @@ -5914,8 +5923,21 @@ webcore_sources += \ Source/ThirdParty/ANGLE/src/compiler/ConstantUnion.h \ Source/ThirdParty/ANGLE/src/compiler/debug.cpp \ Source/ThirdParty/ANGLE/src/compiler/debug.h \ + Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraph.cpp \ + Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraph.h \ + Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphBuilder.h \ + Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphBuilder.cpp \ + Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphOutput.h \ + Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphOutput.cpp \ + Source/ThirdParty/ANGLE/src/compiler/depgraph/DependencyGraphTraverse.cpp \ + Source/ThirdParty/ANGLE/src/compiler/DetectDiscontinuity.cpp \ + Source/ThirdParty/ANGLE/src/compiler/DetectDiscontinuity.h \ Source/ThirdParty/ANGLE/src/compiler/DetectRecursion.cpp \ Source/ThirdParty/ANGLE/src/compiler/DetectRecursion.h \ + Source/ThirdParty/ANGLE/src/compiler/Diagnostics.cpp \ + Source/ThirdParty/ANGLE/src/compiler/Diagnostics.h \ + Source/ThirdParty/ANGLE/src/compiler/DirectiveHandler.cpp \ + Source/ThirdParty/ANGLE/src/compiler/DirectiveHandler.h \ Source/ThirdParty/ANGLE/src/compiler/ExtensionBehavior.h \ Source/ThirdParty/ANGLE/src/compiler/ForLoopUnroll.cpp \ Source/ThirdParty/ANGLE/src/compiler/ForLoopUnroll.h \ @@ -5928,6 +5950,7 @@ webcore_sources += \ Source/ThirdParty/ANGLE/src/compiler/InitializeGlobals.h \ Source/ThirdParty/ANGLE/src/compiler/Initialize.h \ Source/ThirdParty/ANGLE/src/compiler/InitializeParseContext.h \ + Source/ThirdParty/ANGLE/src/compiler/InitializeParseContext.cpp \ Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp \ Source/ThirdParty/ANGLE/src/compiler/intermediate.h \ Source/ThirdParty/ANGLE/src/compiler/intermOut.cpp \ @@ -5951,6 +5974,7 @@ webcore_sources += \ Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h \ Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp \ Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.h \ + Source/ThirdParty/ANGLE/src/compiler/Pragma.h \ Source/ThirdParty/ANGLE/src/compiler/preprocessor/atom.c \ Source/ThirdParty/ANGLE/src/compiler/preprocessor/atom.h \ Source/ThirdParty/ANGLE/src/compiler/preprocessor/compile.h \ @@ -5960,6 +5984,29 @@ webcore_sources += \ Source/ThirdParty/ANGLE/src/compiler/preprocessor/length_limits.h \ Source/ThirdParty/ANGLE/src/compiler/preprocessor/memory.c \ Source/ThirdParty/ANGLE/src/compiler/preprocessor/memory.h \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DiagnosticsBase.cpp \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Diagnostics.h \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DirectiveHandlerBase.cpp \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DirectiveHandler.h \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DirectiveParser.cpp \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/DirectiveParser.h \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/ExpressionParser.cpp \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/ExpressionParser.h \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.cpp \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.h \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Lexer.cpp \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Lexer.h \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Macro.cpp \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Macro.h \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/MacroExpander.cpp \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/MacroExpander.h \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Preprocessor.cpp \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Preprocessor.h \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/SourceLocation.h \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Token.cpp \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Token.h \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Tokenizer.cpp \ + Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Tokenizer.h \ Source/ThirdParty/ANGLE/src/compiler/preprocessor/parser.h \ Source/ThirdParty/ANGLE/src/compiler/preprocessor/preprocess.h \ Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c \ @@ -5973,6 +6020,7 @@ webcore_sources += \ Source/ThirdParty/ANGLE/src/compiler/QualifierAlive.h \ Source/ThirdParty/ANGLE/src/compiler/RemoveTree.cpp \ Source/ThirdParty/ANGLE/src/compiler/RemoveTree.h \ + Source/ThirdParty/ANGLE/src/compiler/RenameFunction.h \ Source/ThirdParty/ANGLE/src/compiler/SearchSymbol.cpp \ Source/ThirdParty/ANGLE/src/compiler/SearchSymbol.h \ Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp \ @@ -5981,6 +6029,10 @@ webcore_sources += \ Source/ThirdParty/ANGLE/src/compiler/SymbolTable.h \ Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.cpp \ Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.h \ + Source/ThirdParty/ANGLE/src/compiler/timing/RestrictFragmentShaderTiming.cpp \ + Source/ThirdParty/ANGLE/src/compiler/timing/RestrictFragmentShaderTiming.h \ + Source/ThirdParty/ANGLE/src/compiler/timing/RestrictVertexShaderTiming.cpp \ + Source/ThirdParty/ANGLE/src/compiler/timing/RestrictVertexShaderTiming.h \ Source/ThirdParty/ANGLE/src/compiler/TranslatorESSL.cpp \ Source/ThirdParty/ANGLE/src/compiler/TranslatorESSL.h \ Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.cpp \ @@ -5988,8 +6040,8 @@ webcore_sources += \ Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.cpp \ Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.h \ Source/ThirdParty/ANGLE/src/compiler/Types.h \ - Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.cpp \ - Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.h \ + Source/ThirdParty/ANGLE/src/compiler/UnfoldShortCircuit.cpp \ + Source/ThirdParty/ANGLE/src/compiler/UnfoldShortCircuit.h \ Source/ThirdParty/ANGLE/src/compiler/util.cpp \ Source/ThirdParty/ANGLE/src/compiler/util.h \ Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp \ @@ -6060,8 +6112,9 @@ webcore_sources += \ Source/WebCore/platform/graphics/OpenGLShims.cpp \ Source/WebCore/platform/graphics/OpenGLShims.h \ Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp \ - Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp \ Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h \ + Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp \ + Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.h \ Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp \ Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp if USE_CLUTTER diff --git a/Source/WebCore/Modules/battery/BatteryClient.h b/Source/WebCore/Modules/battery/BatteryClient.h index bf56336cd..2c87a44bb 100644 --- a/Source/WebCore/Modules/battery/BatteryClient.h +++ b/Source/WebCore/Modules/battery/BatteryClient.h @@ -24,14 +24,12 @@ namespace WebCore { -class BatteryController; class Page; class BatteryClient { public: virtual ~BatteryClient() { } - virtual void setController(BatteryController*) = 0; virtual void startUpdating() = 0; virtual void stopUpdating() = 0; virtual void batteryControllerDestroyed() = 0; diff --git a/Source/WebCore/Modules/battery/BatteryController.cpp b/Source/WebCore/Modules/battery/BatteryController.cpp index 7a7688f10..c342e5b38 100644 --- a/Source/WebCore/Modules/battery/BatteryController.cpp +++ b/Source/WebCore/Modules/battery/BatteryController.cpp @@ -33,7 +33,6 @@ BatteryController::BatteryController(BatteryClient* client) : m_client(client) { ASSERT(m_client); - m_client->setController(this); } BatteryController::~BatteryController() diff --git a/Source/WebCore/Modules/indexeddb/IDBBackingStore.h b/Source/WebCore/Modules/indexeddb/IDBBackingStore.h index f7840621b..78a9f667a 100644 --- a/Source/WebCore/Modules/indexeddb/IDBBackingStore.h +++ b/Source/WebCore/Modules/indexeddb/IDBBackingStore.h @@ -67,7 +67,8 @@ public: virtual bool putObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const IDBKey&, const String& value, ObjectStoreRecordIdentifier*) = 0; virtual void clearObjectStore(int64_t databaseId, int64_t objectStoreId) = 0; virtual void deleteObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const ObjectStoreRecordIdentifier*) = 0; - virtual int64_t nextAutoIncrementNumber(int64_t databaseId, int64_t objectStoreId) = 0; + virtual int64_t getKeyGeneratorCurrentNumber(int64_t databaseId, int64_t objectStoreId) = 0; + virtual bool maybeUpdateKeyGeneratorCurrentNumber(int64_t databaseId, int64_t objectStoreId, int64_t newNumber, bool checkCurrent) = 0; virtual bool keyExistsInObjectStore(int64_t databaseId, int64_t objectStoreId, const IDBKey&, ObjectStoreRecordIdentifier* foundRecordIdentifier) = 0; class ObjectStoreRecordCallback { diff --git a/Source/WebCore/Modules/indexeddb/IDBCursor.cpp b/Source/WebCore/Modules/indexeddb/IDBCursor.cpp index 5e9025112..6e28691af 100644 --- a/Source/WebCore/Modules/indexeddb/IDBCursor.cpp +++ b/Source/WebCore/Modules/indexeddb/IDBCursor.cpp @@ -276,6 +276,7 @@ void IDBCursor::setValueReady() if (objectStore->autoIncrement() && !objectStore->metadata().keyPath.isNull()) { const IDBKeyPath& keyPath = objectStore->metadata().keyPath; RefPtr<IDBKey> expectedKey = createIDBKeyFromSerializedValueAndKeyPath(value, keyPath); + ASSERT(m_currentPrimaryKey); ASSERT(expectedKey->isEqual(m_currentPrimaryKey.get())); } } diff --git a/Source/WebCore/Modules/indexeddb/IDBDatabaseException.cpp b/Source/WebCore/Modules/indexeddb/IDBDatabaseException.cpp index 982819a01..803499055 100644 --- a/Source/WebCore/Modules/indexeddb/IDBDatabaseException.cpp +++ b/Source/WebCore/Modules/indexeddb/IDBDatabaseException.cpp @@ -64,7 +64,7 @@ static const struct IDBDatabaseExceptionNameDescription { { "DataCloneError", "The data being stored could not be cloned by the internal structured cloning algorithm.", DATA_CLONE_ERR }, // FIXME: should be a JavaScript TypeError. See https://bugs.webkit.org/show_bug.cgi?id=85513 { "TypeError", "This should be a TypeError", 0 }, - { "NotSupportedError", "Cannot use multiEntry indexed with an array keypath", NOT_SUPPORTED_ERR }, + { 0, 0, 0 }, // FIXME: Previous/legacy value was IDB_NOT_SUPPORTED_ERR. }; static const IDBDatabaseExceptionNameDescription* getErrorEntry(ExceptionCode ec) diff --git a/Source/WebCore/Modules/indexeddb/IDBDatabaseException.h b/Source/WebCore/Modules/indexeddb/IDBDatabaseException.h index 1a179b908..2890aecbf 100644 --- a/Source/WebCore/Modules/indexeddb/IDBDatabaseException.h +++ b/Source/WebCore/Modules/indexeddb/IDBDatabaseException.h @@ -66,7 +66,7 @@ public: IDB_SYNTAX_ERR, IDB_DATA_CLONE_ERR, IDB_TYPE_ERR, // FIXME: Placeholder until bindings have been updated to throw a JS TypeError. See https://bugs.webkit.org/show_bug.cgi?id=85513 - IDB_NOT_SUPPORTED_ERR, + LEGACY_IDB_NOT_SUPPORTED_ERR, // FIXME: Placeholder. }; static int ErrorCodeToExceptionCode(int errorCode) diff --git a/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.cpp b/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.cpp index a087e6aaf..afdb7ec3c 100644 --- a/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.cpp +++ b/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.cpp @@ -219,20 +219,6 @@ void IDBIndexBackendImpl::getKey(PassRefPtr<IDBKeyRange> prpKeyRange, PassRefPtr ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; } -bool IDBIndexBackendImpl::addingKeyAllowed(const IDBKey* indexKey, const IDBKey* primaryKey) -{ - if (!m_unique) - return true; - - RefPtr<IDBKey> foundPrimaryKey; - bool found = backingStore()->keyExistsInIndex(databaseId(), m_objectStoreBackend->id(), m_id, *indexKey, foundPrimaryKey); - if (!found) - return true; - if (primaryKey && foundPrimaryKey->isEqual(primaryKey)) - return true; - return false; -} - } // namespace WebCore #endif // ENABLE(INDEXED_DATABASE) diff --git a/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.h b/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.h index 98385128f..f841a9583 100644 --- a/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.h +++ b/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.h @@ -61,8 +61,6 @@ public: void setId(int64_t id) { m_id = id; } bool hasValidId() const { return m_id != InvalidId; }; - bool addingKeyAllowed(const IDBKey* indexKey, const IDBKey* primaryKey = 0); - // Implements IDBIndexBackendInterface. virtual IDBIndexMetadata metadata() const; diff --git a/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp b/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp index ab8293f0f..832cd4c9d 100644 --- a/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp +++ b/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp @@ -32,6 +32,7 @@ #include <wtf/Assertions.h> #include "FileSystem.h" #include "IDBFactoryBackendImpl.h" +#include "IDBKey.h" #include "IDBKeyPath.h" #include "IDBKeyRange.h" #include "IDBLevelDBCoding.h" @@ -46,6 +47,8 @@ namespace WebCore { using namespace IDBLevelDBCoding; +const int64_t KeyGeneratorInitialNumber = 1; // From the IndexedDB specification. + template <typename DBOrTransaction> static bool getBool(DBOrTransaction* db, const Vector<char>& key, bool& foundBool) { @@ -414,6 +417,15 @@ void IDBLevelDBBackingStore::getObjectStores(int64_t databaseId, Vector<int64_t> it->next(); } + int64_t keyGeneratorCurrentNumber = -1; + if (checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, ObjectStoreMetaDataKey::kKeyGeneratorCurrentNumber)) { + keyGeneratorCurrentNumber = decodeInt(it->value().begin(), it->value().end()); + // FIXME: Return keyGeneratorCurrentNumber, cache in object store, and write lazily to backing store. + // For now, just assert that if it was written it was valid. + ASSERT_UNUSED(keyGeneratorCurrentNumber, keyGeneratorCurrentNumber >= KeyGeneratorInitialNumber); + it->next(); + } + foundIds.append(objectStoreId); foundNames.append(objectStoreName); foundKeyPaths.append(keyPath); @@ -451,6 +463,7 @@ bool IDBLevelDBBackingStore::createObjectStore(int64_t databaseId, const String& const Vector<char> lastVersionKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::kLastVersion); const Vector<char> maxIndexIdKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::kMaxIndexId); const Vector<char> hasKeyPathKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::kHasKeyPath); + const Vector<char> keyGeneratorCurrentNumberKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::kKeyGeneratorCurrentNumber); const Vector<char> namesKey = ObjectStoreNamesKey::encode(databaseId, name); bool ok = putString(m_currentTransaction.get(), nameKey, name); @@ -495,6 +508,12 @@ bool IDBLevelDBBackingStore::createObjectStore(int64_t databaseId, const String& return false; } + ok = putInt(m_currentTransaction.get(), keyGeneratorCurrentNumberKey, KeyGeneratorInitialNumber); + if (!ok) { + LOG_ERROR("Internal Indexed DB error."); + return false; + } + ok = putInt(m_currentTransaction.get(), namesKey, objectStoreId); if (!ok) { LOG_ERROR("Internal Indexed DB error."); @@ -634,35 +653,66 @@ void IDBLevelDBBackingStore::deleteObjectStoreRecord(int64_t databaseId, int64_t m_currentTransaction->remove(existsEntryKey); } -int64_t IDBLevelDBBackingStore::nextAutoIncrementNumber(int64_t databaseId, int64_t objectStoreId) + +int64_t IDBLevelDBBackingStore::getKeyGeneratorCurrentNumber(int64_t databaseId, int64_t objectStoreId) { ASSERT(m_currentTransaction); - const Vector<char> startKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, minIDBKey()); - const Vector<char> stopKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, maxIDBKey()); - OwnPtr<LevelDBIterator> it = m_currentTransaction->createIterator(); + const Vector<char> keyGeneratorCurrentNumberKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::kKeyGeneratorCurrentNumber); - int64_t maxNumericKey = 0; + int64_t keyGeneratorCurrentNumber = -1; + Vector<char> data; + + if (m_currentTransaction->get(keyGeneratorCurrentNumberKey, data)) + keyGeneratorCurrentNumber = decodeInt(data.begin(), data.end()); + else { + // Previously, the key generator state was not stored explicitly but derived from the + // maximum numeric key present in existing data. This violates the spec as the data may + // be cleared but the key generator state must be preserved. + const Vector<char> startKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, minIDBKey()); + const Vector<char> stopKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, maxIDBKey()); + + OwnPtr<LevelDBIterator> it = m_currentTransaction->createIterator(); + int64_t maxNumericKey = 0; + + for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) { + const char* p = it->key().begin(); + const char* limit = it->key().end(); + + ObjectStoreDataKey dataKey; + p = ObjectStoreDataKey::decode(p, limit, &dataKey); + ASSERT(p); + + if (dataKey.userKey()->type() == IDBKey::NumberType) { + int64_t n = static_cast<int64_t>(dataKey.userKey()->number()); + if (n > maxNumericKey) + maxNumericKey = n; + } + } - // FIXME: This does a forward scan over all keys. Improve it. - // Since all dates > all numbers, create Date(-Infinity) and seek backwards. + keyGeneratorCurrentNumber = maxNumericKey + 1; + } - for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) { - const char *p = it->key().begin(); - const char *limit = it->key().end(); + return keyGeneratorCurrentNumber; +} - ObjectStoreDataKey dataKey; - p = ObjectStoreDataKey::decode(p, limit, &dataKey); - ASSERT(p); +bool IDBLevelDBBackingStore::maybeUpdateKeyGeneratorCurrentNumber(int64_t databaseId, int64_t objectStoreId, int64_t newNumber, bool checkCurrent) +{ + ASSERT(m_currentTransaction); - if (dataKey.userKey()->type() == IDBKey::NumberType) { - int64_t n = static_cast<int64_t>(dataKey.userKey()->number()); - if (n > maxNumericKey) - maxNumericKey = n; - } + if (checkCurrent) { + int64_t currentNumber = getKeyGeneratorCurrentNumber(databaseId, objectStoreId); + if (newNumber <= currentNumber) + return true; } - return maxNumericKey + 1; + const Vector<char> keyGeneratorCurrentNumberKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::kKeyGeneratorCurrentNumber); + bool ok = putInt(m_currentTransaction.get(), keyGeneratorCurrentNumberKey, newNumber); + if (!ok) { + LOG_ERROR("Internal Indexed DB error."); + return false; + } + return true; } bool IDBLevelDBBackingStore::keyExistsInObjectStore(int64_t databaseId, int64_t objectStoreId, const IDBKey& key, ObjectStoreRecordIdentifier* foundRecordIdentifier) diff --git a/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.h b/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.h index a65f963e8..c5a9e2ee3 100644 --- a/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.h +++ b/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.h @@ -58,7 +58,8 @@ public: virtual bool putObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const IDBKey&, const String& value, ObjectStoreRecordIdentifier*); virtual void clearObjectStore(int64_t databaseId, int64_t objectStoreId); virtual void deleteObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const ObjectStoreRecordIdentifier*); - virtual int64_t nextAutoIncrementNumber(int64_t databaseId, int64_t objectStoreId); + virtual int64_t getKeyGeneratorCurrentNumber(int64_t databaseId, int64_t objectStoreId); + virtual bool maybeUpdateKeyGeneratorCurrentNumber(int64_t databaseId, int64_t objectStoreId, int64_t newState, bool checkCurrent); virtual bool keyExistsInObjectStore(int64_t databaseId, int64_t objectStoreId, const IDBKey&, ObjectStoreRecordIdentifier* foundRecordIdentifier); virtual bool forEachObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, ObjectStoreRecordCallback&); diff --git a/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.cpp b/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.cpp index 183637721..1ff45a2fd 100644 --- a/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.cpp +++ b/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.cpp @@ -73,6 +73,7 @@ // <database id, 0, 0, 50, object store id, 4> => last "version" number [ObjectStoreMetaDataKey] // <database id, 0, 0, 50, object store id, 5> => maximum index id ever allocated [ObjectStoreMetaDataKey] // <database id, 0, 0, 50, object store id, 6> => has key path (vs. null) [ObjectStoreMetaDataKey] +// <database id, 0, 0, 50, object store id, 7> => key generator current number [ObjectStoreMetaDataKey] // // // Index meta-data: diff --git a/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.h b/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.h index cc1f7278d..a23a29274 100644 --- a/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.h +++ b/Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.h @@ -155,7 +155,8 @@ public: kEvictable = 3, kLastVersion = 4, kMaxIndexId = 5, - kHasKeyPath = 6 + kHasKeyPath = 6, + kKeyGeneratorCurrentNumber = 7 }; ObjectStoreMetaDataKey(); diff --git a/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp b/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp index 65f222bf8..dae83c590 100644 --- a/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp +++ b/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp @@ -252,9 +252,6 @@ PassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, const Strin PassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, PassRefPtr<DOMStringList> keyPath, const Dictionary& options, ExceptionCode& ec) { - // FIXME: Binding code for DOMString[] should not match null. http://webkit.org/b/84217 - if (!keyPath) - return createIndex(name, IDBKeyPath("null"), options, ec); return createIndex(name, IDBKeyPath(*keyPath), options, ec); } @@ -290,7 +287,7 @@ PassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, const IDBKe options.get("multiEntry", multiEntry); if (keyPath.type() == IDBKeyPath::ArrayType && multiEntry) { - ec = IDBDatabaseException::IDB_NOT_SUPPORTED_ERR; + ec = IDBDatabaseException::IDB_INVALID_ACCESS_ERR; return 0; } diff --git a/Source/WebCore/Modules/indexeddb/IDBObjectStore.h b/Source/WebCore/Modules/indexeddb/IDBObjectStore.h index 67b36f995..ef7c063b8 100644 --- a/Source/WebCore/Modules/indexeddb/IDBObjectStore.h +++ b/Source/WebCore/Modules/indexeddb/IDBObjectStore.h @@ -102,6 +102,9 @@ public: IDBObjectStoreMetadata metadata() const { return m_metadata; } void setMetadata(const IDBObjectStoreMetadata& metadata) { m_metadata = metadata; } + typedef Vector<RefPtr<IDBKey> > IndexKeys; + typedef HashMap<String, IndexKeys> IndexKeyMap; + private: IDBObjectStore(const IDBObjectStoreMetadata&, PassRefPtr<IDBObjectStoreBackendInterface>, IDBTransaction*); diff --git a/Source/WebCore/Modules/indexeddb/IDBObjectStore.idl b/Source/WebCore/Modules/indexeddb/IDBObjectStore.idl index 673e24c90..9ed1422b7 100644 --- a/Source/WebCore/Modules/indexeddb/IDBObjectStore.idl +++ b/Source/WebCore/Modules/indexeddb/IDBObjectStore.idl @@ -59,7 +59,7 @@ module storage { [CallWith=ScriptExecutionContext] IDBRequest openCursor(in IDBKey key, in [Optional] unsigned short direction) raises (IDBDatabaseException); - IDBIndex createIndex(in DOMString name, in DOMString[]? keyPath, in [Optional] Dictionary options) + IDBIndex createIndex(in DOMString name, in DOMString[] keyPath, in [Optional] Dictionary options) raises (IDBDatabaseException); IDBIndex createIndex(in DOMString name, in DOMString keyPath, in [Optional] Dictionary options) raises (IDBDatabaseException); diff --git a/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp b/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp index 474cdeb5b..ccad88920 100644 --- a/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp +++ b/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp @@ -57,7 +57,6 @@ IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(const IDBDatabaseBackendImp , m_name(name) , m_keyPath(keyPath) , m_autoIncrement(autoIncrement) - , m_autoIncrementNumber(-1) { loadIndexes(); } @@ -68,7 +67,6 @@ IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(const IDBDatabaseBackendImp , m_name(name) , m_keyPath(keyPath) , m_autoIncrement(autoIncrement) - , m_autoIncrementNumber(-1) { } @@ -141,9 +139,11 @@ static PassRefPtr<SerializedScriptValue> injectKeyIntoKeyPath(PassRefPtr<IDBKey> return IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue(key, value, keyPath); } +// FIXME: Remove this method when get-side key injection is the norm. void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, PutMode putMode, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec) { IDB_TRACE("IDBObjectStoreBackendImpl::put"); + IDB_TRACE("IDBObjectStoreBackendImpl::putWithIndexKeys"); ASSERT(transactionPtr->mode() != IDBTransaction::READ_ONLY); @@ -153,90 +153,137 @@ void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> prpValue, RefPtr<IDBCallbacks> callbacks = prpCallbacks; RefPtr<IDBTransactionBackendInterface> transaction = transactionPtr; + // Null pointers here signify that index keys should be generated as a part of this put. + OwnPtr<Vector<String> > nullIndexNames; + OwnPtr<Vector<IndexKeys> > nullIndexKeys; if (!transaction->scheduleTask( - createCallbackTask(&IDBObjectStoreBackendImpl::putInternal, objectStore, value, key, putMode, callbacks, transaction), - // FIXME: One of these per put() is overkill, since it's simply a cache invalidation. - createCallbackTask(&IDBObjectStoreBackendImpl::revertAutoIncrementKeyCache, objectStore))) + createCallbackTask(&IDBObjectStoreBackendImpl::putInternal, objectStore, value, key, putMode, callbacks, transaction, nullIndexNames.release(), nullIndexKeys.release()))) ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; } -void IDBObjectStoreBackendImpl::revertAutoIncrementKeyCache(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore) +void IDBObjectStoreBackendImpl::putWithIndexKeys(PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, PutMode putMode, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, const Vector<String>& indexNames, const Vector<IndexKeys>& indexKeys, ExceptionCode& ec) { - objectStore->resetAutoIncrementKeyCache(); + IDB_TRACE("IDBObjectStoreBackendImpl::putWithIndexKeys"); + + ASSERT(transactionPtr->mode() != IDBTransaction::READ_ONLY); + + RefPtr<IDBObjectStoreBackendImpl> objectStore = this; + RefPtr<SerializedScriptValue> value = prpValue; + RefPtr<IDBKey> key = prpKey; + RefPtr<IDBCallbacks> callbacks = prpCallbacks; + RefPtr<IDBTransactionBackendInterface> transaction = transactionPtr; + + OwnPtr<Vector<String> > newIndexNames = adoptPtr(new Vector<String>(indexNames)); + OwnPtr<Vector<IndexKeys> > newIndexKeys = adoptPtr(new Vector<IndexKeys>(indexKeys)); + + if (!transaction->scheduleTask( + createCallbackTask(&IDBObjectStoreBackendImpl::putInternal, objectStore, value, key, putMode, callbacks, transaction, newIndexNames.release(), newIndexKeys.release()))) + ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; } namespace { class IndexWriter { public: - explicit IndexWriter(PassRefPtr<IDBIndexBackendImpl> index) - : m_index(index) - { - } + explicit IndexWriter(const IDBIndexMetadata& indexMetadata) + : m_indexMetadata(indexMetadata) + { } + + IndexWriter(const IDBIndexMetadata& indexMetadata, + const IDBObjectStoreBackendInterface::IndexKeys& indexKeys) + : m_indexMetadata(indexMetadata) + , m_indexKeys(indexKeys) + { } - bool loadIndexKeysForValue(SerializedScriptValue* objectValue, const IDBKey* primaryKey = 0, String* errorMessage = 0) + bool generateIndexKeysForValue(SerializedScriptValue* objectValue) { m_indexKeys.clear(); - RefPtr<IDBKey> indexKey = fetchKeyFromKeyPath(objectValue, m_index->keyPath()); + RefPtr<IDBKey> indexKey = fetchKeyFromKeyPath(objectValue, m_indexMetadata.keyPath); if (!indexKey) return true; - if (!m_index->multiEntry() || indexKey->type() != IDBKey::ArrayType) { + if (!m_indexMetadata.multiEntry || indexKey->type() != IDBKey::ArrayType) { if (!indexKey->isValid()) return true; - if (!m_index->addingKeyAllowed(indexKey.get(), primaryKey)) { - if (errorMessage) - *errorMessage = String::format("Unable to add key to index '%s': the key does not satisfy its uniqueness requirements.", - m_index->name().utf8().data()); - return false; - } m_indexKeys.append(indexKey); } else { - ASSERT(m_index->multiEntry()); + ASSERT(m_indexMetadata.multiEntry); ASSERT(indexKey->type() == IDBKey::ArrayType); indexKey = IDBKey::createMultiEntryArray(indexKey->array()); for (size_t i = 0; i < indexKey->array().size(); ++i) { - if (!m_index->addingKeyAllowed(indexKey->array()[i].get(), primaryKey)) { - if (errorMessage) - *errorMessage = String::format("Unable to add key to index '%s': at least one key does not satisfy the uniqueness requirements.", - m_index->name().utf8().data()); - return false; - } m_indexKeys.append(indexKey->array()[i]); } } return true; } - bool writeIndexKeys(const IDBBackingStore::ObjectStoreRecordIdentifier* recordIdentifier, IDBBackingStore& backingStore, int64_t databaseId, int64_t objectStoreId, String* errorMessage = 0) + bool verifyIndexKeys(IDBBackingStore& backingStore, + int64_t databaseId, int64_t objectStoreId, int64_t indexId, + const IDBKey* primaryKey = 0, String* errorMessage = 0) + { + for (size_t i = 0; i < m_indexKeys.size(); ++i) { + if (!addingKeyAllowed(backingStore, databaseId, objectStoreId, indexId, + (m_indexKeys)[i].get(), primaryKey)) { + if (errorMessage) + *errorMessage = String::format("Unable to add key to index '%s': at least one key does not satisfy the uniqueness requirements.", + m_indexMetadata.name.utf8().data()); + return false; + } + } + return true; + } + + bool writeIndexKeys(const IDBBackingStore::ObjectStoreRecordIdentifier* recordIdentifier, IDBBackingStore& backingStore, int64_t databaseId, int64_t objectStoreId, int64_t indexId) const { for (size_t i = 0; i < m_indexKeys.size(); ++i) { - if (!backingStore.deleteIndexDataForRecord(databaseId, objectStoreId, m_index->id(), recordIdentifier)) + if (!backingStore.deleteIndexDataForRecord(databaseId, objectStoreId, indexId, recordIdentifier)) return false; - if (!backingStore.putIndexDataForRecord(databaseId, objectStoreId, m_index->id(), *m_indexKeys[i].get(), recordIdentifier)) + if (!backingStore.putIndexDataForRecord(databaseId, objectStoreId, indexId, *(m_indexKeys)[i].get(), recordIdentifier)) return false; } return true; } + const String& indexName() const { return m_indexMetadata.name; } + private: - RefPtr<IDBIndexBackendImpl> m_index; - Vector<RefPtr<IDBKey> > m_indexKeys; + + bool addingKeyAllowed(IDBBackingStore& backingStore, + int64_t databaseId, int64_t objectStoreId, int64_t indexId, + const IDBKey* indexKey, const IDBKey* primaryKey) + { + if (!m_indexMetadata.unique) + return true; + + RefPtr<IDBKey> foundPrimaryKey; + bool found = backingStore.keyExistsInIndex(databaseId, objectStoreId, indexId, *indexKey, foundPrimaryKey); + if (!found) + return true; + if (primaryKey && foundPrimaryKey->isEqual(primaryKey)) + return true; + return false; + } + const IDBIndexMetadata m_indexMetadata; + IDBObjectStoreBackendInterface::IndexKeys m_indexKeys; }; } -void IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction) +void IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction, PassOwnPtr<Vector<String> > popIndexNames, PassOwnPtr<Vector<IndexKeys> > popIndexKeys) { IDB_TRACE("IDBObjectStoreBackendImpl::putInternal"); ASSERT(transaction->mode() != IDBTransaction::READ_ONLY); RefPtr<SerializedScriptValue> value = prpValue; RefPtr<IDBKey> key = prpKey; + OwnPtr<Vector<String> > indexNames = popIndexNames; + OwnPtr<Vector<IndexKeys> > indexKeys = popIndexKeys; + ASSERT((!indexNames && !indexKeys) || indexNames->size() == indexKeys->size()); + const bool autoIncrement = objectStore->autoIncrement(); + bool keyWasGenerated = false; if (putMode != CursorUpdate) { - const bool autoIncrement = objectStore->autoIncrement(); const bool hasKeyPath = !objectStore->m_keyPath.isNull(); if (hasKeyPath) { ASSERT(!key); @@ -246,16 +293,17 @@ void IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr< } if (autoIncrement) { if (!key) { - RefPtr<IDBKey> autoIncKey = objectStore->genAutoIncrementKey(); + RefPtr<IDBKey> autoIncKey = objectStore->generateKey(); + keyWasGenerated = true; if (!autoIncKey->isValid()) { callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "Maximum key generator value reached.")); return; } + // FIXME: Remove this when get-side key injection is the norm. if (hasKeyPath) { RefPtr<SerializedScriptValue> valueAfterInjection = injectKeyIntoKeyPath(autoIncKey, value, objectStore->m_keyPath); ASSERT(valueAfterInjection); if (!valueAfterInjection) { - objectStore->resetAutoIncrementKeyCache(); // Checks in put() ensure this should only happen if I/O error occurs. callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error inserting generated key into the object.")); return; @@ -263,9 +311,6 @@ void IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr< value = valueAfterInjection; } key = autoIncKey; - } else { - // FIXME: Logic to update generator state should go here. Currently it does a scan. - objectStore->resetAutoIncrementKeyCache(); } } } @@ -274,22 +319,36 @@ void IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr< RefPtr<IDBBackingStore::ObjectStoreRecordIdentifier> recordIdentifier = objectStore->backingStore()->createInvalidRecordIdentifier(); if (putMode == AddOnly && objectStore->backingStore()->keyExistsInObjectStore(objectStore->databaseId(), objectStore->id(), *key, recordIdentifier.get())) { - objectStore->resetAutoIncrementKeyCache(); callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::CONSTRAINT_ERR, "Key already exists in the object store.")); return; } Vector<OwnPtr<IndexWriter> > indexWriters; + HashMap<String, IndexKeys> indexKeyMap; + if (indexKeys) { + for (size_t i = 0; i < indexNames->size(); ++i) + indexKeyMap.add(indexNames->at(i), indexKeys->at(i)); + } + for (IndexMap::iterator it = objectStore->m_indexes.begin(); it != objectStore->m_indexes.end(); ++it) { const RefPtr<IDBIndexBackendImpl>& index = it->second; if (!index->hasValidId()) continue; // The index object has been created, but does not exist in the database yet. - OwnPtr<IndexWriter> indexWriter(adoptPtr(new IndexWriter(index))); + OwnPtr<IndexWriter> indexWriter; + // FIXME: Turn this into an ASSERT(indexKeys) when get-side key injection is the norm. + if (indexKeys) + indexWriter = adoptPtr(new IndexWriter(index->metadata(), indexKeyMap.get(it->first))); + else { + indexWriter = adoptPtr(new IndexWriter(index->metadata())); + indexWriter->generateIndexKeysForValue(value.get()); + } String errorMessage; - if (!indexWriter->loadIndexKeysForValue(value.get(), key.get(), &errorMessage)) { - objectStore->resetAutoIncrementKeyCache(); + if (!indexWriter->verifyIndexKeys(*objectStore->backingStore(), + objectStore->databaseId(), + objectStore->id(), + index->id(), key.get(), &errorMessage)) { callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, errorMessage)); return; } @@ -306,16 +365,23 @@ void IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr< } for (size_t i = 0; i < indexWriters.size(); ++i) { - if (!indexWriters[i]->writeIndexKeys(recordIdentifier.get(), - *objectStore->backingStore(), objectStore->databaseId(), - objectStore->m_id)) { + IndexWriter* indexWriter = indexWriters[i].get(); + if (!indexWriter->writeIndexKeys(recordIdentifier.get(), + *objectStore->backingStore(), + objectStore->databaseId(), + objectStore->m_id, + objectStore->m_indexes.get(indexWriter->indexName())->id())) { + callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Error writing data to stable storage.")); transaction->abort(); return; } } - callbacks->onSuccess(key.get()); + if (autoIncrement && putMode != CursorUpdate && key->type() == IDBKey::NumberType) + objectStore->updateKeyGenerator(key.get(), !keyWasGenerated); + + callbacks->onSuccess(key.release()); } void IDBObjectStoreBackendImpl::deleteFunction(PassRefPtr<IDBKeyRange> prpKeyRange, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction, ExceptionCode& ec) @@ -383,33 +449,36 @@ void IDBObjectStoreBackendImpl::clearInternal(ScriptExecutionContext*, PassRefPt namespace { class PopulateIndexCallback : public IDBBackingStore::ObjectStoreRecordCallback { public: - PopulateIndexCallback(IDBBackingStore& backingStore, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBIndexBackendImpl> index) + PopulateIndexCallback(IDBBackingStore& backingStore, const IDBIndexMetadata& indexMetadata, int64_t databaseId, int64_t objectStoreId, int64_t indexId) : m_backingStore(backingStore) , m_databaseId(databaseId) , m_objectStoreId(objectStoreId) - , m_writer(index) + , m_indexId(indexId) + , m_writer(indexMetadata) { } virtual bool callback(const IDBBackingStore::ObjectStoreRecordIdentifier* recordIdentifier, const String& value) { RefPtr<SerializedScriptValue> objectValue = SerializedScriptValue::createFromWire(value); - if (!m_writer.loadIndexKeysForValue(objectValue.get())) + m_writer.generateIndexKeysForValue(objectValue.get()); + if (!m_writer.verifyIndexKeys(m_backingStore, m_databaseId, m_objectStoreId, m_indexId)) return false; - return m_writer.writeIndexKeys(recordIdentifier, m_backingStore, m_databaseId, m_objectStoreId); + return m_writer.writeIndexKeys(recordIdentifier, m_backingStore, m_databaseId, m_objectStoreId, m_indexId); } private: IDBBackingStore& m_backingStore; int64_t m_databaseId; int64_t m_objectStoreId; + int64_t m_indexId; IndexWriter m_writer; }; } bool IDBObjectStoreBackendImpl::populateIndex(IDBBackingStore& backingStore, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBIndexBackendImpl> index) { - PopulateIndexCallback callback(backingStore, databaseId, objectStoreId, index); + PopulateIndexCallback callback(backingStore, index->metadata(), databaseId, objectStoreId, index->id()); if (!backingStore.forEachObjectStoreRecord(databaseId, objectStoreId, callback)) return false; return true; @@ -576,18 +645,20 @@ void IDBObjectStoreBackendImpl::addIndexToMap(ScriptExecutionContext*, PassRefPt objectStore->m_indexes.set(indexPtr->name(), indexPtr); } -PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::genAutoIncrementKey() +PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::generateKey() { - const int64_t kMaxGeneratorValue = 9007199254740992LL; // Maximum integer storable as ECMAScript number. - if (m_autoIncrementNumber > kMaxGeneratorValue) + const int64_t maxGeneratorValue = 9007199254740992LL; // Maximum integer storable as ECMAScript number. + int64_t currentNumber = backingStore()->getKeyGeneratorCurrentNumber(databaseId(), id()); + if (currentNumber < 0 || currentNumber > maxGeneratorValue) return IDBKey::createInvalid(); - if (m_autoIncrementNumber > 0) - return IDBKey::createNumber(m_autoIncrementNumber++); - m_autoIncrementNumber = backingStore()->nextAutoIncrementNumber(databaseId(), id()); - if (m_autoIncrementNumber > kMaxGeneratorValue) - return IDBKey::createInvalid(); - return IDBKey::createNumber(m_autoIncrementNumber++); + return IDBKey::createNumber(currentNumber); +} + +void IDBObjectStoreBackendImpl::updateKeyGenerator(const IDBKey* key, bool checkCurrent) +{ + ASSERT(key && key->type() == IDBKey::NumberType); + backingStore()->maybeUpdateKeyGeneratorCurrentNumber(databaseId(), id(), static_cast<int64_t>(floor(key->number())) + 1, checkCurrent); } diff --git a/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.h b/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.h index 1e39ddac3..a37c67e7f 100644 --- a/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.h +++ b/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.h @@ -67,6 +67,7 @@ public: virtual void get(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&); virtual void put(PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, PutMode, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&); + virtual void putWithIndexKeys(PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, PutMode, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, const Vector<String>&, const Vector<IndexKeys>&, ExceptionCode&); virtual void deleteFunction(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&); virtual void clear(PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&); @@ -88,11 +89,11 @@ private: IDBObjectStoreBackendImpl(const IDBDatabaseBackendImpl*, const String& name, const IDBKeyPath&, bool autoIncrement); void loadIndexes(); - PassRefPtr<IDBKey> genAutoIncrementKey(); - void resetAutoIncrementKeyCache() { m_autoIncrementNumber = -1; } + PassRefPtr<IDBKey> generateKey(); + void updateKeyGenerator(const IDBKey*, bool checkCurrent); static void getInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>); - static void putInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, PutMode, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBTransactionBackendInterface>); + static void putInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, PutMode, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBTransactionBackendInterface>, PassOwnPtr<Vector<String> > popIndexNames, PassOwnPtr<Vector<IndexKeys> >); static void deleteInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>); static void clearInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBCallbacks>); static void createIndexInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBIndexBackendImpl>, PassRefPtr<IDBTransactionBackendInterface>); @@ -103,7 +104,6 @@ private: // These are used as setVersion transaction abort tasks. static void removeIndexFromMap(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBIndexBackendImpl>); static void addIndexToMap(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBIndexBackendImpl>); - static void revertAutoIncrementKeyCache(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>); PassRefPtr<IDBBackingStore> backingStore() const { return m_database->backingStore(); } int64_t databaseId() const { return m_database->id(); } @@ -116,7 +116,6 @@ private: typedef HashMap<String, RefPtr<IDBIndexBackendImpl> > IndexMap; IndexMap m_indexes; - int64_t m_autoIncrementNumber; }; } // namespace WebCore diff --git a/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendInterface.h b/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendInterface.h index 07f9f7260..37d3ee0f9 100644 --- a/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendInterface.h +++ b/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendInterface.h @@ -55,7 +55,10 @@ public: AddOnly, CursorUpdate }; + typedef Vector<RefPtr<IDBKey> > IndexKeys; + virtual void put(PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, PutMode, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) = 0; + virtual void putWithIndexKeys(PassRefPtr<SerializedScriptValue>, PassRefPtr<IDBKey>, PutMode, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, const Vector<String>&, const Vector<IndexKeys>&, ExceptionCode&) = 0; virtual void deleteFunction(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) = 0; virtual void clear(PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) = 0; diff --git a/Source/WebCore/Modules/indexeddb/IDBRequest.cpp b/Source/WebCore/Modules/indexeddb/IDBRequest.cpp index 62d292340..54afe03a6 100644 --- a/Source/WebCore/Modules/indexeddb/IDBRequest.cpp +++ b/Source/WebCore/Modules/indexeddb/IDBRequest.cpp @@ -332,6 +332,7 @@ void IDBRequest::onSuccess(PassRefPtr<SerializedScriptValue> prpSerializedScript RefPtr<IDBKey> primaryKey = prpPrimaryKey; RefPtr<IDBKey> expectedKey = createIDBKeyFromSerializedValueAndKeyPath(serializedScriptValue, keyPath); + ASSERT(primaryKey); ASSERT(expectedKey->isEqual(primaryKey.get())); #endif onSuccess(serializedScriptValue.release()); @@ -438,25 +439,28 @@ bool IDBRequest::dispatchEvent(PassRefPtr<Event> event) if (cursorToNotify) cursorToNotify->postSuccessHandlerCallback(); - if (m_transaction && event->type() != eventNames().blockedEvent) { - // If an error event and the default wasn't prevented... - if (dontPreventDefault && event->type() == eventNames().errorEvent) { + if (m_transaction) { + if (event->type() == eventNames().errorEvent && dontPreventDefault && !m_requestAborted) { m_transaction->setError(m_error); m_transaction->abort(); } - m_transaction->backend()->didCompleteTaskEvents(); - } - if (m_transaction && m_readyState == DONE) - m_transaction->unregisterRequest(this); + if (event->type() != eventNames().blockedEvent) + m_transaction->backend()->didCompleteTaskEvents(); + + if (m_readyState == DONE) + m_transaction->unregisterRequest(this); + } return dontPreventDefault; } void IDBRequest::uncaughtExceptionInEventHandler() { - if (m_transaction) - m_transaction->backend()->abort(); + if (m_transaction && !m_requestAborted) { + m_transaction->setError(DOMError::create(IDBDatabaseException::getErrorName(IDBDatabaseException::IDB_ABORT_ERR))); + m_transaction->abort(); + } } void IDBRequest::enqueueEvent(PassRefPtr<Event> event) diff --git a/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp b/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp index c09aa0ece..5c2b0ecba 100644 --- a/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp +++ b/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp @@ -122,20 +122,6 @@ const String& IDBTransaction::mode() const return mode; } -IDBDatabase* IDBTransaction::db() const -{ - return m_database.get(); -} - -PassRefPtr<DOMError> IDBTransaction::error(ExceptionCode& ec) const -{ - if (m_state != Finished) { - ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; - return 0; - } - return m_error; -} - void IDBTransaction::setError(PassRefPtr<DOMError> error) { ASSERT(m_state != Finished); @@ -276,6 +262,9 @@ void IDBTransaction::onAbort() ASSERT(m_state != Finished); if (m_state != Finishing) { + // FIXME: Propagate true cause from back end (e.g. QuotaError, UnknownError, etc.) + setError(DOMError::create(IDBDatabaseException::getErrorName(IDBDatabaseException::UNKNOWN_ERR))); + // Abort was not triggered by front-end, so outstanding requests must // be aborted now. while (!m_requestList.isEmpty()) { diff --git a/Source/WebCore/Modules/indexeddb/IDBTransaction.h b/Source/WebCore/Modules/indexeddb/IDBTransaction.h index e5fba7cbe..30378627f 100644 --- a/Source/WebCore/Modules/indexeddb/IDBTransaction.h +++ b/Source/WebCore/Modules/indexeddb/IDBTransaction.h @@ -75,10 +75,8 @@ public: // Implement the IDBTransaction IDL const String& mode() const; - IDBDatabase* db() const; - PassRefPtr<DOMError> error(ExceptionCode&) const; - void setError(PassRefPtr<DOMError>); - + IDBDatabase* db() const { return m_database.get(); } + PassRefPtr<DOMError> error() const { return m_error; } PassRefPtr<IDBObjectStore> objectStore(const String& name, ExceptionCode&); void abort(); @@ -96,6 +94,7 @@ public: void objectStoreCreated(const String&, PassRefPtr<IDBObjectStore>); void objectStoreDeleted(const String&); void setActive(bool); + void setError(PassRefPtr<DOMError>); DEFINE_ATTRIBUTE_EVENT_LISTENER(abort); DEFINE_ATTRIBUTE_EVENT_LISTENER(complete); diff --git a/Source/WebCore/Modules/indexeddb/IDBTransaction.idl b/Source/WebCore/Modules/indexeddb/IDBTransaction.idl index a0e54c03e..dfa9ed9a1 100644 --- a/Source/WebCore/Modules/indexeddb/IDBTransaction.idl +++ b/Source/WebCore/Modules/indexeddb/IDBTransaction.idl @@ -39,13 +39,13 @@ module storage { // Properties readonly attribute DOMString mode; readonly attribute IDBDatabase db; - readonly attribute DOMError error - getter raises (IDBDatabaseException); + readonly attribute DOMError error; // Methods IDBObjectStore objectStore (in DOMString name) raises (IDBDatabaseException); void abort (); + // Events attribute EventListener onabort; attribute EventListener oncomplete; diff --git a/Source/WebCore/Modules/protocolhandler/NavigatorRegisterProtocolHandler.cpp b/Source/WebCore/Modules/protocolhandler/NavigatorRegisterProtocolHandler.cpp index 0d5eb89c9..650376a96 100644 --- a/Source/WebCore/Modules/protocolhandler/NavigatorRegisterProtocolHandler.cpp +++ b/Source/WebCore/Modules/protocolhandler/NavigatorRegisterProtocolHandler.cpp @@ -29,8 +29,6 @@ #if ENABLE(REGISTER_PROTOCOL_HANDLER) || ENABLE(CUSTOM_SCHEME_HANDLER) -#include "Chrome.h" -#include "ChromeClient.h" #include "Document.h" #include "ExceptionCode.h" #include "Frame.h" @@ -112,14 +110,20 @@ static bool verifyProtocolHandlerScheme(const String& scheme, ExceptionCode& ec) return false; } -NavigatorRegisterProtocolHandler::NavigatorRegisterProtocolHandler() +NavigatorRegisterProtocolHandler* NavigatorRegisterProtocolHandler::from(Page* page) { + return static_cast<NavigatorRegisterProtocolHandler*>(RefCountedSupplement<Page, NavigatorRegisterProtocolHandler>::from(page, NavigatorRegisterProtocolHandler::supplementName())); } NavigatorRegisterProtocolHandler::~NavigatorRegisterProtocolHandler() { } +PassRefPtr<NavigatorRegisterProtocolHandler> NavigatorRegisterProtocolHandler::create(RegisterProtocolHandlerClient* client) +{ + return adoptRef(new NavigatorRegisterProtocolHandler(client)); +} + #if ENABLE(REGISTER_PROTOCOL_HANDLER) void NavigatorRegisterProtocolHandler::registerProtocolHandler(Navigator* navigator, const String& scheme, const String& url, const String& title, ExceptionCode& ec) { @@ -138,27 +142,23 @@ void NavigatorRegisterProtocolHandler::registerProtocolHandler(Navigator* naviga if (!verifyProtocolHandlerScheme(scheme, ec)) return; - Page* page = navigator->frame()->page(); - if (!page) - return; - - page->chrome()->client()->registerProtocolHandler(scheme, baseURL, url, navigator->frame()->displayStringModifiedByEncoding(title)); + NavigatorRegisterProtocolHandler::from(navigator->frame()->page())->client()->registerProtocolHandler(scheme, baseURL, url, navigator->frame()->displayStringModifiedByEncoding(title)); } #endif #if ENABLE(CUSTOM_SCHEME_HANDLER) -static String customHandlersStateString(const ChromeClient::CustomHandlersState state) +static String customHandlersStateString(const RegisterProtocolHandlerClient::CustomHandlersState state) { DEFINE_STATIC_LOCAL(const String, newHandler, ("new")); DEFINE_STATIC_LOCAL(const String, registeredHandler, ("registered")); DEFINE_STATIC_LOCAL(const String, declinedHandler, ("declined")); switch (state) { - case ChromeClient::CustomHandlersNew: + case RegisterProtocolHandlerClient::CustomHandlersNew: return newHandler; - case ChromeClient::CustomHandlersRegistered: + case RegisterProtocolHandlerClient::CustomHandlersRegistered: return registeredHandler; - case ChromeClient::CustomHandlersDeclined: + case RegisterProtocolHandlerClient::CustomHandlersDeclined: return declinedHandler; } @@ -182,11 +182,7 @@ String NavigatorRegisterProtocolHandler::isProtocolHandlerRegistered(Navigator* if (!verifyProtocolHandlerScheme(scheme, ec)) return declined; - Page* page = navigator->frame()->page(); - if (!page) - return declined; - - return customHandlersStateString(page->chrome()->client()->isProtocolHandlerRegistered(scheme, baseURL, url)); + return customHandlersStateString(NavigatorRegisterProtocolHandler::from(navigator->frame()->page())->client()->isProtocolHandlerRegistered(scheme, baseURL, url)); } void NavigatorRegisterProtocolHandler::unregisterProtocolHandler(Navigator* navigator, const String& scheme, const String& url, ExceptionCode& ec) @@ -203,14 +199,21 @@ void NavigatorRegisterProtocolHandler::unregisterProtocolHandler(Navigator* navi if (!verifyProtocolHandlerScheme(scheme, ec)) return; - Page* page = navigator->frame()->page(); - if (!page) - return; - - page->chrome()->client()->unregisterProtocolHandler(scheme, baseURL, url); + NavigatorRegisterProtocolHandler::from(navigator->frame()->page())->client()->unregisterProtocolHandler(scheme, baseURL, url); } #endif +const AtomicString& NavigatorRegisterProtocolHandler::supplementName() +{ + DEFINE_STATIC_LOCAL(AtomicString, name, ("NavigatorRegisterProtocolHandler")); + return name; +} + +void provideRegisterProtocolHandlerTo(Page* page, RegisterProtocolHandlerClient* client) +{ + RefCountedSupplement<Page, NavigatorRegisterProtocolHandler>::provideTo(page, NavigatorRegisterProtocolHandler::supplementName(), NavigatorRegisterProtocolHandler::create(client)); +} + } // namespace WebCore #endif // ENABLE(REGISTER_PROTOCOL_HANDLER) || ENABLE(CUSTOM_SCHEME_HANDLER) diff --git a/Source/WebCore/Modules/protocolhandler/NavigatorRegisterProtocolHandler.h b/Source/WebCore/Modules/protocolhandler/NavigatorRegisterProtocolHandler.h index 2193e01f4..23b3d1b55 100644 --- a/Source/WebCore/Modules/protocolhandler/NavigatorRegisterProtocolHandler.h +++ b/Source/WebCore/Modules/protocolhandler/NavigatorRegisterProtocolHandler.h @@ -29,17 +29,25 @@ #if ENABLE(REGISTER_PROTOCOL_HANDLER) || ENABLE(CUSTOM_SCHEME_HANDLER) +#include "RefCountedSupplement.h" +#include "RegisterProtocolHandlerClient.h" #include <wtf/PassRefPtr.h> #include <wtf/text/WTFString.h> namespace WebCore { +class Page; class Navigator; typedef int ExceptionCode; -class NavigatorRegisterProtocolHandler { +class NavigatorRegisterProtocolHandler : public RefCountedSupplement<Page, NavigatorRegisterProtocolHandler> { public: + virtual ~NavigatorRegisterProtocolHandler(); + + static const AtomicString& supplementName(); + static NavigatorRegisterProtocolHandler* from(Page*); + #if ENABLE(REGISTER_PROTOCOL_HANDLER) static void registerProtocolHandler(Navigator*, const String& scheme, const String& url, const String& title, ExceptionCode&); #endif @@ -49,9 +57,16 @@ public: static void unregisterProtocolHandler(Navigator*, const String& scheme, const String& url, ExceptionCode&); #endif + static PassRefPtr<NavigatorRegisterProtocolHandler> create(RegisterProtocolHandlerClient*); + private: - NavigatorRegisterProtocolHandler(); - ~NavigatorRegisterProtocolHandler(); + explicit NavigatorRegisterProtocolHandler(RegisterProtocolHandlerClient* client) + : m_client(client) + { } + + RegisterProtocolHandlerClient* client() { return m_client; } + + RegisterProtocolHandlerClient* m_client; }; } // namespace WebCore diff --git a/Source/WebCore/Modules/protocolhandler/RegisterProtocolHandlerClient.h b/Source/WebCore/Modules/protocolhandler/RegisterProtocolHandlerClient.h new file mode 100644 index 000000000..ad641b307 --- /dev/null +++ b/Source/WebCore/Modules/protocolhandler/RegisterProtocolHandlerClient.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2012 Samsung Electronics. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef RegisterProtocolHandlerClient_h +#define RegisterProtocolHandlerClient_h + +#if ENABLE(REGISTER_PROTOCOL_HANDLER) || ENABLE(CUSTOM_SCHEME_HANDLER) + +#include <wtf/text/WTFString.h> + +namespace WebCore { + +class Page; + +class RegisterProtocolHandlerClient { +public: + virtual ~RegisterProtocolHandlerClient() { } + +#if ENABLE(REGISTER_PROTOCOL_HANDLER) + virtual void registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title) = 0; +#endif + +#if ENABLE(CUSTOM_SCHEME_HANDLER) + enum CustomHandlersState { + CustomHandlersNew, + CustomHandlersRegistered, + CustomHandlersDeclined + }; + + virtual CustomHandlersState isProtocolHandlerRegistered(const String& scheme, const String& baseURL, const String& url) = 0; + virtual void unregisterProtocolHandler(const String& scheme, const String& baseURL, const String& url) = 0; +#endif +}; + +void provideRegisterProtocolHandlerTo(Page*, RegisterProtocolHandlerClient*); + +} + +#endif +#endif // RegisterProtocolHandlerClient_h diff --git a/Source/WebCore/Target.pri b/Source/WebCore/Target.pri index 5dac2b05d..3244bbc04 100644 --- a/Source/WebCore/Target.pri +++ b/Source/WebCore/Target.pri @@ -10,7 +10,7 @@ TARGET = WebCore include(WebCore.pri) WEBKIT += wtf -!v8: WEBKIT += javascriptcore +WEBKIT += javascriptcore CONFIG += staticlib @@ -70,339 +70,172 @@ SOURCES += \ bindings/generic/ActiveDOMCallback.cpp \ bindings/generic/RuntimeEnabledFeatures.cpp -v8 { - include($$PWD/../JavaScriptCore/yarr/yarr.pri) - - SOURCES += \ - platform/qt/PlatformSupportQt.cpp \ - bindings/generic/BindingSecurityBase.cpp \ - \ - bindings/v8/WorldContextHandle.cpp \ - bindings/v8/V8IsolatedContext.cpp \ - bindings/v8/custom/V8HistoryCustom.cpp \ - bindings/v8/custom/V8PopStateEventCustom.cpp \ - bindings/v8/ScriptGCEvent.cpp - - SOURCES += \ - bindings/v8/custom/V8ArrayBufferCustom.cpp \ - bindings/v8/custom/V8ArrayBufferViewCustom.cpp \ - bindings/v8/custom/V8BlobCustom.cpp \ - bindings/v8/custom/V8CustomXPathNSResolver.cpp \ - bindings/v8/custom/V8DataViewCustom.cpp \ - bindings/v8/custom/V8DeviceMotionEventCustom.cpp \ - bindings/v8/custom/V8DeviceOrientationEventCustom.cpp \ - bindings/v8/custom/V8Float32ArrayCustom.cpp \ - bindings/v8/custom/V8Float64ArrayCustom.cpp \ - bindings/v8/custom/V8Int8ArrayCustom.cpp \ - bindings/v8/custom/V8Int16ArrayCustom.cpp \ - bindings/v8/custom/V8Int32ArrayCustom.cpp \ - bindings/v8/custom/V8Uint8ArrayCustom.cpp \ - bindings/v8/custom/V8Uint16ArrayCustom.cpp \ - bindings/v8/custom/V8Uint32ArrayCustom.cpp \ - bindings/v8/custom/V8Uint8ClampedArrayCustom.cpp \ - \ - bindings/v8/DateExtension.cpp \ - bindings/v8/DOMData.cpp \ - bindings/v8/DOMDataStore.cpp \ - bindings/v8/NPV8Object.cpp \ - bindings/v8/NPObjectWrapper.cpp \ - bindings/v8/Dictionary.cpp \ - bindings/v8/PageScriptDebugServer.cpp \ - bindings/v8/RetainedDOMInfo.cpp \ - bindings/v8/ScheduledAction.cpp \ - bindings/v8/ScopedDOMDataStore.cpp \ - bindings/v8/ScriptCachedFrameData.cpp \ - bindings/v8/ScriptCallStackFactory.cpp \ - bindings/ScriptControllerBase.cpp \ - bindings/v8/ScriptController.cpp \ - bindings/v8/ScriptControllerQt.cpp \ - bindings/v8/ScriptEventListener.cpp \ - bindings/v8/ScriptFunctionCall.cpp \ - bindings/v8/ScriptInstance.cpp \ - bindings/v8/ScriptObject.cpp \ - bindings/v8/ScriptScope.cpp \ - bindings/v8/ScriptState.cpp \ - bindings/v8/ScriptValue.cpp \ - bindings/v8/StaticDOMDataStore.cpp \ - bindings/v8/SerializedScriptValue.cpp \ - bindings/v8/V8AbstractEventListener.cpp \ - bindings/v8/V8Binding.cpp \ - bindings/v8/V8BindingPerContextData.cpp \ - bindings/v8/V8Collection.cpp \ - bindings/v8/V8DOMMap.cpp \ - bindings/v8/V8DOMWrapper.cpp \ - bindings/v8/V8EventListener.cpp \ - bindings/v8/V8EventListenerList.cpp \ - bindings/v8/V8GCController.cpp \ - bindings/v8/V8GCForContextDispose.cpp \ - bindings/v8/V8Helpers.cpp \ - bindings/v8/V8HiddenPropertyName.cpp \ - bindings/v8/IsolatedWorld.cpp \ - bindings/v8/V8LazyEventListener.cpp \ - bindings/v8/V8NPObject.cpp \ - bindings/v8/V8NPUtils.cpp \ - bindings/v8/V8NodeFilterCondition.cpp \ - bindings/v8/V8Proxy.cpp \ - bindings/v8/V8RecursionScope.cpp \ - bindings/v8/V8Utilities.cpp \ - bindings/v8/V8WindowErrorHandler.cpp \ - bindings/v8/V8WorkerContextEventListener.cpp \ - bindings/v8/WorkerContextExecutionProxy.cpp \ - bindings/v8/WorkerScriptDebugServer.cpp \ - bindings/v8/WorkerScriptController.cpp \ - \ - bindings/v8/V8DOMWindowShell.cpp \ - bindings/v8/DOMWrapperWorld.cpp \ - \ - bindings/v8/npruntime.cpp \ - \ - bindings/v8/custom/V8CSSRuleCustom.cpp \ - bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp \ - bindings/v8/custom/V8CSSValueCustom.cpp \ - bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp \ - bindings/v8/custom/V8ClipboardCustom.cpp \ - bindings/v8/custom/V8CoordinatesCustom.cpp \ - bindings/v8/custom/V8ImageDataCustom.cpp \ - bindings/v8/custom/V8InjectedScriptHostCustom.cpp \ - bindings/v8/custom/V8InjectedScriptManager.cpp \ - bindings/v8/custom/V8InspectorFrontendHostCustom.cpp \ - bindings/v8/custom/V8DOMStringMapCustom.cpp - - SOURCES += \ - bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp \ - bindings/v8/custom/V8CustomVoidCallback.cpp \ - bindings/v8/custom/V8DOMFormDataCustom.cpp \ - bindings/v8/custom/V8DOMWindowCustom.cpp \ - bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp \ - bindings/v8/custom/V8DocumentCustom.cpp \ - bindings/v8/custom/V8DocumentLocationCustom.cpp \ - bindings/v8/custom/V8EventCustom.cpp \ - bindings/v8/custom/V8FileReaderCustom.cpp \ - bindings/v8/custom/V8HTMLAllCollectionCustom.cpp +SOURCES += \ + bindings/ScriptControllerBase.cpp \ + bindings/js/CallbackFunction.cpp \ + bindings/js/DOMObjectHashTableMap.cpp \ + bindings/js/DOMWrapperWorld.cpp \ + bindings/js/Dictionary.cpp \ + bindings/js/GCController.cpp \ + bindings/js/JSArrayBufferCustom.cpp \ + bindings/js/JSAttrCustom.cpp \ + bindings/js/JSBlobCustom.cpp \ + bindings/js/JSCDATASectionCustom.cpp \ + bindings/js/JSCSSFontFaceRuleCustom.cpp \ + bindings/js/JSCSSImportRuleCustom.cpp \ + bindings/js/JSCSSMediaRuleCustom.cpp \ + bindings/js/JSCSSPageRuleCustom.cpp \ + bindings/js/JSCSSRuleCustom.cpp \ + bindings/js/JSCSSRuleListCustom.cpp \ + bindings/js/JSCSSStyleDeclarationCustom.cpp \ + bindings/js/JSCSSStyleRuleCustom.cpp \ + bindings/js/JSCSSValueCustom.cpp \ + bindings/js/JSCallbackData.cpp \ + bindings/js/JSCanvasRenderingContext2DCustom.cpp \ + bindings/js/JSCanvasRenderingContextCustom.cpp \ + bindings/js/JSClipboardCustom.cpp \ + bindings/js/JSConsoleCustom.cpp \ + bindings/js/JSCoordinatesCustom.cpp \ + bindings/js/JSCustomVoidCallback.cpp \ + bindings/js/JSCustomXPathNSResolver.cpp \ + bindings/js/JSDictionary.cpp \ + bindings/js/JSDOMBinding.cpp \ + bindings/js/JSDOMFormDataCustom.cpp \ + bindings/js/JSDOMGlobalObject.cpp \ + bindings/js/JSDOMImplementationCustom.cpp \ + bindings/js/JSDOMMimeTypeArrayCustom.cpp \ + bindings/js/JSDOMPluginArrayCustom.cpp \ + bindings/js/JSDOMPluginCustom.cpp \ + bindings/js/JSDOMStringListCustom.cpp \ + bindings/js/JSDOMStringMapCustom.cpp \ + bindings/js/JSDOMTokenListCustom.cpp \ + bindings/js/JSDOMWindowBase.cpp \ + bindings/js/JSDOMWindowCustom.cpp \ + bindings/js/JSDOMWindowShell.cpp \ + bindings/js/JSDOMWindowWebAudioCustom.cpp \ + bindings/js/JSDOMWindowWebSocketCustom.cpp \ + bindings/js/JSDOMWrapper.cpp \ + bindings/js/JSDataViewCustom.cpp \ + bindings/js/JSDesktopNotificationsCustom.cpp \ + bindings/js/JSDeviceMotionEventCustom.cpp \ + bindings/js/JSDeviceOrientationEventCustom.cpp \ + bindings/js/JSDocumentCustom.cpp \ + bindings/js/JSElementCustom.cpp \ + bindings/js/JSErrorHandler.cpp \ + bindings/js/JSEventCustom.cpp \ + bindings/js/JSEventListener.cpp \ + bindings/js/JSEventTargetCustom.cpp \ + bindings/js/JSExceptionBase.cpp \ + bindings/js/JSFileReaderCustom.cpp \ + bindings/js/JSFloat32ArrayCustom.cpp \ + bindings/js/JSFloat64ArrayCustom.cpp \ + bindings/js/JSGeolocationCustom.cpp \ + bindings/js/JSHTMLAllCollectionCustom.cpp \ + bindings/js/JSHTMLAppletElementCustom.cpp \ + bindings/js/JSHTMLCanvasElementCustom.cpp \ + bindings/js/JSHTMLCollectionCustom.cpp \ + bindings/js/JSHTMLDocumentCustom.cpp \ + bindings/js/JSHTMLElementCustom.cpp \ + bindings/js/JSHTMLEmbedElementCustom.cpp \ + bindings/js/JSHTMLFormElementCustom.cpp \ + bindings/js/JSHTMLFrameElementCustom.cpp \ + bindings/js/JSHTMLFrameSetElementCustom.cpp \ + bindings/js/JSHTMLInputElementCustom.cpp \ + bindings/js/JSHTMLLinkElementCustom.cpp \ + bindings/js/JSHTMLMediaElementCustom.cpp \ + bindings/js/JSHTMLObjectElementCustom.cpp \ + bindings/js/JSHTMLOptionsCollectionCustom.cpp \ + bindings/js/JSHTMLOutputElementCustom.cpp \ + bindings/js/JSHTMLSelectElementCustom.cpp \ + bindings/js/JSHTMLStyleElementCustom.cpp \ + bindings/js/JSHistoryCustom.cpp \ + bindings/js/JSImageConstructor.cpp \ + bindings/js/JSImageDataCustom.cpp \ + bindings/js/JSInjectedScriptHostCustom.cpp \ + bindings/js/JSInjectedScriptManager.cpp \ + bindings/js/JSInspectorFrontendHostCustom.cpp \ + bindings/js/JSInt16ArrayCustom.cpp \ + bindings/js/JSInt32ArrayCustom.cpp \ + bindings/js/JSInt8ArrayCustom.cpp \ + bindings/js/JSLazyEventListener.cpp \ + bindings/js/JSLocationCustom.cpp \ + bindings/js/JSMainThreadExecState.cpp \ + bindings/js/JSMediaListCustom.cpp \ + bindings/js/JSMemoryInfoCustom.cpp \ + bindings/js/JSMessageChannelCustom.cpp \ + bindings/js/JSMessageEventCustom.cpp \ + bindings/js/JSMessagePortCustom.cpp \ + bindings/js/JSMessagePortCustom.h \ + bindings/js/JSMutationCallbackCustom.cpp \ + bindings/js/JSMutationObserverCustom.cpp \ + bindings/js/JSNamedNodeMapCustom.cpp \ + bindings/js/JSNodeCustom.cpp \ + bindings/js/JSNodeFilterCondition.cpp \ + bindings/js/JSNodeFilterCustom.cpp \ + bindings/js/JSNodeIteratorCustom.cpp \ + bindings/js/JSNodeListCustom.cpp \ + bindings/js/JSNotificationCustom.cpp \ + bindings/js/JSPluginElementFunctions.cpp \ + bindings/js/JSPopStateEventCustom.cpp \ + bindings/js/JSProcessingInstructionCustom.cpp \ + bindings/js/JSRequestAnimationFrameCallbackCustom.cpp \ + bindings/js/JSScriptProfileNodeCustom.cpp \ + bindings/js/JSStorageCustom.cpp \ + bindings/js/JSStyleSheetCustom.cpp \ + bindings/js/JSStyleSheetListCustom.cpp \ + bindings/js/JSTextCustom.cpp \ + bindings/js/JSTouchCustom.cpp \ + bindings/js/JSTouchListCustom.cpp \ + bindings/js/JSTreeWalkerCustom.cpp \ + bindings/js/JSUint16ArrayCustom.cpp \ + bindings/js/JSUint32ArrayCustom.cpp \ + bindings/js/JSUint8ArrayCustom.cpp \ + bindings/js/JSUint8ClampedArrayCustom.cpp \ + bindings/js/JSWebKitAnimationCustom.cpp \ + bindings/js/JSWebKitAnimationListCustom.cpp \ + bindings/js/JSWebKitCSSKeyframeRuleCustom.cpp \ + bindings/js/JSWebKitCSSKeyframesRuleCustom.cpp \ + bindings/js/JSWebKitPointCustom.cpp \ + bindings/js/JSXMLHttpRequestCustom.cpp \ + bindings/js/JSXMLHttpRequestUploadCustom.cpp \ + bindings/js/JSXPathResultCustom.cpp \ + bindings/js/PageScriptDebugServer.cpp \ + bindings/js/ScheduledAction.cpp \ + bindings/js/ScriptCachedFrameData.cpp \ + bindings/js/ScriptCallStackFactory.cpp \ + bindings/js/ScriptController.cpp \ + bindings/js/ScriptControllerQt.cpp \ + bindings/js/ScriptDebugServer.cpp \ + bindings/js/ScriptEventListener.cpp \ + bindings/js/ScriptFunctionCall.cpp \ + bindings/js/ScriptGCEvent.cpp \ + bindings/js/ScriptObject.cpp \ + bindings/js/ScriptProfile.cpp \ + bindings/js/ScriptState.cpp \ + bindings/js/ScriptValue.cpp \ + bindings/js/SerializedScriptValue.cpp \ + bridge/IdentifierRep.cpp \ + bridge/NP_jsobject.cpp \ + bridge/c/CRuntimeObject.cpp \ + bridge/c/c_class.cpp \ + bridge/c/c_instance.cpp \ + bridge/c/c_runtime.cpp \ + bridge/c/c_utility.cpp \ + bridge/jsc/BridgeJSC.cpp \ + bridge/npruntime.cpp \ + bridge/qt/qt_class.cpp \ + bridge/qt/qt_instance.cpp \ + bridge/qt/qt_pixmapruntime.cpp \ + bridge/runtime_array.cpp \ + bridge/runtime_method.cpp \ + bridge/runtime_object.cpp \ + bridge/runtime_root.cpp \ + testing/js/WebCoreTestSupport.cpp - SOURCES += \ - bindings/v8/custom/V8HTMLCanvasElementCustom.cpp \ - bindings/v8/custom/V8HTMLCollectionCustom.cpp \ - bindings/v8/custom/V8HTMLDocumentCustom.cpp \ - bindings/v8/custom/V8HTMLElementCustom.cpp \ - bindings/v8/custom/V8HTMLFormElementCustom.cpp \ - bindings/v8/custom/V8HTMLFrameElementCustom.cpp \ - bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp \ - bindings/v8/custom/V8HTMLImageElementConstructor.cpp \ - bindings/v8/custom/V8HTMLInputElementCustom.cpp \ - bindings/v8/custom/V8HTMLLinkElementCustom.cpp \ - bindings/v8/custom/V8HTMLMediaElementCustom.cpp \ - bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp \ - bindings/v8/custom/V8HTMLOutputElementCustom.cpp \ - bindings/v8/custom/V8HTMLPlugInElementCustom.cpp \ - bindings/v8/custom/V8HTMLSelectElementCustom.cpp \ - bindings/v8/custom/V8LocationCustom.cpp \ - bindings/v8/custom/V8MessageChannelConstructor.cpp \ - bindings/v8/custom/V8MessagePortCustom.cpp \ - bindings/v8/custom/V8MessageEventCustom.cpp \ - bindings/v8/custom/V8MutationCallbackCustom.cpp \ - bindings/v8/custom/V8MutationObserverCustom.cpp \ - bindings/v8/custom/V8NamedNodeMapCustom.cpp \ - bindings/v8/custom/V8NamedNodesCollection.cpp \ - bindings/v8/custom/V8NodeCustom.cpp \ - bindings/v8/custom/V8NodeListCustom.cpp \ - bindings/v8/custom/V8PerformanceCustom.cpp \ - bindings/v8/custom/V8PerformanceEntryCustom.cpp \ - bindings/v8/custom/V8SQLResultSetRowListCustom.cpp \ - bindings/v8/custom/V8SQLTransactionCustom.cpp \ - bindings/v8/custom/V8WebSocketCustom.cpp \ - \ - bindings/v8/custom/V8StorageCustom.cpp \ - bindings/v8/custom/V8StyleSheetCustom.cpp \ - bindings/v8/custom/V8StyleSheetListCustom.cpp \ - bindings/v8/custom/V8WebKitAnimationCustom.cpp \ - bindings/v8/custom/V8WebKitPointConstructor.cpp \ - bindings/v8/custom/V8WorkerContextCustom.cpp \ - bindings/v8/custom/V8WorkerCustom.cpp \ - bindings/v8/custom/V8XMLHttpRequestConstructor.cpp \ - bindings/v8/custom/V8XMLHttpRequestCustom.cpp \ - \ - bindings/v8/custom/V8SVGDocumentCustom.cpp \ - bindings/v8/custom/V8SVGElementCustom.cpp \ - bindings/v8/custom/V8SVGLengthCustom.cpp \ - bindings/v8/custom/V8SVGPathSegCustom.cpp \ - \ - bindings/v8/specialization/V8BindingState.cpp\ - \ - bindings/v8/custom/V8NotificationCustom.cpp \ - bindings/v8/custom/V8NotificationCenterCustom.cpp \ - bindings/v8/custom/V8ConsoleCustom.cpp \ - bindings/v8/custom/V8SQLTransactionSyncCustom.cpp \ - bindings/v8/V8WorkerContextErrorHandler.cpp \ - testing/v8/WebCoreTestSupport.cpp +haveQt(5) { + SOURCES += bridge/qt/qt_runtime.cpp } else { - SOURCES += \ - bindings/ScriptControllerBase.cpp \ - bindings/js/CallbackFunction.cpp \ - bindings/js/DOMObjectHashTableMap.cpp \ - bindings/js/DOMWrapperWorld.cpp \ - bindings/js/Dictionary.cpp \ - bindings/js/GCController.cpp \ - bindings/js/JSArrayBufferCustom.cpp \ - bindings/js/JSAttrCustom.cpp \ - bindings/js/JSBlobCustom.cpp \ - bindings/js/JSCDATASectionCustom.cpp \ - bindings/js/JSCSSFontFaceRuleCustom.cpp \ - bindings/js/JSCSSImportRuleCustom.cpp \ - bindings/js/JSCSSMediaRuleCustom.cpp \ - bindings/js/JSCSSPageRuleCustom.cpp \ - bindings/js/JSCSSRuleCustom.cpp \ - bindings/js/JSCSSRuleListCustom.cpp \ - bindings/js/JSCSSStyleDeclarationCustom.cpp \ - bindings/js/JSCSSStyleRuleCustom.cpp \ - bindings/js/JSCSSValueCustom.cpp \ - bindings/js/JSCallbackData.cpp \ - bindings/js/JSCanvasRenderingContext2DCustom.cpp \ - bindings/js/JSCanvasRenderingContextCustom.cpp \ - bindings/js/JSClipboardCustom.cpp \ - bindings/js/JSConsoleCustom.cpp \ - bindings/js/JSCoordinatesCustom.cpp \ - bindings/js/JSCustomVoidCallback.cpp \ - bindings/js/JSCustomXPathNSResolver.cpp \ - bindings/js/JSDictionary.cpp \ - bindings/js/JSDOMBinding.cpp \ - bindings/js/JSDOMFormDataCustom.cpp \ - bindings/js/JSDOMGlobalObject.cpp \ - bindings/js/JSDOMImplementationCustom.cpp \ - bindings/js/JSDOMMimeTypeArrayCustom.cpp \ - bindings/js/JSDOMPluginArrayCustom.cpp \ - bindings/js/JSDOMPluginCustom.cpp \ - bindings/js/JSDOMStringListCustom.cpp \ - bindings/js/JSDOMStringMapCustom.cpp \ - bindings/js/JSDOMTokenListCustom.cpp \ - bindings/js/JSDOMWindowBase.cpp \ - bindings/js/JSDOMWindowCustom.cpp \ - bindings/js/JSDOMWindowShell.cpp \ - bindings/js/JSDOMWindowWebAudioCustom.cpp \ - bindings/js/JSDOMWindowWebSocketCustom.cpp \ - bindings/js/JSDOMWrapper.cpp \ - bindings/js/JSDataViewCustom.cpp \ - bindings/js/JSDesktopNotificationsCustom.cpp \ - bindings/js/JSDeviceMotionEventCustom.cpp \ - bindings/js/JSDeviceOrientationEventCustom.cpp \ - bindings/js/JSDocumentCustom.cpp \ - bindings/js/JSElementCustom.cpp \ - bindings/js/JSErrorHandler.cpp \ - bindings/js/JSEventCustom.cpp \ - bindings/js/JSEventListener.cpp \ - bindings/js/JSEventTargetCustom.cpp \ - bindings/js/JSExceptionBase.cpp \ - bindings/js/JSFileReaderCustom.cpp \ - bindings/js/JSFloat32ArrayCustom.cpp \ - bindings/js/JSFloat64ArrayCustom.cpp \ - bindings/js/JSGeolocationCustom.cpp \ - bindings/js/JSHTMLAllCollectionCustom.cpp \ - bindings/js/JSHTMLAppletElementCustom.cpp \ - bindings/js/JSHTMLCanvasElementCustom.cpp \ - bindings/js/JSHTMLCollectionCustom.cpp \ - bindings/js/JSHTMLDocumentCustom.cpp \ - bindings/js/JSHTMLElementCustom.cpp \ - bindings/js/JSHTMLEmbedElementCustom.cpp \ - bindings/js/JSHTMLFormElementCustom.cpp \ - bindings/js/JSHTMLFrameElementCustom.cpp \ - bindings/js/JSHTMLFrameSetElementCustom.cpp \ - bindings/js/JSHTMLInputElementCustom.cpp \ - bindings/js/JSHTMLLinkElementCustom.cpp \ - bindings/js/JSHTMLMediaElementCustom.cpp \ - bindings/js/JSHTMLObjectElementCustom.cpp \ - bindings/js/JSHTMLOptionsCollectionCustom.cpp \ - bindings/js/JSHTMLOutputElementCustom.cpp \ - bindings/js/JSHTMLSelectElementCustom.cpp \ - bindings/js/JSHTMLStyleElementCustom.cpp \ - bindings/js/JSHistoryCustom.cpp \ - bindings/js/JSImageConstructor.cpp \ - bindings/js/JSImageDataCustom.cpp \ - bindings/js/JSInjectedScriptHostCustom.cpp \ - bindings/js/JSInjectedScriptManager.cpp \ - bindings/js/JSInspectorFrontendHostCustom.cpp \ - bindings/js/JSInt16ArrayCustom.cpp \ - bindings/js/JSInt32ArrayCustom.cpp \ - bindings/js/JSInt8ArrayCustom.cpp \ - bindings/js/JSLazyEventListener.cpp \ - bindings/js/JSLocationCustom.cpp \ - bindings/js/JSMainThreadExecState.cpp \ - bindings/js/JSMediaListCustom.cpp \ - bindings/js/JSMemoryInfoCustom.cpp \ - bindings/js/JSMessageChannelCustom.cpp \ - bindings/js/JSMessageEventCustom.cpp \ - bindings/js/JSMessagePortCustom.cpp \ - bindings/js/JSMessagePortCustom.h \ - bindings/js/JSMutationCallbackCustom.cpp \ - bindings/js/JSMutationObserverCustom.cpp \ - bindings/js/JSNamedNodeMapCustom.cpp \ - bindings/js/JSNodeCustom.cpp \ - bindings/js/JSNodeFilterCondition.cpp \ - bindings/js/JSNodeFilterCustom.cpp \ - bindings/js/JSNodeIteratorCustom.cpp \ - bindings/js/JSNodeListCustom.cpp \ - bindings/js/JSNotificationCustom.cpp \ - bindings/js/JSPluginElementFunctions.cpp \ - bindings/js/JSPopStateEventCustom.cpp \ - bindings/js/JSProcessingInstructionCustom.cpp \ - bindings/js/JSRequestAnimationFrameCallbackCustom.cpp \ - bindings/js/JSScriptProfileNodeCustom.cpp \ - bindings/js/JSStorageCustom.cpp \ - bindings/js/JSStyleSheetCustom.cpp \ - bindings/js/JSStyleSheetListCustom.cpp \ - bindings/js/JSTextCustom.cpp \ - bindings/js/JSTouchCustom.cpp \ - bindings/js/JSTouchListCustom.cpp \ - bindings/js/JSTreeWalkerCustom.cpp \ - bindings/js/JSUint16ArrayCustom.cpp \ - bindings/js/JSUint32ArrayCustom.cpp \ - bindings/js/JSUint8ArrayCustom.cpp \ - bindings/js/JSUint8ClampedArrayCustom.cpp \ - bindings/js/JSWebKitAnimationCustom.cpp \ - bindings/js/JSWebKitAnimationListCustom.cpp \ - bindings/js/JSWebKitCSSKeyframeRuleCustom.cpp \ - bindings/js/JSWebKitCSSKeyframesRuleCustom.cpp \ - bindings/js/JSWebKitPointCustom.cpp \ - bindings/js/JSXMLHttpRequestCustom.cpp \ - bindings/js/JSXMLHttpRequestUploadCustom.cpp \ - bindings/js/JSXPathResultCustom.cpp \ - bindings/js/PageScriptDebugServer.cpp \ - bindings/js/ScheduledAction.cpp \ - bindings/js/ScriptCachedFrameData.cpp \ - bindings/js/ScriptCallStackFactory.cpp \ - bindings/js/ScriptController.cpp \ - bindings/js/ScriptControllerQt.cpp \ - bindings/js/ScriptDebugServer.cpp \ - bindings/js/ScriptEventListener.cpp \ - bindings/js/ScriptFunctionCall.cpp \ - bindings/js/ScriptGCEvent.cpp \ - bindings/js/ScriptObject.cpp \ - bindings/js/ScriptProfile.cpp \ - bindings/js/ScriptState.cpp \ - bindings/js/ScriptValue.cpp \ - bindings/js/SerializedScriptValue.cpp \ - bridge/IdentifierRep.cpp \ - bridge/NP_jsobject.cpp \ - bridge/c/CRuntimeObject.cpp \ - bridge/c/c_class.cpp \ - bridge/c/c_instance.cpp \ - bridge/c/c_runtime.cpp \ - bridge/c/c_utility.cpp \ - bridge/jsc/BridgeJSC.cpp \ - bridge/npruntime.cpp \ - bridge/qt/qt_class.cpp \ - bridge/qt/qt_instance.cpp \ - bridge/qt/qt_pixmapruntime.cpp \ - bridge/runtime_array.cpp \ - bridge/runtime_method.cpp \ - bridge/runtime_object.cpp \ - bridge/runtime_root.cpp \ - testing/js/WebCoreTestSupport.cpp - - haveQt(5) { - SOURCES += bridge/qt/qt_runtime.cpp - } else { - SOURCES += bridge/qt/qt_runtime_qt4.cpp - } + SOURCES += bridge/qt/qt_runtime_qt4.cpp } SOURCES += \ @@ -511,6 +344,7 @@ SOURCES += \ css/WebKitCSSSVGDocumentValue.cpp \ css/WebKitCSSShaderValue.cpp \ css/WebKitCSSTransformValue.cpp \ + css/WrapShapeFunctions.cpp \ dom/ActiveDOMObject.cpp \ dom/Attr.cpp \ dom/BeforeTextInsertedEvent.cpp \ @@ -888,6 +722,7 @@ SOURCES += \ html/shadow/HTMLContentElement.cpp \ html/shadow/HTMLShadowElement.cpp \ html/shadow/InsertionPoint.cpp \ + html/shadow/ImageInnerElement.cpp \ html/shadow/MediaControls.cpp \ html/shadow/MediaControlRootElement.cpp \ html/shadow/MeterShadowElement.cpp \ @@ -1436,150 +1271,83 @@ HEADERS += \ bindings/generic/ActiveDOMCallback.h \ bindings/generic/RuntimeEnabledFeatures.h -v8 { - HEADERS += \ - bindings/v8/custom/V8CustomVoidCallback.h \ - bindings/v8/custom/V8CustomXPathNSResolver.h \ - bindings/v8/custom/V8HTMLImageElementConstructor.h \ - bindings/v8/custom/V8HTMLSelectElementCustom.h \ - bindings/v8/custom/V8NamedNodesCollection.h \ - \ - bindings/v8/DateExtension.h \ - bindings/v8/DOMData.h \ - bindings/v8/DOMDataStore.h \ - bindings/v8/DOMWrapperWorld.h \ - bindings/v8/IsolatedWorld.h \ - bindings/v8/npruntime_impl.h \ - bindings/v8/npruntime_priv.h \ - bindings/v8/NPV8Object.h \ - bindings/v8/NPObjectWrapper.h \ - bindings/v8/OwnHandle.h \ - bindings/v8/PageScriptDebugServer.h \ - bindings/v8/RetainedDOMInfo.h \ - bindings/v8/RetainedObjectInfo.h \ - bindings/v8/SafeAllocation.h \ - bindings/v8/ScheduledAction.h \ - bindings/v8/ScopedDOMDataStore.h \ - bindings/v8/ScriptCachedFrameData.h \ - bindings/v8/ScriptController.h \ - bindings/v8/ScriptEventListener.h \ - bindings/v8/ScriptFunctionCall.h \ - bindings/v8/ScriptInstance.h \ - bindings/v8/ScriptObject.h \ - bindings/v8/ScriptProfile.h \ - bindings/v8/ScriptProfiler.h \ - bindings/v8/ScriptScope.h \ - bindings/v8/ScriptSourceCode.h \ - bindings/v8/ScriptState.h \ - bindings/v8/ScriptValue.h \ - bindings/v8/ScriptWrappable.h \ - bindings/v8/SerializedScriptValue.h \ - bindings/v8/SharedPersistent.h \ - bindings/v8/StaticDOMDataStore.h \ - bindings/v8/V8AbstractEventListener.h \ - bindings/v8/V8Binding.h \ - bindings/v8/V8Collection.h \ - bindings/v8/V8DOMMap.h \ - bindings/v8/V8DOMWindowShell.h \ - bindings/v8/V8DOMWrapper.h \ - bindings/v8/V8EventListener.h \ - bindings/v8/V8EventListenerList.h \ - bindings/v8/V8GCController.h \ - bindings/v8/V8Helpers.h \ - bindings/v8/V8HiddenPropertyName.h \ - bindings/v8/V8IsolatedContext.h \ - bindings/v8/V8LazyEventListener.h \ - bindings/v8/V8NodeFilterCondition.h \ - bindings/v8/V8NPObject.h \ - bindings/v8/V8NPUtils.h \ - bindings/v8/V8Proxy.h \ - bindings/v8/V8RecursionScope.h \ - bindings/v8/V8Utilities.h \ - bindings/v8/V8WindowErrorHandler.h \ - bindings/v8/V8WorkerContextEventListener.h \ - bindings/v8/WorkerContextExecutionProxy.h \ - bindings/v8/WorkerScriptDebugServer.h \ - bindings/v8/WorkerScriptController.h \ - bindings/v8/WorldContextHandle.h -} else { - HEADERS += \ - bindings/js/CachedScriptSourceProvider.h \ - bindings/js/CallbackFunction.h \ - bindings/js/GCController.h \ - bindings/js/DOMObjectHashTableMap.h \ - bindings/js/DOMWrapperWorld.h \ - bindings/js/JSArrayBufferViewHelper.h \ - bindings/js/JSCSSStyleDeclarationCustom.h \ - bindings/js/JSCallbackData.h \ - bindings/js/JSCustomVoidCallback.h \ - bindings/js/JSCustomXPathNSResolver.h \ - bindings/js/JSDictionary.h \ - bindings/js/JSDOMBinding.h \ - bindings/js/JSDOMGlobalObject.h \ - bindings/js/JSDOMStringMapCustom.h \ - bindings/js/JSDOMWindowBase.h \ - bindings/js/JSDOMWindowCustom.h \ - bindings/js/JSDOMWindowShell.h \ - bindings/js/JSDOMWrapper.h \ - bindings/js/JSErrorHandler.h \ - bindings/js/JSEventListener.h \ - bindings/js/JSHTMLAppletElementCustom.h \ - bindings/js/JSHTMLEmbedElementCustom.h \ - bindings/js/JSHTMLInputElementCustom.h \ - bindings/js/JSHTMLObjectElementCustom.h \ - bindings/js/JSHTMLSelectElementCustom.h \ - bindings/js/JSHistoryCustom.h \ - bindings/js/JSImageConstructor.h \ - bindings/js/JSLazyEventListener.h \ - bindings/js/JSLocationCustom.h \ - bindings/js/JSNodeCustom.h \ - bindings/js/JSNodeFilterCondition.h \ - bindings/js/JSPluginElementFunctions.h \ - bindings/js/JSStorageCustom.h \ - bindings/js/JSWorkerContextBase.h \ - bindings/js/JavaScriptCallFrame.h \ - bindings/js/PageScriptDebugServer.h \ - bindings/js/ScheduledAction.h \ - bindings/js/ScriptCachedFrameData.h \ - bindings/js/ScriptController.h \ - bindings/js/ScriptDebugServer.h \ - bindings/js/ScriptEventListener.h \ - bindings/js/ScriptFunctionCall.h \ - bindings/js/ScriptGCEvent.h \ - bindings/js/ScriptHeapSnapshot.h \ - bindings/js/ScriptObject.h \ - bindings/js/ScriptProfile.h \ - bindings/js/ScriptProfileNode.h \ - bindings/js/ScriptProfiler.h \ - bindings/js/ScriptSourceCode.h \ - bindings/js/ScriptSourceProvider.h \ - bindings/js/ScriptState.h \ - bindings/js/ScriptValue.h \ - bindings/js/ScriptWrappable.h \ - bindings/js/SerializedScriptValue.h \ - bindings/js/StringSourceProvider.h \ - bindings/js/WebCoreJSClientData.h \ - bindings/js/WorkerScriptController.h \ - bindings/js/WorkerScriptDebugServer.h \ - bridge/Bridge.h \ - bridge/c/CRuntimeObject.h \ - bridge/c/c_class.h \ - bridge/c/c_instance.h \ - bridge/c/c_runtime.h \ - bridge/c/c_utility.h \ - bridge/jsc/BridgeJSC.h \ - bridge/IdentifierRep.h \ - bridge/NP_jsobject.h \ - bridge/qt/qt_class.h \ - bridge/qt/qt_instance.h \ - bridge/qt/qt_runtime.h \ - bridge/qt/qt_pixmapruntime.h \ - bridge/runtime_array.h \ - bridge/runtime_method.h \ - bridge/runtime_object.h \ - bridge/runtime_root.h \ - plugins/npruntime.h -} +HEADERS += \ + bindings/js/CachedScriptSourceProvider.h \ + bindings/js/CallbackFunction.h \ + bindings/js/GCController.h \ + bindings/js/DOMObjectHashTableMap.h \ + bindings/js/DOMWrapperWorld.h \ + bindings/js/JSArrayBufferViewHelper.h \ + bindings/js/JSCSSStyleDeclarationCustom.h \ + bindings/js/JSCallbackData.h \ + bindings/js/JSCustomVoidCallback.h \ + bindings/js/JSCustomXPathNSResolver.h \ + bindings/js/JSDictionary.h \ + bindings/js/JSDOMBinding.h \ + bindings/js/JSDOMGlobalObject.h \ + bindings/js/JSDOMStringMapCustom.h \ + bindings/js/JSDOMWindowBase.h \ + bindings/js/JSDOMWindowCustom.h \ + bindings/js/JSDOMWindowShell.h \ + bindings/js/JSDOMWrapper.h \ + bindings/js/JSErrorHandler.h \ + bindings/js/JSEventListener.h \ + bindings/js/JSHTMLAppletElementCustom.h \ + bindings/js/JSHTMLEmbedElementCustom.h \ + bindings/js/JSHTMLInputElementCustom.h \ + bindings/js/JSHTMLObjectElementCustom.h \ + bindings/js/JSHTMLSelectElementCustom.h \ + bindings/js/JSHistoryCustom.h \ + bindings/js/JSImageConstructor.h \ + bindings/js/JSLazyEventListener.h \ + bindings/js/JSLocationCustom.h \ + bindings/js/JSNodeCustom.h \ + bindings/js/JSNodeFilterCondition.h \ + bindings/js/JSPluginElementFunctions.h \ + bindings/js/JSStorageCustom.h \ + bindings/js/JSWorkerContextBase.h \ + bindings/js/JavaScriptCallFrame.h \ + bindings/js/PageScriptDebugServer.h \ + bindings/js/ScheduledAction.h \ + bindings/js/ScriptCachedFrameData.h \ + bindings/js/ScriptController.h \ + bindings/js/ScriptDebugServer.h \ + bindings/js/ScriptEventListener.h \ + bindings/js/ScriptFunctionCall.h \ + bindings/js/ScriptGCEvent.h \ + bindings/js/ScriptHeapSnapshot.h \ + bindings/js/ScriptObject.h \ + bindings/js/ScriptProfile.h \ + bindings/js/ScriptProfileNode.h \ + bindings/js/ScriptProfiler.h \ + bindings/js/ScriptSourceCode.h \ + bindings/js/ScriptSourceProvider.h \ + bindings/js/ScriptState.h \ + bindings/js/ScriptValue.h \ + bindings/js/ScriptWrappable.h \ + bindings/js/SerializedScriptValue.h \ + bindings/js/StringSourceProvider.h \ + bindings/js/WebCoreJSClientData.h \ + bindings/js/WorkerScriptController.h \ + bindings/js/WorkerScriptDebugServer.h \ + bridge/Bridge.h \ + bridge/c/CRuntimeObject.h \ + bridge/c/c_class.h \ + bridge/c/c_instance.h \ + bridge/c/c_runtime.h \ + bridge/c/c_utility.h \ + bridge/jsc/BridgeJSC.h \ + bridge/IdentifierRep.h \ + bridge/NP_jsobject.h \ + bridge/qt/qt_class.h \ + bridge/qt/qt_instance.h \ + bridge/qt/qt_runtime.h \ + bridge/qt/qt_pixmapruntime.h \ + bridge/runtime_array.h \ + bridge/runtime_method.h \ + bridge/runtime_object.h \ + bridge/runtime_root.h \ + plugins/npruntime.h HEADERS += \ Modules/geolocation/Geolocation.h \ @@ -1703,6 +1471,7 @@ HEADERS += \ css/WebKitCSSSVGDocumentValue.h \ css/WebKitCSSShaderValue.h \ css/WebKitCSSTransformValue.h \ + css/WrapShapeFunctions.h \ dom/ActiveDOMObject.h \ dom/Attr.h \ dom/Attribute.h \ @@ -2321,6 +2090,7 @@ HEADERS += \ platform/graphics/Region.h \ platform/graphics/RoundedRect.h \ platform/graphics/qt/FontCustomPlatformData.h \ + platform/graphics/qt/NativeImageQt.h \ platform/graphics/qt/StillImageQt.h \ platform/graphics/qt/TransparencyLayer.h \ platform/graphics/SegmentedFontData.h \ @@ -3105,20 +2875,16 @@ contains(DEFINES, ENABLE_SQL_DATABASE=1) { Modules/webdatabase/SQLTransactionCoordinator.cpp \ Modules/webdatabase/SQLTransactionSync.cpp \ - !v8 { - SOURCES += \ - bindings/js/JSCustomSQLStatementErrorCallback.cpp \ - bindings/js/JSSQLResultSetRowListCustom.cpp \ - bindings/js/JSSQLTransactionCustom.cpp \ - bindings/js/JSSQLTransactionSyncCustom.cpp - } + SOURCES += \ + bindings/js/JSCustomSQLStatementErrorCallback.cpp \ + bindings/js/JSSQLResultSetRowListCustom.cpp \ + bindings/js/JSSQLTransactionCustom.cpp \ + bindings/js/JSSQLTransactionSyncCustom.cpp } contains(DEFINES, ENABLE_INDEXED_DATABASE=1) { - !v8 { - HEADERS += \ - bindings/js/IDBBindingUtilities.h \ - } + HEADERS += \ + bindings/js/IDBBindingUtilities.h \ HEADERS += \ Modules/indexeddb/IDBAny.h \ @@ -3147,12 +2913,10 @@ contains(DEFINES, ENABLE_INDEXED_DATABASE=1) { Modules/indexeddb/IDBTransaction.h \ Modules/indexeddb/IDBTransactionBackendInterface.h - !v8 { - SOURCES += \ - bindings/js/IDBBindingUtilities.cpp \ - bindings/js/JSIDBAnyCustom.cpp \ - bindings/js/JSIDBKeyCustom.cpp - } + SOURCES += \ + bindings/js/IDBBindingUtilities.cpp \ + bindings/js/JSIDBAnyCustom.cpp \ + bindings/js/JSIDBKeyCustom.cpp SOURCES += \ Modules/indexeddb/DOMWindowIndexedDatabase.cpp \ @@ -3247,15 +3011,14 @@ contains(DEFINES, ENABLE_ICONDATABASE=1) { } contains(DEFINES, ENABLE_WORKERS=1) { - !v8 { - SOURCES += \ - bindings/js/JSDedicatedWorkerContextCustom.cpp \ - bindings/js/JSWorkerContextBase.cpp \ - bindings/js/JSWorkerContextCustom.cpp \ - bindings/js/JSWorkerCustom.cpp \ - bindings/js/WorkerScriptController.cpp \ - bindings/js/WorkerScriptDebugServer.cpp - } + SOURCES += \ + bindings/js/JSDedicatedWorkerContextCustom.cpp \ + bindings/js/JSWorkerContextBase.cpp \ + bindings/js/JSWorkerContextCustom.cpp \ + bindings/js/JSWorkerCustom.cpp \ + bindings/js/WorkerScriptController.cpp \ + bindings/js/WorkerScriptDebugServer.cpp + SOURCES += \ loader/WorkerThreadableLoader.cpp \ page/WorkerNavigator.cpp \ @@ -3273,10 +3036,9 @@ contains(DEFINES, ENABLE_WORKERS=1) { } contains(DEFINES, ENABLE_SHARED_WORKERS=1) { - !v8 { - SOURCES += \ - bindings/js/JSSharedWorkerCustom.cpp - } + SOURCES += \ + bindings/js/JSSharedWorkerCustom.cpp + SOURCES += \ workers/DefaultSharedWorkerRepository.cpp \ workers/SharedWorker.cpp \ @@ -3409,13 +3171,8 @@ contains(DEFINES, ENABLE_FULLSCREEN_API=1) { } contains(DEFINES, ENABLE_XSLT=1) { - v8 { - SOURCES += \ - bindings/v8/custom/V8XSLTProcessorCustom.cpp - } else { - SOURCES += \ - bindings/js/JSXSLTProcessorCustom.cpp - } + SOURCES += \ + bindings/js/JSXSLTProcessorCustom.cpp SOURCES += xml/XMLTreeViewer.cpp HEADERS += xml/XMLTreeViewer.h @@ -3540,21 +3297,12 @@ contains(DEFINES, ENABLE_DEVICE_ORIENTATION=1) { platform/qt/DeviceOrientationProviderQt.cpp } -contains(DEFINES, ENABLE_GEOLOCATION=1) { - v8 { - SOURCES += \ - bindings/v8/custom/V8GeolocationCustom.cpp - } -} - contains(DEFINES, ENABLE_SVG=1) { - !v8 { - SOURCES += \ - # TODO: this-one-is-not-auto-added! FIXME! tmp/SVGElementFactory.cpp \ - bindings/js/JSSVGElementInstanceCustom.cpp \ - bindings/js/JSSVGLengthCustom.cpp \ - bindings/js/JSSVGPathSegCustom.cpp - } + SOURCES += \ +# TODO: this-one-is-not-auto-added! FIXME! tmp/SVGElementFactory.cpp \ + bindings/js/JSSVGElementInstanceCustom.cpp \ + bindings/js/JSSVGLengthCustom.cpp \ + bindings/js/JSSVGPathSegCustom.cpp SOURCES += \ css/SVGCSSComputedStyleDeclaration.cpp \ @@ -3793,40 +3541,22 @@ contains(DEFINES, ENABLE_SVG=1) { } contains(DEFINES, ENABLE_JAVASCRIPT_DEBUGGER=1) { - v8 { - SOURCES += \ - bindings/v8/ScriptDebugServer.cpp \ - bindings/v8/ScriptProfiler.cpp \ - bindings/v8/ScriptHeapSnapshot.cpp \ - bindings/v8/JavaScriptCallFrame.cpp \ - bindings/v8/custom/V8ScriptProfileCustom.cpp \ - bindings/v8/custom/V8JavaScriptCallFrameCustom.cpp \ - bindings/v8/custom/V8ScriptProfileNodeCustom.cpp \ - bindings/v8/ScriptProfileNode.cpp \ - bindings/v8/ScriptProfile.cpp - } else { - SOURCES += \ - bindings/js/JSJavaScriptCallFrameCustom.cpp \ - bindings/js/ScriptProfiler.cpp \ - bindings/js/JavaScriptCallFrame.cpp - } + SOURCES += \ + bindings/js/JSJavaScriptCallFrameCustom.cpp \ + bindings/js/ScriptProfiler.cpp \ + bindings/js/JavaScriptCallFrame.cpp } contains(DEFINES, ENABLE_VIDEO_TRACK=1) { - v8 { - SOURCES += \ - bindings/v8/custom/V8TrackEventCustom.cpp - } else { - SOURCES += \ - bindings/js/JSTextTrackCueCustom.cpp \ - bindings/js/JSTextTrackCustom.cpp \ - bindings/js/JSTextTrackCustom.h \ - bindings/js/JSTrackCustom.cpp \ - bindings/js/JSTrackCustom.h \ - bindings/js/JSTrackEventCustom.cpp \ - bindings/js/JSTextTrackListCustom.cpp - } + SOURCES += \ + bindings/js/JSTextTrackCueCustom.cpp \ + bindings/js/JSTextTrackCustom.cpp \ + bindings/js/JSTextTrackCustom.h \ + bindings/js/JSTrackCustom.cpp \ + bindings/js/JSTrackCustom.h \ + bindings/js/JSTrackEventCustom.cpp \ + bindings/js/JSTextTrackListCustom.cpp } contains(DEFINES, ENABLE_WEB_SOCKETS=1) { @@ -3865,10 +3595,8 @@ contains(DEFINES, ENABLE_WEB_SOCKETS=1) { platform/network/SocketStreamHandleBase.cpp \ platform/network/qt/SocketStreamHandleQt.cpp - !v8 { - SOURCES += \ - bindings/js/JSWebSocketCustom.cpp - } + SOURCES += \ + bindings/js/JSWebSocketCustom.cpp contains(DEFINES, ENABLE_WORKERS=1) { HEADERS += \ @@ -3911,13 +3639,8 @@ contains(DEFINES, ENABLE_WEBGL=1) { html/canvas/WebGLUniformLocation.h \ html/canvas/WebGLVertexArrayObjectOES.h \ - v8 { - SOURCES += \ - bindings/v8/custom/V8WebGLRenderingContextCustom.cpp - } else { - SOURCES += \ - bindings/js/JSWebGLRenderingContextCustom.cpp - } + SOURCES += \ + bindings/js/JSWebGLRenderingContextCustom.cpp SOURCES += \ html/canvas/CanvasContextAttributes.cpp \ @@ -3993,7 +3716,10 @@ contains(DEFINES, WTF_USE_3D_GRAPHICS=1) { ANGLE_DIR = $$replace(PWD, "WebCore", "ThirdParty/ANGLE") - INCLUDEPATH += $$ANGLE_DIR/src $$ANGLE_DIR/include + INCLUDEPATH += \ + $$ANGLE_DIR/src \ + $$ANGLE_DIR/src/compiler/preprocessor/new \ + $$ANGLE_DIR/include ANGLE_HEADERS += \ $$ANGLE_DIR/src/compiler/BaseTypes.h \ @@ -4001,11 +3727,16 @@ contains(DEFINES, WTF_USE_3D_GRAPHICS=1) { $$ANGLE_DIR/src/compiler/Common.h \ $$ANGLE_DIR/src/compiler/ConstantUnion.h \ $$ANGLE_DIR/src/compiler/debug.h \ + $$ANGLE_DIR/src/compiler/depgraph/DependencyGraph.h \ + $$ANGLE_DIR/src/compiler/depgraph/DependencyGraphBuilder.h \ + $$ANGLE_DIR/src/compiler/depgraph/DependencyGraphOutput.h \ + $$ANGLE_DIR/src/compiler/DetectDiscontinuity.h \ $$ANGLE_DIR/src/compiler/DetectRecursion.h \ + $$ANGLE_DIR/src/compiler/Diagnostics.h \ + $$ANGLE_DIR/src/compiler/DirectiveHandler.h \ $$ANGLE_DIR/src/compiler/ExtensionBehavior.h \ $$ANGLE_DIR/src/compiler/ForLoopUnroll.h \ $$ANGLE_DIR/src/compiler/glslang.h \ - $$ANGLE_DIR/src/compiler/glslang_tab.h \ $$ANGLE_DIR/src/compiler/InfoSink.h \ $$ANGLE_DIR/src/compiler/InitializeDll.h \ $$ANGLE_DIR/src/compiler/InitializeGlobals.h \ @@ -4016,11 +3747,23 @@ contains(DEFINES, WTF_USE_3D_GRAPHICS=1) { $$ANGLE_DIR/src/compiler/MMap.h \ $$ANGLE_DIR/src/compiler/MapLongVariableNames.h \ $$ANGLE_DIR/src/compiler/osinclude.h \ + $$ANGLE_DIR/src/compiler/Pragma.h \ $$ANGLE_DIR/src/compiler/preprocessor/atom.h \ $$ANGLE_DIR/src/compiler/preprocessor/compile.h \ $$ANGLE_DIR/src/compiler/preprocessor/cpp.h \ $$ANGLE_DIR/src/compiler/preprocessor/length_limits.h \ $$ANGLE_DIR/src/compiler/preprocessor/memory.h \ + $$ANGLE_DIR/src/compiler/preprocessor/new/Diagnostics.h \ + $$ANGLE_DIR/src/compiler/preprocessor/new/DirectiveHandler.h \ + $$ANGLE_DIR/src/compiler/preprocessor/new/DirectiveParser.h \ + $$ANGLE_DIR/src/compiler/preprocessor/new/Input.h \ + $$ANGLE_DIR/src/compiler/preprocessor/new/Lexer.h \ + $$ANGLE_DIR/src/compiler/preprocessor/new/Macro.h \ + $$ANGLE_DIR/src/compiler/preprocessor/new/MacroExpander.h \ + $$ANGLE_DIR/src/compiler/preprocessor/new/Preprocessor.h \ + $$ANGLE_DIR/src/compiler/preprocessor/new/SourceLocation.h \ + $$ANGLE_DIR/src/compiler/preprocessor/new/Token.h \ + $$ANGLE_DIR/src/compiler/preprocessor/new/Tokenizer.h \ $$ANGLE_DIR/src/compiler/preprocessor/parser.h \ $$ANGLE_DIR/src/compiler/preprocessor/preprocess.h \ $$ANGLE_DIR/src/compiler/preprocessor/scanner.h \ @@ -4035,14 +3778,17 @@ contains(DEFINES, WTF_USE_3D_GRAPHICS=1) { $$ANGLE_DIR/src/compiler/PoolAlloc.h \ $$ANGLE_DIR/src/compiler/QualifierAlive.h \ $$ANGLE_DIR/src/compiler/RemoveTree.h \ + $$ANGLE_DIR/src/compiler/RenameFunction.h \ $$ANGLE_DIR/src/compiler/SearchSymbol.h \ $$ANGLE_DIR/src/compiler/ShHandle.h \ $$ANGLE_DIR/src/compiler/SymbolTable.h \ + $$ANGLE_DIR/src/compiler/timing/RestrictFragmentShaderTiming.h \ + $$ANGLE_DIR/src/compiler/timing/RestrictVertexShaderTiming.h \ $$ANGLE_DIR/src/compiler/TranslatorESSL.h \ $$ANGLE_DIR/src/compiler/TranslatorGLSL.h \ $$ANGLE_DIR/src/compiler/TranslatorHLSL.h \ $$ANGLE_DIR/src/compiler/Types.h \ - $$ANGLE_DIR/src/compiler/UnfoldSelect.h \ + $$ANGLE_DIR/src/compiler/UnfoldShortCircuit.h \ $$ANGLE_DIR/src/compiler/util.h \ $$ANGLE_DIR/src/compiler/ValidateLimitations.h \ $$ANGLE_DIR/src/compiler/VariableInfo.h \ @@ -4055,13 +3801,19 @@ contains(DEFINES, WTF_USE_3D_GRAPHICS=1) { $$ANGLE_DIR/src/compiler/CodeGenGLSL.cpp \ $$ANGLE_DIR/src/compiler/Compiler.cpp \ $$ANGLE_DIR/src/compiler/debug.cpp \ + $$ANGLE_DIR/src/compiler/depgraph/DependencyGraph.cpp \ + $$ANGLE_DIR/src/compiler/depgraph/DependencyGraphBuilder.cpp \ + $$ANGLE_DIR/src/compiler/depgraph/DependencyGraphOutput.cpp \ + $$ANGLE_DIR/src/compiler/depgraph/DependencyGraphTraverse.cpp \ + $$ANGLE_DIR/src/compiler/DetectDiscontinuity.cpp \ $$ANGLE_DIR/src/compiler/DetectRecursion.cpp \ + $$ANGLE_DIR/src/compiler/Diagnostics.cpp \ + $$ANGLE_DIR/src/compiler/DirectiveHandler.cpp \ $$ANGLE_DIR/src/compiler/ForLoopUnroll.cpp \ - $$ANGLE_DIR/src/compiler/glslang_lex.cpp \ - $$ANGLE_DIR/src/compiler/glslang_tab.cpp \ $$ANGLE_DIR/src/compiler/InfoSink.cpp \ $$ANGLE_DIR/src/compiler/Initialize.cpp \ $$ANGLE_DIR/src/compiler/InitializeDll.cpp \ + $$ANGLE_DIR/src/compiler/InitializeParseContext.cpp \ $$ANGLE_DIR/src/compiler/Intermediate.cpp \ $$ANGLE_DIR/src/compiler/intermOut.cpp \ $$ANGLE_DIR/src/compiler/IntermTraverse.cpp \ @@ -4079,10 +3831,12 @@ contains(DEFINES, WTF_USE_3D_GRAPHICS=1) { $$ANGLE_DIR/src/compiler/SearchSymbol.cpp \ $$ANGLE_DIR/src/compiler/ShaderLang.cpp \ $$ANGLE_DIR/src/compiler/SymbolTable.cpp \ + $$ANGLE_DIR/src/compiler/timing/RestrictFragmentShaderTiming.cpp \ + $$ANGLE_DIR/src/compiler/timing/RestrictVertexShaderTiming.cpp \ $$ANGLE_DIR/src/compiler/TranslatorESSL.cpp \ $$ANGLE_DIR/src/compiler/TranslatorGLSL.cpp \ $$ANGLE_DIR/src/compiler/TranslatorHLSL.cpp \ - $$ANGLE_DIR/src/compiler/UnfoldSelect.cpp \ + $$ANGLE_DIR/src/compiler/UnfoldShortCircuit.cpp \ $$ANGLE_DIR/src/compiler/util.cpp \ $$ANGLE_DIR/src/compiler/ValidateLimitations.cpp \ $$ANGLE_DIR/src/compiler/VariableInfo.cpp \ @@ -4093,6 +3847,15 @@ contains(DEFINES, WTF_USE_3D_GRAPHICS=1) { $$ANGLE_DIR/src/compiler/preprocessor/cpp.c \ $$ANGLE_DIR/src/compiler/preprocessor/cppstruct.c \ $$ANGLE_DIR/src/compiler/preprocessor/memory.c \ + $$ANGLE_DIR/src/compiler/preprocessor/new/DiagnosticsBase.cpp \ + $$ANGLE_DIR/src/compiler/preprocessor/new/DirectiveHandlerBase.cpp \ + $$ANGLE_DIR/src/compiler/preprocessor/new/DirectiveParser.cpp \ + $$ANGLE_DIR/src/compiler/preprocessor/new/Input.cpp \ + $$ANGLE_DIR/src/compiler/preprocessor/new/Lexer.cpp \ + $$ANGLE_DIR/src/compiler/preprocessor/new/Macro.cpp \ + $$ANGLE_DIR/src/compiler/preprocessor/new/MacroExpander.cpp \ + $$ANGLE_DIR/src/compiler/preprocessor/new/Preprocessor.cpp \ + $$ANGLE_DIR/src/compiler/preprocessor/new/Token.cpp \ $$ANGLE_DIR/src/compiler/preprocessor/scanner.c \ $$ANGLE_DIR/src/compiler/preprocessor/symbols.c \ $$ANGLE_DIR/src/compiler/preprocessor/tokens.c diff --git a/Source/WebCore/WebCore.exp.in b/Source/WebCore/WebCore.exp.in index 1b2618e7f..9efb2c77a 100644 --- a/Source/WebCore/WebCore.exp.in +++ b/Source/WebCore/WebCore.exp.in @@ -250,6 +250,7 @@ __ZN7WebCore14DocumentLoader8setTitleERKNS_19StringWithDirectionE __ZN7WebCore14DocumentLoaderC1ERKNS_15ResourceRequestERKNS_14SubstituteDataE __ZN7WebCore14DocumentLoaderC2ERKNS_15ResourceRequestERKNS_14SubstituteDataE __ZN7WebCore14DocumentLoaderD2Ev +__ZNK7WebCore14DocumentLoader17reportMemoryUsageEPNS_16MemoryObjectInfoE __ZN7WebCore14DocumentWriter11setEncodingERKN3WTF6StringEb __ZN7WebCore14FileIconLoader14notifyFinishedEN3WTF10PassRefPtrINS_4IconEEE __ZN7WebCore14FrameSelection10setFocusedEb @@ -834,6 +835,7 @@ __ZN7WebCore8Document26pageSizeAndMarginsInPixelsEiRNS_7IntSizeERiS3_S3_S3_ __ZN7WebCore8Document27removeMediaCanStartListenerEPNS_21MediaCanStartListenerE __ZN7WebCore8Document36updateLayoutIgnorePendingStylesheetsEv __ZN7WebCore8Document4headEv +__ZN7WebCore8Document8iconURLsEv __ZN7WebCore8FormData6createEPKvm __ZN7WebCore8FormDataD1Ev __ZN7WebCore8Gradient12addColorStopEfRKNS_5ColorE diff --git a/Source/WebCore/WebCore.gyp/WebCore.gyp b/Source/WebCore/WebCore.gyp/WebCore.gyp index c274e2f03..2b4df7a61 100644 --- a/Source/WebCore/WebCore.gyp/WebCore.gyp +++ b/Source/WebCore/WebCore.gyp/WebCore.gyp @@ -1580,8 +1580,8 @@ ['exclude', 'platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz\\.cpp$'], ['exclude', 'platform/graphics/harfbuzz/HarfBuzzSkia\\.cpp$'], - ['include', 'platform/graphics/harfbuzz/ng/HarfBuzzFace\\.(cpp|h)$'], - ['include', 'platform/graphics/harfbuzz/ng/HarfBuzzFaceSkia\\.cpp$'], + ['include', 'platform/graphics/harfbuzz/ng/HarfBuzzNGFace\\.(cpp|h)$'], + ['include', 'platform/graphics/harfbuzz/ng/HarfBuzzNGFaceSkia\\.cpp$'], ['include', 'platform/graphics/harfbuzz/ng/HarfBuzzShaper\\.(cpp|h)$'], ], }], @@ -1703,12 +1703,11 @@ ['exclude', 'platform/graphics/skia/FontCacheSkia\\.cpp$'], ['exclude', 'platform/graphics/skia/GlyphPageTreeNodeSkia\\.cpp$'], ['exclude', 'platform/graphics/skia/SimpleFontDataSkia\\.cpp$'], - ['exclude', 'platform/chromium/DragImageChromiumMac\\.cpp$'], # Mac uses Harfbuzz-ng. ['include', 'platform/graphics/harfbuzz/HarfBuzzShaperBase\\.(cpp|h)$'], - ['include', 'platform/graphics/harfbuzz/ng/HarfBuzzFaceCoreText\\.cpp$'], - ['include', 'platform/graphics/harfbuzz/ng/HarfBuzzFace\\.(cpp|h)$'], + ['include', 'platform/graphics/harfbuzz/ng/HarfBuzzNGFaceCoreText\\.cpp$'], + ['include', 'platform/graphics/harfbuzz/ng/HarfBuzzNGFace\\.(cpp|h)$'], ['include', 'platform/graphics/harfbuzz/ng/HarfBuzzShaper\\.(cpp|h)$'], ], },{ # OS!="mac" diff --git a/Source/WebCore/WebCore.gypi b/Source/WebCore/WebCore.gypi index f3f77ea43..09d970f1f 100644 --- a/Source/WebCore/WebCore.gypi +++ b/Source/WebCore/WebCore.gypi @@ -110,6 +110,7 @@ 'css/WebKitCSSFilterValue.h', 'css/WebKitCSSShaderValue.h', 'css/WebKitCSSTransformValue.h', + 'css/WrapShapeFunctions.h', 'editing/ApplyBlockElementCommand.h', 'editing/CompositeEditCommand.h', 'editing/DeleteSelectionCommand.h', @@ -1583,6 +1584,7 @@ 'Modules/notifications/WorkerContextNotifications.h', 'Modules/protocolhandler/NavigatorRegisterProtocolHandler.cpp', 'Modules/protocolhandler/NavigatorRegisterProtocolHandler.h', + 'Modules/protocolhandler/RegisterProtocolHandlerClient.h', 'Modules/quota/DOMWindowQuota.cpp', 'Modules/quota/DOMWindowQuota.h', 'Modules/quota/StorageInfo.cpp', @@ -2181,7 +2183,6 @@ 'bindings/v8/ScriptCallStackFactory.h', 'bindings/v8/ScriptController.cpp', 'bindings/v8/ScriptController.h', - 'bindings/v8/ScriptControllerQt.cpp', 'bindings/v8/ScriptDebugServer.cpp', 'bindings/v8/ScriptDebugServer.h', 'bindings/v8/ScriptEventListener.cpp', @@ -2602,6 +2603,7 @@ 'css/WebKitCSSSVGDocumentValue.cpp', 'css/WebKitCSSSVGDocumentValue.h', 'css/WebKitCSSTransformValue.cpp', + 'css/WrapShapeFunctions.cpp', 'editing/AlternativeTextController.cpp', 'editing/AlternativeTextController.h', 'editing/AppendNodeCommand.cpp', @@ -2912,6 +2914,7 @@ 'loader/HistoryController.cpp', 'loader/ImageLoader.cpp', 'loader/ImageLoader.h', + 'loader/ImageLoaderClient.h', 'loader/LinkLoader.cpp', 'loader/LinkLoader.h', 'loader/LinkLoaderClient.h', @@ -3357,7 +3360,6 @@ 'platform/chromium/CursorChromium.cpp', 'platform/chromium/DragDataChromium.cpp', 'platform/chromium/DragDataRef.h', - 'platform/chromium/DragImageChromiumMac.cpp', 'platform/chromium/DragImageChromiumSkia.cpp', 'platform/chromium/DragImageRef.h', 'platform/chromium/EventTracerChromium.cpp', @@ -3775,10 +3777,10 @@ 'platform/graphics/harfbuzz/HarfBuzzSkia.h', 'platform/graphics/harfbuzz/HarfBuzzShaperBase.cpp', 'platform/graphics/harfbuzz/HarfBuzzShaperBase.h', - 'platform/graphics/harfbuzz/ng/HarfBuzzFaceCoreText.cpp', - 'platform/graphics/harfbuzz/ng/HarfBuzzFaceSkia.cpp', - 'platform/graphics/harfbuzz/ng/HarfBuzzFace.cpp', - 'platform/graphics/harfbuzz/ng/HarfBuzzFace.h', + 'platform/graphics/harfbuzz/ng/HarfBuzzNGFaceCoreText.cpp', + 'platform/graphics/harfbuzz/ng/HarfBuzzNGFaceSkia.cpp', + 'platform/graphics/harfbuzz/ng/HarfBuzzNGFace.cpp', + 'platform/graphics/harfbuzz/ng/HarfBuzzNGFace.h', 'platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp', 'platform/graphics/harfbuzz/ng/HarfBuzzShaper.h', 'platform/graphics/mac/ColorMac.mm', @@ -5712,6 +5714,8 @@ 'html/shadow/HTMLContentElement.h', 'html/shadow/HTMLShadowElement.cpp', 'html/shadow/HTMLShadowElement.h', + 'html/shadow/ImageInnerElement.cpp', + 'html/shadow/ImageInnerElement.h', 'html/shadow/InsertionPoint.cpp', 'html/shadow/InsertionPoint.h', 'html/shadow/MediaControls.cpp', diff --git a/Source/WebCore/WebCore.pri b/Source/WebCore/WebCore.pri index b399bc292..49522f304 100644 --- a/Source/WebCore/WebCore.pri +++ b/Source/WebCore/WebCore.pri @@ -94,24 +94,12 @@ INCLUDEPATH += \ $$SOURCE_DIR/xml/parser \ $$SOURCE_DIR/../ThirdParty -v8 { - DEFINES *= V8_BINDING=1 - - INCLUDEPATH += \ - $$SOURCE_DIR/bindings/v8 \ - $$SOURCE_DIR/bindings/v8/custom \ - $$SOURCE_DIR/bindings/v8/specialization \ - $$SOURCE_DIR/bridge/qt/v8 \ - $$SOURCE_DIR/testing/v8 - -} else { - INCLUDEPATH += \ - $$SOURCE_DIR/bridge/jsc \ - $$SOURCE_DIR/bindings/js \ - $$SOURCE_DIR/bindings/js/specialization \ - $$SOURCE_DIR/bridge/c \ - $$SOURCE_DIR/testing/js -} +INCLUDEPATH += \ + $$SOURCE_DIR/bridge/jsc \ + $$SOURCE_DIR/bindings/js \ + $$SOURCE_DIR/bindings/js/specialization \ + $$SOURCE_DIR/bridge/c \ + $$SOURCE_DIR/testing/js INCLUDEPATH += $$WEBCORE_GENERATED_SOURCES_DIR diff --git a/Source/WebCore/WebCore.vcproj/WebCore.vcproj b/Source/WebCore/WebCore.vcproj/WebCore.vcproj index 53b224c3b..19be056d1 100755 --- a/Source/WebCore/WebCore.vcproj/WebCore.vcproj +++ b/Source/WebCore/WebCore.vcproj/WebCore.vcproj @@ -27299,6 +27299,10 @@ > </File> <File + RelativePath="..\loader\ImageLoaderClient.h" + > + </File> + <File RelativePath="..\loader\LinkLoader.cpp" > </File> @@ -37646,6 +37650,14 @@ RelativePath="..\css\WebKitCSSTransformValue.h" > </File> + <File + RelativePath="..\css\WrapShapeFunctions.cpp" + > + </File> + <File + RelativePath="..\css\WrapShapeFunctions.h" + > + </File> </Filter> <Filter Name="rendering" @@ -63390,6 +63402,14 @@ > </File> <File + RelativePath="..\html\shadow\ImageInnerElement.cpp" + > + </File> + <File + RelativePath="..\html\shadow\ImageInnerElement.h" + > + </File> + <File RelativePath="..\html\shadow\MediaControlElements.cpp" > </File> diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj index da4730919..93be27504 100644 --- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj +++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj @@ -1600,6 +1600,9 @@ 550A0BC9085F6039007353D6 /* QualifiedName.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 550A0BC7085F6039007353D6 /* QualifiedName.cpp */; }; 550A0BCA085F6039007353D6 /* QualifiedName.h in Headers */ = {isa = PBXBuildFile; fileRef = 550A0BC8085F6039007353D6 /* QualifiedName.h */; settings = {ATTRIBUTES = (Private, ); }; }; 573D134714CE39FF0057ABCA /* InspectorTypeBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 573D134514CE39FF0057ABCA /* InspectorTypeBuilder.cpp */; }; + 5759898715AAC0B100353C31 /* ImageInnerElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 572145CC15A51DA700AD119C /* ImageInnerElement.h */; }; + 5759898915AAC0E900353C31 /* ImageInnerElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 572145CB15A51DA700AD119C /* ImageInnerElement.cpp */; }; + 5759898F15AEAB9400353C31 /* ImageLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 5759898E15AEAB9400353C31 /* ImageLoaderClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; 578DA20E1520EB8C006141C1 /* InspectorFrontend.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F4F5FFC11CBD30100A186BF /* InspectorFrontend.h */; settings = {ATTRIBUTES = (Private, ); }; }; 578DA20F1520EBA3006141C1 /* InspectorTypeBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 573D134614CE39FF0057ABCA /* InspectorTypeBuilder.h */; settings = {ATTRIBUTES = (Private, ); }; }; 57B791A314C6A62900F202D1 /* ContentDistributor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57B7919F14C6A62900F202D1 /* ContentDistributor.cpp */; }; @@ -6459,6 +6462,9 @@ FDB1700614A2BAB200A2B5D9 /* MultiChannelResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = FDB1700414A2BAB200A2B5D9 /* MultiChannelResampler.h */; }; FDC54F041399B0DA008D9117 /* BiquadFilterNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FDC54F011399B0DA008D9117 /* BiquadFilterNode.cpp */; }; FDC54F051399B0DA008D9117 /* BiquadFilterNode.h in Headers */ = {isa = PBXBuildFile; fileRef = FDC54F021399B0DA008D9117 /* BiquadFilterNode.h */; }; + FDE6860215B0A93B00BB480C /* WrapShapeFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD7E95A215ACD6090039E3D0 /* WrapShapeFunctions.cpp */; }; + FDE6860315B0A96100BB480C /* WrapShapeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = FD7E95A015ACD5620039E3D0 /* WrapShapeFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; }; + FDE6860415B0A96100BB480C /* WrapShapes.h in Headers */ = {isa = PBXBuildFile; fileRef = FDB51CF4159CD70300E227C5 /* WrapShapes.h */; settings = {ATTRIBUTES = (Private, ); }; }; FDEA6242152102E200479DF0 /* JSOscillator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FDEA6240152102E200479DF0 /* JSOscillator.cpp */; }; FDEA6243152102E200479DF0 /* JSOscillator.h in Headers */ = {isa = PBXBuildFile; fileRef = FDEA6241152102E200479DF0 /* JSOscillator.h */; }; FDEA6246152102FC00479DF0 /* JSWaveTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FDEA6244152102FC00479DF0 /* JSWaveTable.cpp */; }; @@ -8705,8 +8711,11 @@ 53C8298C13D8D92700DE2DEB /* RenderFlexibleBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderFlexibleBox.h; sourceTree = "<group>"; }; 550A0BC7085F6039007353D6 /* QualifiedName.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QualifiedName.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; }; 550A0BC8085F6039007353D6 /* QualifiedName.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = QualifiedName.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; }; + 572145CB15A51DA700AD119C /* ImageInnerElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageInnerElement.cpp; sourceTree = "<group>"; }; + 572145CC15A51DA700AD119C /* ImageInnerElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageInnerElement.h; sourceTree = "<group>"; }; 573D134514CE39FF0057ABCA /* InspectorTypeBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorTypeBuilder.cpp; sourceTree = "<group>"; }; 573D134614CE39FF0057ABCA /* InspectorTypeBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorTypeBuilder.h; sourceTree = "<group>"; }; + 5759898E15AEAB9400353C31 /* ImageLoaderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageLoaderClient.h; sourceTree = "<group>"; }; 57B7919F14C6A62900F202D1 /* ContentDistributor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ContentDistributor.cpp; sourceTree = "<group>"; }; 57B791A014C6A62900F202D1 /* ContentDistributor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentDistributor.h; sourceTree = "<group>"; }; 57B791A114C6A62900F202D1 /* ContentSelectorQuery.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ContentSelectorQuery.cpp; sourceTree = "<group>"; }; @@ -13738,6 +13747,8 @@ FD6F252B13F5EF0E0065165F /* MediaElementAudioSourceNode.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MediaElementAudioSourceNode.idl; sourceTree = "<group>"; }; FD7868B7136B999200D403DF /* JSDynamicsCompressorNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDynamicsCompressorNode.cpp; sourceTree = "<group>"; }; FD7868B8136B999200D403DF /* JSDynamicsCompressorNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDynamicsCompressorNode.h; sourceTree = "<group>"; }; + FD7E95A015ACD5620039E3D0 /* WrapShapeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WrapShapeFunctions.h; sourceTree = "<group>"; }; + FD7E95A215ACD6090039E3D0 /* WrapShapeFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WrapShapeFunctions.cpp; sourceTree = "<group>"; }; FD7F298A13D4C0CB00AD9535 /* WaveShaperDSPKernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WaveShaperDSPKernel.cpp; sourceTree = "<group>"; }; FD7F298B13D4C0CB00AD9535 /* WaveShaperDSPKernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WaveShaperDSPKernel.h; sourceTree = "<group>"; }; FD7F298C13D4C0CB00AD9535 /* WaveShaperNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WaveShaperNode.cpp; sourceTree = "<group>"; }; @@ -13797,6 +13808,7 @@ FDB052DE1561A42C00B500D6 /* AudioSummingJunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioSummingJunction.h; sourceTree = "<group>"; }; FDB1700314A2BAB200A2B5D9 /* MultiChannelResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MultiChannelResampler.cpp; sourceTree = "<group>"; }; FDB1700414A2BAB200A2B5D9 /* MultiChannelResampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MultiChannelResampler.h; sourceTree = "<group>"; }; + FDB51CF4159CD70300E227C5 /* WrapShapes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WrapShapes.h; path = style/WrapShapes.h; sourceTree = "<group>"; }; FDC54F011399B0DA008D9117 /* BiquadFilterNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BiquadFilterNode.cpp; sourceTree = "<group>"; }; FDC54F021399B0DA008D9117 /* BiquadFilterNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BiquadFilterNode.h; sourceTree = "<group>"; }; FDC54F031399B0DA008D9117 /* BiquadFilterNode.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = BiquadFilterNode.idl; sourceTree = "<group>"; }; @@ -14819,6 +14831,8 @@ 4ABDFF0714DBE312004D117D /* HTMLShadowElement.cpp */, 4ABDFF0814DBE312004D117D /* HTMLShadowElement.h */, 4ABDFF0914DBE312004D117D /* HTMLShadowElement.idl */, + 572145CB15A51DA700AD119C /* ImageInnerElement.cpp */, + 572145CC15A51DA700AD119C /* ImageInnerElement.h */, 57CF497214EE36D700ECFF14 /* InsertionPoint.cpp */, 57CF497314EE36D700ECFF14 /* InsertionPoint.h */, 417253A81354BBBC00360F2A /* MediaControlElements.cpp */, @@ -20293,6 +20307,7 @@ BC2274750E8366E200E7F975 /* SVGRenderStyle.h */, BC2274760E8366E200E7F975 /* SVGRenderStyleDefs.cpp */, BC2274770E8366E200E7F975 /* SVGRenderStyleDefs.h */, + FDB51CF4159CD70300E227C5 /* WrapShapes.h */, ); name = style; sourceTree = "<group>"; @@ -20399,6 +20414,7 @@ 97DCE20010807C750057D394 /* HistoryController.h */, 089582530E857A7E00F82C83 /* ImageLoader.cpp */, 089582540E857A7E00F82C83 /* ImageLoader.h */, + 5759898E15AEAB9400353C31 /* ImageLoaderClient.h */, 98CE4325129E00BD005821DC /* LinkLoader.cpp */, 98CE4329129E00E5005821DC /* LinkLoader.h */, 984264EF12D5280A000D88A4 /* LinkLoaderClient.h */, @@ -21056,6 +21072,8 @@ BC9ADD7F0CC4092200098C4C /* WebKitCSSTransformValue.cpp */, BC9ADD220CC4032600098C4C /* WebKitCSSTransformValue.h */, 31611E540E1C4D4A00F6A579 /* WebKitCSSTransformValue.idl */, + FD7E95A215ACD6090039E3D0 /* WrapShapeFunctions.cpp */, + FD7E95A015ACD5620039E3D0 /* WrapShapeFunctions.h */, ); path = css; sourceTree = "<group>"; @@ -21979,6 +21997,8 @@ buildActionMask = 2147483647; files = ( 97BC69DB1505F076001B74AC /* AbstractDatabase.h in Headers */, + FDE6860415B0A96100BB480C /* WrapShapes.h in Headers */, + FDE6860315B0A96100BB480C /* WrapShapeFunctions.h in Headers */, 41E1B1D10FF5986900576B3B /* AbstractWorker.h in Headers */, 29A8122E0FBB9C1D00510293 /* AccessibilityARIAGridCell.h in Headers */, 29A812330FBB9C1D00510293 /* AccessibilityARIAGridRow.h in Headers */, @@ -23422,8 +23442,10 @@ 22BD9F81135364FE009BD102 /* ImageBufferDataCG.h in Headers */, A779791A0D6B9D0C003851B9 /* ImageData.h in Headers */, 97205AB61239291000B17380 /* ImageDocument.h in Headers */, + 5759898715AAC0B100353C31 /* ImageInnerElement.h in Headers */, F55B3DC21251F12D003EF269 /* ImageInputType.h in Headers */, 089582560E857A7E00F82C83 /* ImageLoader.h in Headers */, + 5759898F15AEAB9400353C31 /* ImageLoaderClient.h in Headers */, BC7F44A80B9E324E00A9D081 /* ImageObserver.h in Headers */, 2D5A5931152525D00036EE51 /* ImageOrientation.h in Headers */, 49291E4B134172C800E753DE /* ImageRenderingMode.h in Headers */, @@ -25585,6 +25607,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + FDE6860215B0A93B00BB480C /* WrapShapeFunctions.cpp in Sources */, 97BC69DA1505F076001B74AC /* AbstractDatabase.cpp in Sources */, 41E1B1D00FF5986900576B3B /* AbstractWorker.cpp in Sources */, 0F29C16E1300C2E2002D794E /* AccessibilityAllInOne.cpp in Sources */, @@ -26579,6 +26602,7 @@ B275355E0B053814002CE64F /* ImageCG.cpp in Sources */, A77979190D6B9D0C003851B9 /* ImageData.cpp in Sources */, 97205AB51239291000B17380 /* ImageDocument.cpp in Sources */, + 5759898915AAC0E900353C31 /* ImageInnerElement.cpp in Sources */, F55B3DC11251F12D003EF269 /* ImageInputType.cpp in Sources */, 089582550E857A7E00F82C83 /* ImageLoader.cpp in Sources */, B275357B0B053814002CE64F /* ImageMac.mm in Sources */, diff --git a/Source/WebCore/bindings/js/JSDOMGlobalObject.h b/Source/WebCore/bindings/js/JSDOMGlobalObject.h index 3ce12d10f..bdab568f0 100644 --- a/Source/WebCore/bindings/js/JSDOMGlobalObject.h +++ b/Source/WebCore/bindings/js/JSDOMGlobalObject.h @@ -27,12 +27,10 @@ #ifndef JSDOMGlobalObject_h #define JSDOMGlobalObject_h +#include "PlatformExportMacros.h" #include <runtime/JSGlobalObject.h> #include <runtime/JSGlobalThis.h> -#ifndef WEBKIT_EXPORTDATA -#define WEBKIT_EXPORTDATA -#endif namespace WebCore { diff --git a/Source/WebCore/bindings/js/ScriptWrappable.h b/Source/WebCore/bindings/js/ScriptWrappable.h index 2d92bb455..3cb5d816c 100644 --- a/Source/WebCore/bindings/js/ScriptWrappable.h +++ b/Source/WebCore/bindings/js/ScriptWrappable.h @@ -56,8 +56,8 @@ public: void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::DOM); - memoryObjectInfo->reportObject(m_wrapper); + MemoryClassInfo<ScriptWrappable> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + info.addMember(m_wrapper); } private: diff --git a/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm b/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm index 31c164bf0..ebb5e7fa0 100644 --- a/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm +++ b/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm @@ -634,6 +634,24 @@ sub ShouldGenerateToJSImplementation return 0; } +sub GetAttributeGetterName +{ + my ($interfaceName, $className, $attribute) = @_; + if ($attribute->isStatic) { + return $codeGenerator->WK_lcfirst($className) . "Constructor" . $codeGenerator->WK_ucfirst($attribute->signature->name); + } + return "js" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : ""); +} + +sub GetAttributeSetterName +{ + my ($interfaceName, $className, $attribute) = @_; + if ($attribute->isStatic) { + return "set" . $codeGenerator->WK_ucfirst($className) . "Constructor" . $codeGenerator->WK_ucfirst($attribute->signature->name); + } + return "setJS" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : ""); +} + sub GetFunctionName { my ($className, $function) = @_; @@ -785,7 +803,7 @@ sub GenerateHeader # Check if we have any writable properties my $hasReadWriteProperties = 0; foreach (@{$dataNode->attributes}) { - if ($_->type !~ /^readonly\ attribute$/) { + if ($_->type !~ /^readonly\ attribute$/ && !$_->isStatic) { $hasReadWriteProperties = 1; } } @@ -1117,10 +1135,10 @@ sub GenerateHeader foreach my $attribute (@{$dataNode->attributes}) { my $conditionalString = $codeGenerator->GenerateConditionalString($attribute->signature); push(@headerContent, "#if ${conditionalString}\n") if $conditionalString; - my $getter = "js" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : ""); + my $getter = GetAttributeGetterName($interfaceName, $className, $attribute); push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, JSC::JSValue, JSC::PropertyName);\n"); unless ($attribute->type =~ /readonly/) { - my $setter = "setJS" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : ""); + my $setter = GetAttributeSetterName($interfaceName, $className, $attribute); push(@headerContent, "void ${setter}(JSC::ExecState*, JSC::JSObject*, JSC::JSValue);\n"); } push(@headerContent, "#endif\n") if $conditionalString; @@ -1186,6 +1204,7 @@ sub GenerateAttributesHashTable($$) my @entries = (); foreach my $attribute (@{$dataNode->attributes}) { + next if ($attribute->isStatic); my $name = $attribute->signature->name; push(@hashKeys, $name); @@ -1196,13 +1215,13 @@ sub GenerateAttributesHashTable($$) my $special = (@specials > 0) ? join(" | ", @specials) : "0"; push(@hashSpecials, $special); - my $getter = "js" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : ""); + my $getter = GetAttributeGetterName($interfaceName, $className, $attribute); push(@hashValue1, $getter); if ($attribute->type =~ /readonly/) { push(@hashValue2, "0"); } else { - my $setter = "setJS" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : ""); + my $setter = GetAttributeSetterName($interfaceName, $className, $attribute); push(@hashValue2, $setter); } @@ -1413,6 +1432,33 @@ sub GenerateImplementation } } + foreach my $attribute (@{$dataNode->attributes}) { + next unless ($attribute->isStatic); + my $name = $attribute->signature->name; + push(@hashKeys, $name); + + my @specials = (); + push(@specials, "DontDelete") unless $attribute->signature->extendedAttributes->{"Deletable"}; + push(@specials, "ReadOnly") if $attribute->type =~ /readonly/; + my $special = (@specials > 0) ? join(" | ", @specials) : "0"; + push(@hashSpecials, $special); + + my $getter = GetAttributeGetterName($interfaceName, $className, $attribute); + push(@hashValue1, $getter); + + if ($attribute->type =~ /readonly/) { + push(@hashValue2, "0"); + } else { + my $setter = GetAttributeSetterName($interfaceName, $className, $attribute); + push(@hashValue2, $setter); + } + + my $conditional = $attribute->signature->extendedAttributes->{"Conditional"}; + if ($conditional) { + $conditionals{$name} = $conditional; + } + } + foreach my $function (@{$dataNode->functions}) { next unless ($function->isStatic); next if $function->{overloadIndex} && $function->{overloadIndex} > 1; @@ -1714,119 +1760,130 @@ sub GenerateImplementation my $name = $attribute->signature->name; my $type = $codeGenerator->StripModule($attribute->signature->type); $codeGenerator->AssertNotSequenceType($type); - my $getFunctionName = "js" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : ""); + my $getFunctionName = GetAttributeGetterName($interfaceName, $className, $attribute); my $implGetterFunctionName = $codeGenerator->WK_lcfirst($name); my $attributeConditionalString = $codeGenerator->GenerateConditionalString($attribute->signature); push(@implContent, "#if ${attributeConditionalString}\n") if $attributeConditionalString; - push(@implContent, "JSValue ${getFunctionName}(ExecState* exec, JSValue slotBase, PropertyName)\n"); + push(@implContent, "JSValue ${getFunctionName}(ExecState* exec, JSValue"); + push(@implContent, " slotBase") if !$attribute->isStatic; + push(@implContent, ", PropertyName)\n"); push(@implContent, "{\n"); - push(@implContent, " ${className}* castedThis = jsCast<$className*>(asObject(slotBase));\n"); - - if ($attribute->signature->extendedAttributes->{"CachedAttribute"}) { - $needsMarkChildren = 1; - } - if ($dataNode->extendedAttributes->{"CheckSecurity"} && - !$attribute->signature->extendedAttributes->{"DoNotCheckSecurity"} && - !$attribute->signature->extendedAttributes->{"DoNotCheckSecurityOnGetter"}) { - push(@implContent, " if (!castedThis->allowsAccessFrom(exec))\n"); + if ($attribute->isStatic) { + push(@implContent, " ScriptExecutionContext* scriptContext = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->scriptExecutionContext();\n"); + push(@implContent, " if (!scriptContext)\n"); push(@implContent, " return jsUndefined();\n"); - } + push(@implContent, " JSC::JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "${implClassName}::$implGetterFunctionName(scriptContext)", "") . ";\n"); + push(@implContent, " return result;\n"); + } else { + push(@implContent, " ${className}* castedThis = jsCast<$className*>(asObject(slotBase));\n"); - if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCustom"} || $attribute->signature->extendedAttributes->{"CustomGetter"} || $attribute->signature->extendedAttributes->{"JSCustomGetter"}) { - push(@implContent, " return castedThis->$implGetterFunctionName(exec);\n"); - } elsif ($attribute->signature->extendedAttributes->{"CheckSecurityForNode"}) { - $implIncludes{"JSDOMBinding.h"} = 1; - push(@implContent, " $implClassName* impl = static_cast<$implClassName*>(castedThis->impl());\n"); - push(@implContent, " return shouldAllowAccessToNode(exec, impl->" . $attribute->signature->name . "()) ? " . NativeToJSValue($attribute->signature, 0, $implClassName, "impl->$implGetterFunctionName()", "castedThis") . " : jsNull();\n"); - } elsif ($type eq "EventListener") { - $implIncludes{"EventListener.h"} = 1; - push(@implContent, " UNUSED_PARAM(exec);\n"); - push(@implContent, " $implClassName* impl = static_cast<$implClassName*>(castedThis->impl());\n"); - push(@implContent, " if (EventListener* listener = impl->$implGetterFunctionName()) {\n"); - push(@implContent, " if (const JSEventListener* jsListener = JSEventListener::cast(listener)) {\n"); - if ($implClassName eq "Document" || $implClassName eq "WorkerContext" || $implClassName eq "SharedWorkerContext" || $implClassName eq "DedicatedWorkerContext") { - push(@implContent, " if (JSObject* jsFunction = jsListener->jsFunction(impl))\n"); - } else { - push(@implContent, " if (JSObject* jsFunction = jsListener->jsFunction(impl->scriptExecutionContext()))\n"); - } - push(@implContent, " return jsFunction;\n"); - push(@implContent, " }\n"); - push(@implContent, " }\n"); - push(@implContent, " return jsNull();\n"); - } elsif ($attribute->signature->type =~ /Constructor$/) { - my $constructorType = $codeGenerator->StripModule($attribute->signature->type); - $constructorType =~ s/Constructor$//; - # Constructor attribute is only used by DOMWindow.idl, so it's correct to pass castedThis as the global object - # Once JSDOMWrappers have a back-pointer to the globalObject we can pass castedThis->globalObject() - push(@implContent, " return JS" . $constructorType . "::getConstructor(exec, castedThis);\n"); - } elsif (!@{$attribute->getterExceptions}) { - push(@implContent, " UNUSED_PARAM(exec);\n") if !$attribute->signature->extendedAttributes->{"CallWith"}; - - my $cacheIndex = 0; if ($attribute->signature->extendedAttributes->{"CachedAttribute"}) { - $cacheIndex = $currentCachedAttribute; - $currentCachedAttribute++; - push(@implContent, " if (JSValue cachedValue = castedThis->m_" . $attribute->signature->name . ".get())\n"); - push(@implContent, " return cachedValue;\n"); + $needsMarkChildren = 1; } - my @callWithArgs = GenerateCallWith($attribute->signature->extendedAttributes->{"CallWith"}, \@implContent, "jsUndefined()"); + if ($dataNode->extendedAttributes->{"CheckSecurity"} && + !$attribute->signature->extendedAttributes->{"DoNotCheckSecurity"} && + !$attribute->signature->extendedAttributes->{"DoNotCheckSecurityOnGetter"}) { + push(@implContent, " if (!castedThis->allowsAccessFrom(exec))\n"); + push(@implContent, " return jsUndefined();\n"); + } - if ($svgListPropertyType) { - push(@implContent, " JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "castedThis->impl()->$implGetterFunctionName(" . (join ", ", @callWithArgs) . ")", "castedThis") . ";\n"); - } elsif ($svgPropertyOrListPropertyType) { - push(@implContent, " $svgPropertyOrListPropertyType& impl = castedThis->impl()->propertyReference();\n"); - if ($svgPropertyOrListPropertyType eq "float") { # Special case for JSSVGNumber - push(@implContent, " JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "impl", "castedThis") . ";\n"); + if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCustom"} || $attribute->signature->extendedAttributes->{"CustomGetter"} || $attribute->signature->extendedAttributes->{"JSCustomGetter"}) { + push(@implContent, " return castedThis->$implGetterFunctionName(exec);\n"); + } elsif ($attribute->signature->extendedAttributes->{"CheckSecurityForNode"}) { + $implIncludes{"JSDOMBinding.h"} = 1; + push(@implContent, " $implClassName* impl = static_cast<$implClassName*>(castedThis->impl());\n"); + push(@implContent, " return shouldAllowAccessToNode(exec, impl->" . $attribute->signature->name . "()) ? " . NativeToJSValue($attribute->signature, 0, $implClassName, "impl->$implGetterFunctionName()", "castedThis") . " : jsNull();\n"); + } elsif ($type eq "EventListener") { + $implIncludes{"EventListener.h"} = 1; + push(@implContent, " UNUSED_PARAM(exec);\n"); + push(@implContent, " $implClassName* impl = static_cast<$implClassName*>(castedThis->impl());\n"); + push(@implContent, " if (EventListener* listener = impl->$implGetterFunctionName()) {\n"); + push(@implContent, " if (const JSEventListener* jsListener = JSEventListener::cast(listener)) {\n"); + if ($implClassName eq "Document" || $implClassName eq "WorkerContext" || $implClassName eq "SharedWorkerContext" || $implClassName eq "DedicatedWorkerContext") { + push(@implContent, " if (JSObject* jsFunction = jsListener->jsFunction(impl))\n"); } else { - push(@implContent, " JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "impl.$implGetterFunctionName(" . (join ", ", @callWithArgs) . ")", "castedThis") . ";\n"); - + push(@implContent, " if (JSObject* jsFunction = jsListener->jsFunction(impl->scriptExecutionContext()))\n"); } - } else { - my ($functionName, @arguments) = $codeGenerator->GetterExpression(\%implIncludes, $interfaceName, $attribute); - if ($attribute->signature->extendedAttributes->{"ImplementedBy"}) { - my $implementedBy = $attribute->signature->extendedAttributes->{"ImplementedBy"}; - $implIncludes{"${implementedBy}.h"} = 1; - $functionName = "${implementedBy}::${functionName}"; - unshift(@arguments, "impl"); - } else { - $functionName = "impl->${functionName}"; + push(@implContent, " return jsFunction;\n"); + push(@implContent, " }\n"); + push(@implContent, " }\n"); + push(@implContent, " return jsNull();\n"); + } elsif ($attribute->signature->type =~ /Constructor$/) { + my $constructorType = $codeGenerator->StripModule($attribute->signature->type); + $constructorType =~ s/Constructor$//; + # Constructor attribute is only used by DOMWindow.idl, so it's correct to pass castedThis as the global object + # Once JSDOMWrappers have a back-pointer to the globalObject we can pass castedThis->globalObject() + push(@implContent, " return JS" . $constructorType . "::getConstructor(exec, castedThis);\n"); + } elsif (!@{$attribute->getterExceptions}) { + push(@implContent, " UNUSED_PARAM(exec);\n") if !$attribute->signature->extendedAttributes->{"CallWith"}; + + my $cacheIndex = 0; + if ($attribute->signature->extendedAttributes->{"CachedAttribute"}) { + $cacheIndex = $currentCachedAttribute; + $currentCachedAttribute++; + push(@implContent, " if (JSValue cachedValue = castedThis->m_" . $attribute->signature->name . ".get())\n"); + push(@implContent, " return cachedValue;\n"); } - unshift(@arguments, @callWithArgs); + my @callWithArgs = GenerateCallWith($attribute->signature->extendedAttributes->{"CallWith"}, \@implContent, "jsUndefined()"); - my $jsType = NativeToJSValue($attribute->signature, 0, $implClassName, "${functionName}(" . join(", ", @arguments) . ")", "castedThis"); - push(@implContent, " $implClassName* impl = static_cast<$implClassName*>(castedThis->impl());\n"); - if ($codeGenerator->IsSVGAnimatedType($type)) { - push(@implContent, " RefPtr<$type> obj = $jsType;\n"); - push(@implContent, " JSValue result = toJS(exec, castedThis->globalObject(), obj.get());\n"); + if ($svgListPropertyType) { + push(@implContent, " JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "castedThis->impl()->$implGetterFunctionName(" . (join ", ", @callWithArgs) . ")", "castedThis") . ";\n"); + } elsif ($svgPropertyOrListPropertyType) { + push(@implContent, " $svgPropertyOrListPropertyType& impl = castedThis->impl()->propertyReference();\n"); + if ($svgPropertyOrListPropertyType eq "float") { # Special case for JSSVGNumber + push(@implContent, " JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "impl", "castedThis") . ";\n"); + } else { + push(@implContent, " JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "impl.$implGetterFunctionName(" . (join ", ", @callWithArgs) . ")", "castedThis") . ";\n"); + + } } else { - push(@implContent, " JSValue result = $jsType;\n"); - } - } + my ($functionName, @arguments) = $codeGenerator->GetterExpression(\%implIncludes, $interfaceName, $attribute); + if ($attribute->signature->extendedAttributes->{"ImplementedBy"}) { + my $implementedBy = $attribute->signature->extendedAttributes->{"ImplementedBy"}; + $implIncludes{"${implementedBy}.h"} = 1; + $functionName = "${implementedBy}::${functionName}"; + unshift(@arguments, "impl"); + } else { + $functionName = "impl->${functionName}"; + } - push(@implContent, " castedThis->m_" . $attribute->signature->name . ".set(exec->globalData(), castedThis, result);\n") if ($attribute->signature->extendedAttributes->{"CachedAttribute"}); - push(@implContent, " return result;\n"); + unshift(@arguments, @callWithArgs); - } else { - my @arguments = ("ec"); - push(@implContent, " ExceptionCode ec = 0;\n"); + my $jsType = NativeToJSValue($attribute->signature, 0, $implClassName, "${functionName}(" . join(", ", @arguments) . ")", "castedThis"); + push(@implContent, " $implClassName* impl = static_cast<$implClassName*>(castedThis->impl());\n"); + if ($codeGenerator->IsSVGAnimatedType($type)) { + push(@implContent, " RefPtr<$type> obj = $jsType;\n"); + push(@implContent, " JSValue result = toJS(exec, castedThis->globalObject(), obj.get());\n"); + } else { + push(@implContent, " JSValue result = $jsType;\n"); + } + } - unshift(@arguments, GenerateCallWith($attribute->signature->extendedAttributes->{"CallWith"}, \@implContent, "jsUndefined()")); + push(@implContent, " castedThis->m_" . $attribute->signature->name . ".set(exec->globalData(), castedThis, result);\n") if ($attribute->signature->extendedAttributes->{"CachedAttribute"}); + push(@implContent, " return result;\n"); - if ($svgPropertyOrListPropertyType) { - push(@implContent, " $svgPropertyOrListPropertyType impl(*castedThis->impl());\n"); - push(@implContent, " JSC::JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "impl.$implGetterFunctionName(" . join(", ", @arguments) . ")", "castedThis") . ";\n"); } else { - push(@implContent, " $implClassName* impl = static_cast<$implClassName*>(castedThis->impl());\n"); - push(@implContent, " JSC::JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "impl->$implGetterFunctionName(" . join(", ", @arguments) . ")", "castedThis") . ";\n"); - } + my @arguments = ("ec"); + push(@implContent, " ExceptionCode ec = 0;\n"); - push(@implContent, " setDOMException(exec, ec);\n"); - push(@implContent, " return result;\n"); + unshift(@arguments, GenerateCallWith($attribute->signature->extendedAttributes->{"CallWith"}, \@implContent, "jsUndefined()")); + + if ($svgPropertyOrListPropertyType) { + push(@implContent, " $svgPropertyOrListPropertyType impl(*castedThis->impl());\n"); + push(@implContent, " JSC::JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "impl.$implGetterFunctionName(" . join(", ", @arguments) . ")", "castedThis") . ";\n"); + } else { + push(@implContent, " $implClassName* impl = static_cast<$implClassName*>(castedThis->impl());\n"); + push(@implContent, " JSC::JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "impl->$implGetterFunctionName(" . join(", ", @arguments) . ")", "castedThis") . ";\n"); + } + + push(@implContent, " setDOMException(exec, ec);\n"); + push(@implContent, " return result;\n"); + } } push(@implContent, "}\n\n"); @@ -1856,7 +1913,7 @@ sub GenerateImplementation # Check if we have any writable attributes my $hasReadWriteProperties = 0; foreach my $attribute (@{$dataNode->attributes}) { - $hasReadWriteProperties = 1 if $attribute->type !~ /^readonly/; + $hasReadWriteProperties = 1 if $attribute->type !~ /^readonly/ && !$attribute->isStatic; } my $hasSetter = $hasReadWriteProperties @@ -1904,126 +1961,137 @@ sub GenerateImplementation if ($attribute->type !~ /^readonly/) { my $name = $attribute->signature->name; my $type = $codeGenerator->StripModule($attribute->signature->type); - my $putFunctionName = "setJS" . $interfaceName . $codeGenerator->WK_ucfirst($name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : ""); + my $putFunctionName = GetAttributeSetterName($interfaceName, $className, $attribute); my $implSetterFunctionName = $codeGenerator->WK_ucfirst($name); my $attributeConditionalString = $codeGenerator->GenerateConditionalString($attribute->signature); push(@implContent, "#if ${attributeConditionalString}\n") if $attributeConditionalString; - push(@implContent, "void ${putFunctionName}(ExecState* exec, JSObject* thisObject, JSValue value)\n"); + push(@implContent, "void ${putFunctionName}(ExecState* exec, JSObject*"); + push(@implContent, " thisObject") if !$attribute->isStatic; + push(@implContent, ", JSValue value)\n"); push(@implContent, "{\n"); - push(@implContent, " UNUSED_PARAM(exec);\n"); - if ($dataNode->extendedAttributes->{"CheckSecurity"} && !$attribute->signature->extendedAttributes->{"DoNotCheckSecurity"}) { - if ($interfaceName eq "DOMWindow") { - push(@implContent, " if (!jsCast<$className*>(thisObject)->allowsAccessFrom(exec))\n"); - } else { - push(@implContent, " if (!shouldAllowAccessToFrame(exec, jsCast<$className*>(thisObject)->impl()->frame()))\n"); - } + if ($attribute->isStatic) { + push(@implContent, " ScriptExecutionContext* scriptContext = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->scriptExecutionContext();\n"); + push(@implContent, " if (!scriptContext)\n"); push(@implContent, " return;\n"); - } - - if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCustom"} || $attribute->signature->extendedAttributes->{"CustomSetter"} || $attribute->signature->extendedAttributes->{"JSCustomSetter"}) { - push(@implContent, " jsCast<$className*>(thisObject)->set$implSetterFunctionName(exec, value);\n"); - } elsif ($type eq "EventListener") { - $implIncludes{"JSEventListener.h"} = 1; - push(@implContent, " UNUSED_PARAM(exec);\n"); - push(@implContent, " ${className}* castedThis = jsCast<${className}*>(thisObject);\n"); - my $windowEventListener = $attribute->signature->extendedAttributes->{"JSWindowEventListener"}; - if ($windowEventListener) { - push(@implContent, " JSDOMGlobalObject* globalObject = castedThis->globalObject();\n"); - } - push(@implContent, " $implClassName* impl = static_cast<$implClassName*>(castedThis->impl());\n"); - if ((($interfaceName eq "DOMWindow") or ($interfaceName eq "WorkerContext")) and $name eq "onerror") { - $implIncludes{"JSErrorHandler.h"} = 1; - push(@implContent, " impl->set$implSetterFunctionName(createJSErrorHandler(exec, value, thisObject));\n"); - } else { - push(@implContent, GenerateAttributeEventListenerCall($className, $implSetterFunctionName, $windowEventListener)); - } - } elsif ($attribute->signature->type =~ /Constructor$/) { - my $constructorType = $attribute->signature->type; - $constructorType =~ s/Constructor$//; - # $constructorType ~= /Constructor$/ indicates that it is NamedConstructor. - # We do not generate the header file for NamedConstructor of class XXXX, - # since we generate the NamedConstructor declaration into the header file of class XXXX. - if ($constructorType ne "DOMObject" and $constructorType !~ /Constructor$/) { - AddToImplIncludes("JS" . $constructorType . ".h", $attribute->signature->extendedAttributes->{"Conditional"}); - } - push(@implContent, " // Shadowing a built-in constructor\n"); - if ($interfaceName eq "DOMWindow" && $className eq "JSblah") { - # FIXME: This branch never executes and should be removed. - push(@implContent, " jsCast<$className*>(thisObject)->putDirect(exec->globalData(), exec->propertyNames().constructor, value);\n"); - } else { - push(@implContent, " jsCast<$className*>(thisObject)->putDirect(exec->globalData(), Identifier(exec, \"$name\"), value);\n"); - } - } elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) { - push(@implContent, " // Shadowing a built-in object\n"); - push(@implContent, " jsCast<$className*>(thisObject)->putDirect(exec->globalData(), Identifier(exec, \"$name\"), value);\n"); + my $nativeValue = JSValueToNative($attribute->signature, "value"); + push(@implContent, " ${implClassName}::set$implSetterFunctionName(scriptContext, ${nativeValue});\n"); } else { - push(@implContent, " $className* castedThis = jsCast<$className*>(thisObject);\n"); - push(@implContent, " $implType* impl = static_cast<$implType*>(castedThis->impl());\n"); - push(@implContent, " ExceptionCode ec = 0;\n") if @{$attribute->setterExceptions}; - - # If the "StrictTypeChecking" extended attribute is present, and the attribute's type is an - # interface type, then if the incoming value does not implement that interface, a TypeError - # is thrown rather than silently passing NULL to the C++ code. - # Per the Web IDL and ECMAScript specifications, incoming values can always be converted to - # both strings and numbers, so do not throw TypeError if the attribute is of these types. - if ($attribute->signature->extendedAttributes->{"StrictTypeChecking"}) { - $implIncludes{"<runtime/Error.h>"} = 1; - - my $argType = $attribute->signature->type; - if (!IsNativeType($argType)) { - push(@implContent, " if (!value.isUndefinedOrNull() && !value.inherits(&JS${argType}::s_info)) {\n"); - push(@implContent, " throwVMTypeError(exec);\n"); - push(@implContent, " return;\n"); - push(@implContent, " };\n"); + push(@implContent, " UNUSED_PARAM(exec);\n"); + + if ($dataNode->extendedAttributes->{"CheckSecurity"} && !$attribute->signature->extendedAttributes->{"DoNotCheckSecurity"}) { + if ($interfaceName eq "DOMWindow") { + push(@implContent, " if (!jsCast<$className*>(thisObject)->allowsAccessFrom(exec))\n"); + } else { + push(@implContent, " if (!shouldAllowAccessToFrame(exec, jsCast<$className*>(thisObject)->impl()->frame()))\n"); } + push(@implContent, " return;\n"); } - my $nativeValue = JSValueToNative($attribute->signature, "value"); - if ($svgPropertyOrListPropertyType) { - if ($svgPropertyType) { - push(@implContent, " if (impl->isReadOnly()) {\n"); - push(@implContent, " setDOMException(exec, NO_MODIFICATION_ALLOWED_ERR);\n"); - push(@implContent, " return;\n"); - push(@implContent, " }\n"); - $implIncludes{"ExceptionCode.h"} = 1; + if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCustom"} || $attribute->signature->extendedAttributes->{"CustomSetter"} || $attribute->signature->extendedAttributes->{"JSCustomSetter"}) { + push(@implContent, " jsCast<$className*>(thisObject)->set$implSetterFunctionName(exec, value);\n"); + } elsif ($type eq "EventListener") { + $implIncludes{"JSEventListener.h"} = 1; + push(@implContent, " UNUSED_PARAM(exec);\n"); + push(@implContent, " ${className}* castedThis = jsCast<${className}*>(thisObject);\n"); + my $windowEventListener = $attribute->signature->extendedAttributes->{"JSWindowEventListener"}; + if ($windowEventListener) { + push(@implContent, " JSDOMGlobalObject* globalObject = castedThis->globalObject();\n"); } - push(@implContent, " $svgPropertyOrListPropertyType& podImpl = impl->propertyReference();\n"); - if ($svgPropertyOrListPropertyType eq "float") { # Special case for JSSVGNumber - push(@implContent, " podImpl = $nativeValue;\n"); + push(@implContent, " $implClassName* impl = static_cast<$implClassName*>(castedThis->impl());\n"); + if ((($interfaceName eq "DOMWindow") or ($interfaceName eq "WorkerContext")) and $name eq "onerror") { + $implIncludes{"JSErrorHandler.h"} = 1; + push(@implContent, " impl->set$implSetterFunctionName(createJSErrorHandler(exec, value, thisObject));\n"); } else { - push(@implContent, " podImpl.set$implSetterFunctionName($nativeValue"); - push(@implContent, ", ec") if @{$attribute->setterExceptions}; - push(@implContent, ");\n"); - push(@implContent, " setDOMException(exec, ec);\n") if @{$attribute->setterExceptions}; + push(@implContent, GenerateAttributeEventListenerCall($className, $implSetterFunctionName, $windowEventListener)); } - if ($svgPropertyType) { - if (@{$attribute->setterExceptions}) { - push(@implContent, " if (!ec)\n"); - push(@implContent, " impl->commitChange();\n"); - } else { - push(@implContent, " impl->commitChange();\n"); - } + } elsif ($attribute->signature->type =~ /Constructor$/) { + my $constructorType = $attribute->signature->type; + $constructorType =~ s/Constructor$//; + # $constructorType ~= /Constructor$/ indicates that it is NamedConstructor. + # We do not generate the header file for NamedConstructor of class XXXX, + # since we generate the NamedConstructor declaration into the header file of class XXXX. + if ($constructorType ne "DOMObject" and $constructorType !~ /Constructor$/) { + AddToImplIncludes("JS" . $constructorType . ".h", $attribute->signature->extendedAttributes->{"Conditional"}); } - } else { - my ($functionName, @arguments) = $codeGenerator->SetterExpression(\%implIncludes, $interfaceName, $attribute); - push(@arguments, $nativeValue); - if ($attribute->signature->extendedAttributes->{"ImplementedBy"}) { - my $implementedBy = $attribute->signature->extendedAttributes->{"ImplementedBy"}; - $implIncludes{"${implementedBy}.h"} = 1; - unshift(@arguments, "impl"); - $functionName = "${implementedBy}::${functionName}"; + push(@implContent, " // Shadowing a built-in constructor\n"); + if ($interfaceName eq "DOMWindow" && $className eq "JSblah") { + # FIXME: This branch never executes and should be removed. + push(@implContent, " jsCast<$className*>(thisObject)->putDirect(exec->globalData(), exec->propertyNames().constructor, value);\n"); } else { - $functionName = "impl->${functionName}"; + push(@implContent, " jsCast<$className*>(thisObject)->putDirect(exec->globalData(), Identifier(exec, \"$name\"), value);\n"); } + } elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) { + push(@implContent, " // Shadowing a built-in object\n"); + push(@implContent, " jsCast<$className*>(thisObject)->putDirect(exec->globalData(), Identifier(exec, \"$name\"), value);\n"); + } else { + push(@implContent, " $className* castedThis = jsCast<$className*>(thisObject);\n"); + push(@implContent, " $implType* impl = static_cast<$implType*>(castedThis->impl());\n"); + push(@implContent, " ExceptionCode ec = 0;\n") if @{$attribute->setterExceptions}; + + # If the "StrictTypeChecking" extended attribute is present, and the attribute's type is an + # interface type, then if the incoming value does not implement that interface, a TypeError + # is thrown rather than silently passing NULL to the C++ code. + # Per the Web IDL and ECMAScript specifications, incoming values can always be converted to + # both strings and numbers, so do not throw TypeError if the attribute is of these types. + if ($attribute->signature->extendedAttributes->{"StrictTypeChecking"}) { + $implIncludes{"<runtime/Error.h>"} = 1; + + my $argType = $attribute->signature->type; + if (!IsNativeType($argType)) { + push(@implContent, " if (!value.isUndefinedOrNull() && !value.inherits(&JS${argType}::s_info)) {\n"); + push(@implContent, " throwVMTypeError(exec);\n"); + push(@implContent, " return;\n"); + push(@implContent, " };\n"); + } + } + + my $nativeValue = JSValueToNative($attribute->signature, "value"); + if ($svgPropertyOrListPropertyType) { + if ($svgPropertyType) { + push(@implContent, " if (impl->isReadOnly()) {\n"); + push(@implContent, " setDOMException(exec, NO_MODIFICATION_ALLOWED_ERR);\n"); + push(@implContent, " return;\n"); + push(@implContent, " }\n"); + $implIncludes{"ExceptionCode.h"} = 1; + } + push(@implContent, " $svgPropertyOrListPropertyType& podImpl = impl->propertyReference();\n"); + if ($svgPropertyOrListPropertyType eq "float") { # Special case for JSSVGNumber + push(@implContent, " podImpl = $nativeValue;\n"); + } else { + push(@implContent, " podImpl.set$implSetterFunctionName($nativeValue"); + push(@implContent, ", ec") if @{$attribute->setterExceptions}; + push(@implContent, ");\n"); + push(@implContent, " setDOMException(exec, ec);\n") if @{$attribute->setterExceptions}; + } + if ($svgPropertyType) { + if (@{$attribute->setterExceptions}) { + push(@implContent, " if (!ec)\n"); + push(@implContent, " impl->commitChange();\n"); + } else { + push(@implContent, " impl->commitChange();\n"); + } + } + } else { + my ($functionName, @arguments) = $codeGenerator->SetterExpression(\%implIncludes, $interfaceName, $attribute); + push(@arguments, $nativeValue); + if ($attribute->signature->extendedAttributes->{"ImplementedBy"}) { + my $implementedBy = $attribute->signature->extendedAttributes->{"ImplementedBy"}; + $implIncludes{"${implementedBy}.h"} = 1; + unshift(@arguments, "impl"); + $functionName = "${implementedBy}::${functionName}"; + } else { + $functionName = "impl->${functionName}"; + } - unshift(@arguments, GenerateCallWith($attribute->signature->extendedAttributes->{"CallWith"}, \@implContent, "")); + unshift(@arguments, GenerateCallWith($attribute->signature->extendedAttributes->{"CallWith"}, \@implContent, "")); - push(@arguments, "ec") if @{$attribute->setterExceptions}; - push(@implContent, " ${functionName}(" . join(", ", @arguments) . ");\n"); - push(@implContent, " setDOMException(exec, ec);\n") if @{$attribute->setterExceptions}; + push(@arguments, "ec") if @{$attribute->setterExceptions}; + push(@implContent, " ${functionName}(" . join(", ", @arguments) . ");\n"); + push(@implContent, " setDOMException(exec, ec);\n") if @{$attribute->setterExceptions}; + } } } diff --git a/Source/WebCore/bindings/scripts/IDLParser.pm b/Source/WebCore/bindings/scripts/IDLParser.pm index af02c64bb..057c03d6c 100644 --- a/Source/WebCore/bindings/scripts/IDLParser.pm +++ b/Source/WebCore/bindings/scripts/IDLParser.pm @@ -337,11 +337,12 @@ sub ParseInterface if ($line =~ /\Wattribute\W/) { $line =~ /$IDLStructure::interfaceAttributeSelector/; - my $attributeType = (defined($1) ? $1 : die("Parsing error!\nSource:\n$line\n)")); - my $attributeExtendedAttributes = (defined($2) ? $2 : " "); chop($attributeExtendedAttributes); + my $isStatic = defined($1); + my $attributeType = (defined($2) ? $2 : die("Parsing error!\nSource:\n$line\n)")); + my $attributeExtendedAttributes = (defined($3) ? $3 : " "); chop($attributeExtendedAttributes); - my $attributeDataType = (defined($3) ? $3 : die("Parsing error!\nSource:\n$line\n)")); - my $attributeDataName = (defined($4) ? $4 : die("Parsing error!\nSource:\n$line\n)")); + my $attributeDataType = (defined($4) ? $4 : die("Parsing error!\nSource:\n$line\n)")); + my $attributeDataName = (defined($5) ? $5 : die("Parsing error!\nSource:\n$line\n)")); ('' =~ /^/); # Reset variables needed for regexp matching @@ -353,6 +354,7 @@ sub ParseInterface my $newDataNode = new domAttribute(); $newDataNode->type($attributeType); + $newDataNode->isStatic($isStatic); $newDataNode->signature(new domSignature()); $newDataNode->signature->name($attributeDataName); @@ -362,7 +364,7 @@ sub ParseInterface my $arrayRef = $dataNode->attributes; push(@$arrayRef, $newDataNode); - print " | |> Attribute; TYPE \"$attributeType\" DATA NAME \"$attributeDataName\" DATA TYPE \"$attributeDataType\" GET EXCEPTION? \"$getterException\" SET EXCEPTION? \"$setterException\"" . + print " | |> Attribute; STATIC? \"$isStatic\" TYPE \"$attributeType\" DATA NAME \"$attributeDataName\" DATA TYPE \"$attributeDataType\" GET EXCEPTION? \"$getterException\" SET EXCEPTION? \"$setterException\"" . dumpExtendedAttributes("\n | ", $newDataNode->signature->extendedAttributes) . "\n" unless $beQuiet; $getterException =~ s/\s+//g; @@ -391,7 +393,7 @@ sub ParseInterface $newDataNode->signature->type($methodType); $newDataNode->signature->extendedAttributes(parseExtendedAttributes($methodExtendedAttributes)); - print " | |- Method; TYPE \"$methodType\" NAME \"$methodName\" EXCEPTION? \"$methodException\"" . + print " | |- Method; STATIC? \"$isStatic\" TYPE \"$methodType\" NAME \"$methodName\" EXCEPTION? \"$methodException\"" . dumpExtendedAttributes("\n | ", $newDataNode->signature->extendedAttributes) . "\n" unless $beQuiet; $methodException =~ s/\s+//g; diff --git a/Source/WebCore/bindings/scripts/IDLStructure.pm b/Source/WebCore/bindings/scripts/IDLStructure.pm index 5e1ab45f9..2e3fb6c80 100644 --- a/Source/WebCore/bindings/scripts/IDLStructure.pm +++ b/Source/WebCore/bindings/scripts/IDLStructure.pm @@ -55,6 +55,7 @@ struct( domFunction => { # Used to represent domClass contents (name of attribute, signature) struct( domAttribute => { type => '$', # Attribute type (including namespace) + isStatic => '$', signature => '$', # Attribute signature getterExceptions => '@', # Possibly raised exceptions. setterExceptions => '@', # Possibly raised exceptions. @@ -110,6 +111,6 @@ our $interfaceSelector = '(interface|exception)\s*((?:' . $extendedAttributeSynt our $interfaceMethodSelector = '\s*((?:' . $extendedAttributeSyntax . ' )?)(static\s+)?' . $supportedTypes . '\s*(' . $idlIdNs . '*)\s*\(\s*([a-zA-Z0-9:\s,=\[\]<>?]*)'; our $interfaceParameterSelector = '(in|out)\s*((?:' . $extendedAttributeSyntax . ' )?)' . $supportedTypes . $supportedTypeSuffix . '\s*(' . $idlIdNs . '*)'; -our $interfaceAttributeSelector = '\s*(readonly attribute|attribute)\s*(' . $extendedAttributeSyntax . ' )?' . $supportedTypes . '\s*(' . $idlType . '*)'; +our $interfaceAttributeSelector = '\s*(static\s+)?(readonly attribute|attribute)\s*(' . $extendedAttributeSyntax . ' )?' . $supportedTypes . '\s*(' . $idlType . '*)'; 1; diff --git a/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp b/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp index 255eb560b..ecb2174d4 100644 --- a/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp +++ b/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp @@ -166,6 +166,8 @@ static const HashTableValue JSTestObjConstructorTableValues[] = { "CONST_VALUE_13", DontDelete | ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjCONST_VALUE_13), (intptr_t)0, NoIntrinsic }, { "CONST_VALUE_14", DontDelete | ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjCONST_VALUE_14), (intptr_t)0, NoIntrinsic }, { "CONST_JAVASCRIPT", DontDelete | ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjCONST_JAVASCRIPT), (intptr_t)0, NoIntrinsic }, + { "staticReadOnlyIntAttr", DontDelete | ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjConstructorStaticReadOnlyIntAttr), (intptr_t)0, NoIntrinsic }, + { "staticStringAttr", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjConstructorStaticStringAttr), (intptr_t)setJSTestObjConstructorStaticStringAttr, NoIntrinsic }, { "classMethod", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestObjConstructorFunctionClassMethod), (intptr_t)0, NoIntrinsic }, { "classMethodWithOptional", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestObjConstructorFunctionClassMethodWithOptional), (intptr_t)1, NoIntrinsic }, { "classMethod2", DontDelete | JSC::Function, (intptr_t)static_cast<NativeFunction>(jsTestObjConstructorFunctionClassMethod2), (intptr_t)1, NoIntrinsic }, @@ -411,6 +413,26 @@ JSValue jsTestObjReadOnlyTestObjAttr(ExecState* exec, JSValue slotBase, Property } +JSValue jsTestObjConstructorStaticReadOnlyIntAttr(ExecState* exec, JSValue, PropertyName) +{ + ScriptExecutionContext* scriptContext = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->scriptExecutionContext(); + if (!scriptContext) + return jsUndefined(); + JSC::JSValue result = jsNumber(TestObj::staticReadOnlyIntAttr(scriptContext)); + return result; +} + + +JSValue jsTestObjConstructorStaticStringAttr(ExecState* exec, JSValue, PropertyName) +{ + ScriptExecutionContext* scriptContext = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->scriptExecutionContext(); + if (!scriptContext) + return jsUndefined(); + JSC::JSValue result = jsString(exec, TestObj::staticStringAttr(scriptContext)); + return result; +} + + JSValue jsTestObjShortAttr(ExecState* exec, JSValue slotBase, PropertyName) { JSTestObj* castedThis = jsCast<JSTestObj*>(asObject(slotBase)); @@ -914,6 +936,15 @@ void JSTestObj::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JS lookupPut<JSTestObj, Base>(exec, propertyName, value, &JSTestObjTable, thisObject, slot); } +void setJSTestObjConstructorStaticStringAttr(ExecState* exec, JSObject*, JSValue value) +{ + ScriptExecutionContext* scriptContext = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->scriptExecutionContext(); + if (!scriptContext) + return; + TestObj::setStaticStringAttr(scriptContext, ustringToString(value.isEmpty() ? UString() : value.toString(exec)->value(exec))); +} + + void setJSTestObjShortAttr(ExecState* exec, JSObject* thisObject, JSValue value) { UNUSED_PARAM(exec); diff --git a/Source/WebCore/bindings/scripts/test/JS/JSTestObj.h b/Source/WebCore/bindings/scripts/test/JS/JSTestObj.h index c74b23f44..13d72cbf0 100644 --- a/Source/WebCore/bindings/scripts/test/JS/JSTestObj.h +++ b/Source/WebCore/bindings/scripts/test/JS/JSTestObj.h @@ -220,6 +220,9 @@ JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionStrictFunction(JSC:: JSC::JSValue jsTestObjReadOnlyIntAttr(JSC::ExecState*, JSC::JSValue, JSC::PropertyName); JSC::JSValue jsTestObjReadOnlyStringAttr(JSC::ExecState*, JSC::JSValue, JSC::PropertyName); JSC::JSValue jsTestObjReadOnlyTestObjAttr(JSC::ExecState*, JSC::JSValue, JSC::PropertyName); +JSC::JSValue jsTestObjConstructorStaticReadOnlyIntAttr(JSC::ExecState*, JSC::JSValue, JSC::PropertyName); +JSC::JSValue jsTestObjConstructorStaticStringAttr(JSC::ExecState*, JSC::JSValue, JSC::PropertyName); +void setJSTestObjConstructorStaticStringAttr(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); JSC::JSValue jsTestObjShortAttr(JSC::ExecState*, JSC::JSValue, JSC::PropertyName); void setJSTestObjShortAttr(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); JSC::JSValue jsTestObjUnsignedShortAttr(JSC::ExecState*, JSC::JSValue, JSC::PropertyName); diff --git a/Source/WebCore/bindings/scripts/test/TestObj.idl b/Source/WebCore/bindings/scripts/test/TestObj.idl index 513df1074..34265b2e2 100644 --- a/Source/WebCore/bindings/scripts/test/TestObj.idl +++ b/Source/WebCore/bindings/scripts/test/TestObj.idl @@ -38,6 +38,10 @@ module test { readonly attribute long readOnlyIntAttr; readonly attribute DOMString readOnlyStringAttr; readonly attribute TestObj readOnlyTestObjAttr; +#if defined(TESTING_JS) + static readonly attribute long staticReadOnlyIntAttr; + static attribute DOMString staticStringAttr; +#endif attribute short shortAttr; attribute unsigned short unsignedShortAttr; attribute long intAttr; diff --git a/Source/WebCore/bindings/v8/DOMDataStore.cpp b/Source/WebCore/bindings/v8/DOMDataStore.cpp index 95efd5059..7fb8b042d 100644 --- a/Source/WebCore/bindings/v8/DOMDataStore.cpp +++ b/Source/WebCore/bindings/v8/DOMDataStore.cpp @@ -121,11 +121,11 @@ void* DOMDataStore::getDOMWrapperMap(DOMWrapperMapType type) void DOMDataStore::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::Binding); - memoryObjectInfo->reportInstrumentedPointer(m_domNodeMap); - memoryObjectInfo->reportInstrumentedPointer(m_activeDomNodeMap); - memoryObjectInfo->reportInstrumentedPointer(m_domObjectMap); - memoryObjectInfo->reportInstrumentedPointer(m_activeDomObjectMap); + MemoryClassInfo<DOMDataStore> info(memoryObjectInfo, this, MemoryInstrumentation::Binding); + info.addInstrumentedMember(m_domNodeMap); + info.addInstrumentedMember(m_activeDomNodeMap); + info.addInstrumentedMember(m_domObjectMap); + info.addInstrumentedMember(m_activeDomObjectMap); } // Called when the object is near death (not reachable from JS roots). diff --git a/Source/WebCore/bindings/v8/IntrusiveDOMWrapperMap.h b/Source/WebCore/bindings/v8/IntrusiveDOMWrapperMap.h index 52308bdc4..1200d123c 100644 --- a/Source/WebCore/bindings/v8/IntrusiveDOMWrapperMap.h +++ b/Source/WebCore/bindings/v8/IntrusiveDOMWrapperMap.h @@ -104,9 +104,9 @@ class ChunkedTable { void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::Binding); + MemoryClassInfo<ChunkedTable> info(memoryObjectInfo, this, MemoryInstrumentation::Binding); for (Chunk* chunk = m_chunks; chunk; chunk = chunk->m_previous) - memoryObjectInfo->reportPointer(chunk, MemoryInstrumentation::Binding); + info.addMember(chunk); } private: @@ -186,8 +186,8 @@ public: virtual void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const OVERRIDE { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::Binding); - memoryObjectInfo->reportInstrumentedObject(m_table); + MemoryClassInfo<IntrusiveDOMWrapperMap> info(memoryObjectInfo, this, MemoryInstrumentation::Binding); + info.addInstrumentedMember(m_table); } private: diff --git a/Source/WebCore/bindings/v8/ScriptCachedFrameData.cpp b/Source/WebCore/bindings/v8/ScriptCachedFrameData.cpp index 0a86d612e..f7af1b43d 100644 --- a/Source/WebCore/bindings/v8/ScriptCachedFrameData.cpp +++ b/Source/WebCore/bindings/v8/ScriptCachedFrameData.cpp @@ -25,58 +25,3 @@ #include "config.h" #include "ScriptCachedFrameData.h" - -#if PLATFORM(QT) -// FIXME: the right guard should be ENABLE(PAGE_CACHE). Replace with the right guard, once -// https://bugs.webkit.org/show_bug.cgi?id=35061 is fixed. - -#include "Frame.h" -#include "V8DOMWindow.h" - -namespace WebCore { - -ScriptCachedFrameData::ScriptCachedFrameData(Frame* frame) - : m_domWindow(0) -{ - v8::HandleScope handleScope; - // The context can only be the context of the main world. - ASSERT(V8Proxy::mainWorldContext(frame) == V8Proxy::context(frame)); - m_context.set(V8Proxy::mainWorldContext(frame)); - // The context can be 0, e.g. if JS is disabled in the browser. - if (m_context.get().IsEmpty()) - return; - m_global.set(m_context.get()->Global()); - m_domWindow = frame->domWindow(); -} - -DOMWindow* ScriptCachedFrameData::domWindow() const -{ - return m_domWindow; -} - -void ScriptCachedFrameData::restore(Frame* frame) -{ - if (m_context.get().IsEmpty()) - return; - - if (!frame || !frame->script()->canExecuteScripts(NotAboutToExecuteScript)) - return; - - v8::HandleScope handleScope; - v8::Context::Scope contextScope(m_context.get()); - - m_context.get()->ReattachGlobal(m_global.get()); - V8Proxy* proxy = V8Proxy::retrieve(frame); - if (proxy) - proxy->windowShell()->setContext(m_context.get()); -} - -void ScriptCachedFrameData::clear() -{ - m_context.clear(); - m_global.clear(); -} - -} // namespace WebCore - -#endif // PLATFORM(QT) diff --git a/Source/WebCore/bindings/v8/ScriptCachedFrameData.h b/Source/WebCore/bindings/v8/ScriptCachedFrameData.h index 1e3a2f643..75e51d465 100644 --- a/Source/WebCore/bindings/v8/ScriptCachedFrameData.h +++ b/Source/WebCore/bindings/v8/ScriptCachedFrameData.h @@ -51,37 +51,6 @@ public: } // namespace WebCore -#elif PLATFORM(QT) -// FIXME: the right guard should be ENABLE(PAGE_CACHE). Replace with the right guard, once -// https://bugs.webkit.org/show_bug.cgi?id=35061 is fixed. - -#include "OwnHandle.h" -#include <v8.h> -#include <wtf/Noncopyable.h> - -namespace WebCore { - -class Frame; -class DOMWindow; - -class ScriptCachedFrameData { - WTF_MAKE_NONCOPYABLE(ScriptCachedFrameData); -public: - ScriptCachedFrameData(Frame*); - ~ScriptCachedFrameData() { } - - void restore(Frame*); - void clear(); - DOMWindow* domWindow() const; - -private: - OwnHandle<v8::Object> m_global; - OwnHandle<v8::Context> m_context; - DOMWindow* m_domWindow; -}; - -} // namespace WebCore - #else #error You need to consider whether you want Page Cache and either add a stub or a real implementation. #endif // PLATFORM(CHROMIUM) diff --git a/Source/WebCore/bindings/v8/ScriptController.cpp b/Source/WebCore/bindings/v8/ScriptController.cpp index d0a7e06e2..0a84a1cea 100644 --- a/Source/WebCore/bindings/v8/ScriptController.cpp +++ b/Source/WebCore/bindings/v8/ScriptController.cpp @@ -67,10 +67,6 @@ #include <wtf/StdLibExtras.h> #include <wtf/text/CString.h> -#if PLATFORM(QT) -#include <QtQml/QJSEngine> -#endif - namespace WebCore { void ScriptController::initializeThreading() diff --git a/Source/WebCore/bindings/v8/ScriptController.h b/Source/WebCore/bindings/v8/ScriptController.h index 7c7836876..32cb33513 100644 --- a/Source/WebCore/bindings/v8/ScriptController.h +++ b/Source/WebCore/bindings/v8/ScriptController.h @@ -44,13 +44,6 @@ #include <wtf/RefCounted.h> #include <wtf/Vector.h> -#if PLATFORM(QT) -#include <qglobal.h> -QT_BEGIN_NAMESPACE -class QJSEngine; -QT_END_NAMESPACE -#endif - struct NPObject; namespace WebCore { @@ -180,10 +173,6 @@ public: NPObject* createScriptObjectForPluginElement(HTMLPlugInElement*); NPObject* windowScriptNPObject(); -#if PLATFORM(QT) - QJSEngine* qtScriptEngine(); -#endif - // Dummy method to avoid a bunch of ifdef's in WebCore. void evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld*); static void getAllWorlds(Vector<RefPtr<DOMWrapperWorld> >& worlds); @@ -196,9 +185,6 @@ private: OwnPtr<V8Proxy> m_proxy; typedef HashMap<Widget*, NPObject*> PluginObjectMap; -#if PLATFORM(QT) - OwnPtr<QJSEngine> m_qtScriptEngine; -#endif // A mapping between Widgets and their corresponding script object. // This list is used so that when the plugin dies, we can immediately diff --git a/Source/WebCore/bindings/v8/ScriptProfiler.cpp b/Source/WebCore/bindings/v8/ScriptProfiler.cpp index 07f039e7c..a268f39ae 100644 --- a/Source/WebCore/bindings/v8/ScriptProfiler.cpp +++ b/Source/WebCore/bindings/v8/ScriptProfiler.cpp @@ -223,7 +223,7 @@ void ScriptProfiler::visitExternalArrays(ExternalArrayVisitor* visitor) void ScriptProfiler::collectBindingMemoryInfo(MemoryInstrumentation* instrumentation) { V8BindingPerIsolateData* data = V8BindingPerIsolateData::current(); - instrumentation->reportInstrumentedPointer(data); + instrumentation->addInstrumentedMember(data); } size_t ScriptProfiler::profilerSnapshotsSize() diff --git a/Source/WebCore/bindings/v8/ScriptWrappable.h b/Source/WebCore/bindings/v8/ScriptWrappable.h index 1c2823216..ef2f7619f 100644 --- a/Source/WebCore/bindings/v8/ScriptWrappable.h +++ b/Source/WebCore/bindings/v8/ScriptWrappable.h @@ -54,8 +54,8 @@ public: void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::DOM); - memoryObjectInfo->reportPointer(m_wrapper, MemoryInstrumentation::DOM); + MemoryClassInfo<ScriptWrappable> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + info.addMember(m_wrapper); } private: diff --git a/Source/WebCore/bindings/v8/V8Binding.cpp b/Source/WebCore/bindings/v8/V8Binding.cpp index 8198ad0d6..d282b0dbe 100644 --- a/Source/WebCore/bindings/v8/V8Binding.cpp +++ b/Source/WebCore/bindings/v8/V8Binding.cpp @@ -92,14 +92,14 @@ void V8BindingPerIsolateData::dispose(v8::Isolate* isolate) void V8BindingPerIsolateData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::Binding); - memoryObjectInfo->reportHashMap(m_rawTemplates); - memoryObjectInfo->reportHashMap(m_templates); - memoryObjectInfo->reportInstrumentedObject(m_stringCache); - memoryObjectInfo->reportVector(m_domDataList); + MemoryClassInfo<V8BindingPerIsolateData> info(memoryObjectInfo, this, MemoryInstrumentation::Binding); + info.addHashMap(m_rawTemplates); + info.addHashMap(m_templates); + info.addInstrumentedMember(m_stringCache); + info.addVector(m_domDataList); for (size_t i = 0; i < m_domDataList.size(); i++) - memoryObjectInfo->reportInstrumentedPointer(m_domDataList[i]); + info.addInstrumentedMember(m_domDataList[i]); } // WebCoreStringResource is a helper class for v8ExternalString. It is used @@ -590,8 +590,8 @@ v8::Persistent<v8::FunctionTemplate> getToStringTemplate() void StringCache::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::Binding); - memoryObjectInfo->reportHashMap(m_stringCache); + MemoryClassInfo<StringCache> info(memoryObjectInfo, this, MemoryInstrumentation::Binding); + info.addHashMap(m_stringCache); } PassRefPtr<DOMStringList> v8ValueToWebCoreDOMStringList(v8::Handle<v8::Value> value) diff --git a/Source/WebCore/bindings/v8/V8DOMMap.h b/Source/WebCore/bindings/v8/V8DOMMap.h index 2b70c582b..4de35585d 100644 --- a/Source/WebCore/bindings/v8/V8DOMMap.h +++ b/Source/WebCore/bindings/v8/V8DOMMap.h @@ -136,8 +136,8 @@ namespace WebCore { virtual void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const OVERRIDE { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::Binding); - memoryObjectInfo->reportHashMap(m_map); + MemoryClassInfo<WeakReferenceMap<KeyType, ValueType> > info(memoryObjectInfo, this, MemoryInstrumentation::Binding); + info.addHashMap(m_map); } protected: diff --git a/Source/WebCore/bindings/v8/V8GCController.cpp b/Source/WebCore/bindings/v8/V8GCController.cpp index 5943dc3b5..65182a7ec 100644 --- a/Source/WebCore/bindings/v8/V8GCController.cpp +++ b/Source/WebCore/bindings/v8/V8GCController.cpp @@ -509,7 +509,7 @@ void V8GCController::gcEpilogue() void V8GCController::checkMemoryUsage() { -#if PLATFORM(CHROMIUM) || PLATFORM(QT) +#if PLATFORM(CHROMIUM) const int lowMemoryUsageMB = MemoryUsageSupport::lowMemoryUsageMB(); const int highMemoryUsageMB = MemoryUsageSupport::highMemoryUsageMB(); const int highUsageDeltaMB = MemoryUsageSupport::highUsageDeltaMB(); diff --git a/Source/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp b/Source/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp index 62ee6bd11..659fd8b28 100644 --- a/Source/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp +++ b/Source/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp @@ -135,7 +135,6 @@ v8::Handle<v8::Value> V8InspectorFrontendHost::showContextMenuCallback(const v8: return v8::Undefined(); } -#if !PLATFORM(QT) static v8::Handle<v8::Value> histogramEnumeration(const char* name, const v8::Arguments& args, int boundaryValue) { if (args.Length() < 1 || !args[0]->IsInt32()) @@ -147,33 +146,20 @@ static v8::Handle<v8::Value> histogramEnumeration(const char* name, const v8::Ar return v8::Undefined(); } -#endif v8::Handle<v8::Value> V8InspectorFrontendHost::recordActionTakenCallback(const v8::Arguments& args) { -#if !PLATFORM(QT) return histogramEnumeration("DevTools.ActionTaken", args, 100); -#else - return v8::Undefined(); -#endif } v8::Handle<v8::Value> V8InspectorFrontendHost::recordPanelShownCallback(const v8::Arguments& args) { -#if !PLATFORM(QT) return histogramEnumeration("DevTools.PanelShown", args, 20); -#else - return v8::Undefined(); -#endif } v8::Handle<v8::Value> V8InspectorFrontendHost::recordSettingChangedCallback(const v8::Arguments& args) { -#if !PLATFORM(QT) return histogramEnumeration("DevTools.SettingChanged", args, 100); -#else - return v8::Undefined(); -#endif } } // namespace WebCore diff --git a/Source/WebCore/bridge/qt/qt_pixmapruntime.cpp b/Source/WebCore/bridge/qt/qt_pixmapruntime.cpp index b0e5f62f9..a2daada83 100644 --- a/Source/WebCore/bridge/qt/qt_pixmapruntime.cpp +++ b/Source/WebCore/bridge/qt/qt_pixmapruntime.cpp @@ -146,8 +146,8 @@ public: if (!objectArg->inherits(&JSHTMLImageElement::s_info)) return jsUndefined(); - // we now know that we have a valid <img> element as the argument, we can attach the pixmap to it. - PassRefPtr<StillImage> stillImage = WebCore::StillImage::create(instance->toPixmap()); + // we now know that we have a valid <img> element as the argument, we can attach the image to it. + RefPtr<StillImage> stillImage = WebCore::StillImage::create(instance->toImage()); HTMLImageElement* imageElement = static_cast<HTMLImageElement*>(static_cast<JSHTMLImageElement*>(objectArg)->impl()); imageElement->setCachedImage(new CachedImage(stillImage.get())); JSDOMGlobalObject* global = static_cast<JSDOMGlobalObject*>(instance->rootObject()->globalObject()); @@ -383,13 +383,13 @@ QVariant QtPixmapInstance::variantFromObject(JSObject* object, QMetaType::Type h if (!image) goto returnEmptyVariant; - QPixmap* pixmap = image->nativeImageForCurrentFrame(); - if (!pixmap) + QImage* nativeImage = image->nativeImageForCurrentFrame(); + if (!nativeImage) goto returnEmptyVariant; return (hint == static_cast<QMetaType::Type>(qMetaTypeId<QPixmap>())) - ? QVariant::fromValue<QPixmap>(*pixmap) - : QVariant::fromValue<QImage>(pixmap->toImage()); + ? QVariant::fromValue<QPixmap>(QPixmap::fromImage(*nativeImage)) + : QVariant::fromValue<QImage>(*nativeImage); } if (object->inherits(&QtPixmapRuntimeObject::s_info)) { diff --git a/Source/WebCore/config.h b/Source/WebCore/config.h index 3784eed1a..94af14716 100644 --- a/Source/WebCore/config.h +++ b/Source/WebCore/config.h @@ -36,11 +36,7 @@ #include <wtf/ExportMacros.h> #include "PlatformExportMacros.h" -#if PLATFORM(QT) && USE(V8) -#include <JavaScriptCore/runtime/JSExportMacros.h> -#else #include <runtime/JSExportMacros.h> -#endif #ifdef __APPLE__ #define HAVE_FUNC_USLEEP 1 @@ -158,11 +154,6 @@ typedef float CGFloat; #define WTF_USE_CA 1 #endif -#if PLATFORM(QT) && USE(V8) && defined(Q_WS_X11) -/* protect ourselves from evil X11 defines */ -#include <bridge/npruntime_internal.h> -#endif - // FIXME: Move this to JavaScriptCore/wtf/Platform.h, which is where we define WTF_USE_AVFOUNDATION on the Mac. // https://bugs.webkit.org/show_bug.cgi?id=67334 #if PLATFORM(WIN) && HAVE(AVCF) diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp index 208d47019..26615c5f0 100644 --- a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp +++ b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp @@ -57,6 +57,12 @@ #include "WebKitCSSTransformValue.h" #include "WebKitFontFamilyNames.h" +#if ENABLE(CSS_EXCLUSIONS) +#include "CSSWrapShapes.h" +#include "WrapShapeFunctions.h" +#include "WrapShapes.h" +#endif + #if ENABLE(CSS_SHADERS) #include "CustomFilterNumberParameter.h" #include "CustomFilterOperation.h" @@ -124,6 +130,9 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyFontVariant, CSSPropertyFontWeight, CSSPropertyHeight, +#if ENABLE(CSS_IMAGE_ORIENTATION) + CSSPropertyImageOrientation, +#endif CSSPropertyImageRendering, #if ENABLE(CSS_IMAGE_RESOLUTION) CSSPropertyImageResolution, @@ -1769,6 +1778,10 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert if (style->borderFit() == BorderFitBorder) return cssValuePool().createIdentifierValue(CSSValueBorder); return cssValuePool().createIdentifierValue(CSSValueLines); +#if ENABLE(CSS_IMAGE_ORIENTATION) + case CSSPropertyImageOrientation: + return cssValuePool().createValue(style->imageOrientation()); +#endif case CSSPropertyImageRendering: return CSSPrimitiveValue::create(style->imageRendering()); #if ENABLE(CSS_IMAGE_RESOLUTION) @@ -2365,11 +2378,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert case CSSPropertyWebkitShapeInside: if (!style->wrapShapeInside()) return cssValuePool().createIdentifierValue(CSSValueAuto); - return cssValuePool().createValue(style->wrapShapeInside()); + return valueForWrapShape(style->wrapShapeInside()); case CSSPropertyWebkitShapeOutside: if (!style->wrapShapeOutside()) return cssValuePool().createIdentifierValue(CSSValueAuto); - return cssValuePool().createValue(style->wrapShapeOutside()); + return valueForWrapShape(style->wrapShapeOutside()); case CSSPropertyWebkitWrapThrough: return cssValuePool().createValue(style->wrapThrough()); #endif diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp index d68288343..bf7d52217 100644 --- a/Source/WebCore/css/CSSParser.cpp +++ b/Source/WebCore/css/CSSParser.cpp @@ -1682,6 +1682,7 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) m_valueList->next(); return true; } + ASSERT(propId != CSSPropertyVariable); #endif if (isKeywordPropertyID(propId)) { @@ -2686,6 +2687,11 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) case CSSPropertyWebkitWrap: return RuntimeEnabledFeatures::cssExclusionsEnabled() && parseShorthand(propId, webkitWrapShorthand(), important); #endif +#if ENABLE(CSS_IMAGE_ORIENTATION) + case CSSPropertyImageOrientation: + validPrimitive = !id && validUnit(value, FAngle); + break; +#endif #if ENABLE(CSS_IMAGE_RESOLUTION) case CSSPropertyImageResolution: parsedValue = parseImageResolution(m_valueList.get()); @@ -2694,11 +2700,6 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) m_valueList->next(); break; #endif -#if ENABLE(CSS_VARIABLES) - case CSSPropertyVariable: - // FIXME: This should have an actual implementation. - return false; -#endif case CSSPropertyBorderBottomStyle: case CSSPropertyBorderCollapse: case CSSPropertyBorderLeftStyle: @@ -2735,6 +2736,9 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) case CSSPropertyTextTransform: case CSSPropertyTextUnderlineMode: case CSSPropertyTextUnderlineStyle: +#if ENABLE(CSS_VARIABLES) + case CSSPropertyVariable: +#endif case CSSPropertyVisibility: case CSSPropertyWebkitAppearance: case CSSPropertyWebkitBackfaceVisibility: @@ -4467,10 +4471,10 @@ PassRefPtr<CSSWrapShape> CSSParser::parseExclusionShapeRectangle(CSSParserValueL ASSERT(argumentNumber < 6); switch (argumentNumber) { case 0: - shape->setLeft(length); + shape->setX(length); break; case 1: - shape->setTop(length); + shape->setY(length); break; case 2: shape->setWidth(length); @@ -4504,7 +4508,7 @@ PassRefPtr<CSSWrapShape> CSSParser::parseExclusionShapeCircle(CSSParserValueList { ASSERT(args); - // circle(x, y, r) + // circle(centerX, centerY, radius) if (args->size() != 5) return 0; @@ -4520,10 +4524,10 @@ PassRefPtr<CSSWrapShape> CSSParser::parseExclusionShapeCircle(CSSParserValueList ASSERT(argumentNumber < 3); switch (argumentNumber) { case 0: - shape->setLeft(length); + shape->setCenterX(length); break; case 1: - shape->setTop(length); + shape->setCenterY(length); break; case 2: shape->setRadius(length); @@ -4548,7 +4552,7 @@ PassRefPtr<CSSWrapShape> CSSParser::parseExclusionShapeEllipse(CSSParserValueLis { ASSERT(args); - // ellipse(x, y, rx, ry) + // ellipse(centerX, centerY, radiusX, radiusY) if (args->size() != 7) return 0; @@ -4563,10 +4567,10 @@ PassRefPtr<CSSWrapShape> CSSParser::parseExclusionShapeEllipse(CSSParserValueLis ASSERT(argumentNumber < 4); switch (argumentNumber) { case 0: - shape->setLeft(length); + shape->setCenterX(length); break; case 1: - shape->setTop(length); + shape->setCenterY(length); break; case 2: shape->setRadiusX(length); diff --git a/Source/WebCore/css/CSSPrimitiveValue.cpp b/Source/WebCore/css/CSSPrimitiveValue.cpp index 5718180f1..d5e6eb654 100644 --- a/Source/WebCore/css/CSSPrimitiveValue.cpp +++ b/Source/WebCore/css/CSSPrimitiveValue.cpp @@ -1046,7 +1046,7 @@ String CSSPrimitiveValue::customCssText() const appendNumber(result, static_cast<unsigned char>(color.blue())); if (color.hasAlpha()) { append(result, commaSpace); - append(result, String::number(color.alpha() / 256.0f)); + append(result, String::number(color.alpha() / 255.0f)); } result.append(')'); diff --git a/Source/WebCore/css/CSSPrimitiveValueMappings.h b/Source/WebCore/css/CSSPrimitiveValueMappings.h index 4855ec381..a370112e0 100644 --- a/Source/WebCore/css/CSSPrimitiveValueMappings.h +++ b/Source/WebCore/css/CSSPrimitiveValueMappings.h @@ -37,6 +37,9 @@ #include "FontDescription.h" #include "FontSmoothingMode.h" #include "GraphicsTypes.h" +#if ENABLE(CSS_IMAGE_ORIENTATION) +#include "ImageOrientation.h" +#endif #include "Length.h" #include "LineClampValue.h" #include "Path.h" @@ -4108,6 +4111,55 @@ template<> inline CSSPrimitiveValue::operator EVectorEffect() const #endif // ENABLE(SVG) +#if ENABLE(CSS_IMAGE_ORIENTATION) + +template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ImageOrientationEnum e) + : CSSValue(PrimitiveClass) +{ + m_primitiveUnitType = CSS_DEG; + switch (e) { + case OriginTopLeft: + m_value.num = 0; + break; + case OriginRightTop: + m_value.num = 90; + break; + case OriginBottomRight: + m_value.num = 180; + break; + case OriginLeftBottom: + m_value.num = 270; + break; + case OriginTopRight: + case OriginLeftTop: + case OriginBottomLeft: + case OriginRightBottom: + ASSERT_NOT_REACHED(); + } +} + +template<> inline CSSPrimitiveValue::operator ImageOrientationEnum() const +{ + ASSERT(isAngle()); + double quarters = 4 * getDoubleValue(CSS_TURN); + int orientation = 3 & static_cast<int>(quarters < 0 ? floor(quarters) : ceil(quarters)); + switch (orientation) { + case 0: + return OriginTopLeft; + case 1: + return OriginRightTop; + case 2: + return OriginBottomRight; + case 3: + return OriginLeftBottom; + default: + ASSERT_NOT_REACHED(); + return OriginTopLeft; + } +} + +#endif // ENABLE(CSS_IMAGE_ORIENTATION) + } #endif diff --git a/Source/WebCore/css/CSSProperty.cpp b/Source/WebCore/css/CSSProperty.cpp index 76cc8ea1a..8c82dc65a 100644 --- a/Source/WebCore/css/CSSProperty.cpp +++ b/Source/WebCore/css/CSSProperty.cpp @@ -282,6 +282,9 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID) case CSSPropertyFontStyle: case CSSPropertyFontVariant: case CSSPropertyFontWeight: +#if ENABLE(CSS_IMAGE_ORIENTATION) + case CSSPropertyImageOrientation: +#endif case CSSPropertyImageRendering: #if ENABLE(CSS_IMAGE_RESOLUTION) case CSSPropertyImageResolution: diff --git a/Source/WebCore/css/CSSPropertyNames.in b/Source/WebCore/css/CSSPropertyNames.in index 8d44f9808..547907efb 100644 --- a/Source/WebCore/css/CSSPropertyNames.in +++ b/Source/WebCore/css/CSSPropertyNames.in @@ -103,6 +103,9 @@ empty-cells float font-stretch height +#if defined(ENABLE_CSS_IMAGE_ORIENTATION) && ENABLE_CSS_IMAGE_ORIENTATION +image-orientation +#endif image-rendering #if defined(ENABLE_CSS_IMAGE_RESOLUTION) && ENABLE_CSS_IMAGE_RESOLUTION image-resolution diff --git a/Source/WebCore/css/CSSWrapShapes.cpp b/Source/WebCore/css/CSSWrapShapes.cpp index 49eb3b88c..16ecc8021 100644 --- a/Source/WebCore/css/CSSWrapShapes.cpp +++ b/Source/WebCore/css/CSSWrapShapes.cpp @@ -46,10 +46,10 @@ String CSSWrapShapeRectangle::cssText() const result.reserveCapacity(32); result.append(rectangleParen); - result.append(m_left->cssText()); + result.append(m_x->cssText()); result.append(comma); - result.append(m_top->cssText()); + result.append(m_y->cssText()); result.append(comma); result.append(m_width->cssText()); @@ -81,10 +81,10 @@ String CSSWrapShapeCircle::cssText() const result.reserveCapacity(32); result.append(circleParen); - result.append(m_left->cssText()); + result.append(m_centerX->cssText()); result.append(comma); - result.append(m_top->cssText()); + result.append(m_centerY->cssText()); result.append(comma); result.append(m_radius->cssText()); @@ -102,10 +102,10 @@ String CSSWrapShapeEllipse::cssText() const result.reserveCapacity(32); result.append(ellipseParen); - result.append(m_left->cssText()); + result.append(m_centerX->cssText()); result.append(comma); - result.append(m_top->cssText()); + result.append(m_centerY->cssText()); result.append(comma); result.append(m_radiusX->cssText()); diff --git a/Source/WebCore/css/CSSWrapShapes.h b/Source/WebCore/css/CSSWrapShapes.h index c877a270f..347bb3410 100644 --- a/Source/WebCore/css/CSSWrapShapes.h +++ b/Source/WebCore/css/CSSWrapShapes.h @@ -47,7 +47,7 @@ public: CSS_WRAP_SHAPE_POLYGON = 4 }; - virtual Type type() = 0; + virtual Type type() const = 0; virtual String cssText() const = 0; public: @@ -61,28 +61,28 @@ class CSSWrapShapeRectangle : public CSSWrapShape { public: static PassRefPtr<CSSWrapShapeRectangle> create() { return adoptRef(new CSSWrapShapeRectangle); } - CSSPrimitiveValue* left() const { return m_left.get(); } - CSSPrimitiveValue* top() const { return m_top.get(); } + CSSPrimitiveValue* x() const { return m_x.get(); } + CSSPrimitiveValue* y() const { return m_y.get(); } CSSPrimitiveValue* width() const { return m_width.get(); } CSSPrimitiveValue* height() const { return m_height.get(); } CSSPrimitiveValue* radiusX() const { return m_radiusX.get(); } CSSPrimitiveValue* radiusY() const { return m_radiusY.get(); } - void setLeft(PassRefPtr<CSSPrimitiveValue> left) { m_left = left; } - void setTop(PassRefPtr<CSSPrimitiveValue> top) { m_top = top; } + void setX(PassRefPtr<CSSPrimitiveValue> x) { m_x = x; } + void setY(PassRefPtr<CSSPrimitiveValue> y) { m_y = y; } void setWidth(PassRefPtr<CSSPrimitiveValue> width) { m_width = width; } void setHeight(PassRefPtr<CSSPrimitiveValue> height) { m_height = height; } void setRadiusX(PassRefPtr<CSSPrimitiveValue> radiusX) { m_radiusX = radiusX; } void setRadiusY(PassRefPtr<CSSPrimitiveValue> radiusY) { m_radiusY = radiusY; } - virtual Type type() { return CSS_WRAP_SHAPE_RECTANGLE; } + virtual Type type() const { return CSS_WRAP_SHAPE_RECTANGLE; } virtual String cssText() const; private: CSSWrapShapeRectangle() { } - RefPtr<CSSPrimitiveValue> m_top; - RefPtr<CSSPrimitiveValue> m_left; + RefPtr<CSSPrimitiveValue> m_y; + RefPtr<CSSPrimitiveValue> m_x; RefPtr<CSSPrimitiveValue> m_width; RefPtr<CSSPrimitiveValue> m_height; RefPtr<CSSPrimitiveValue> m_radiusX; @@ -93,22 +93,22 @@ class CSSWrapShapeCircle : public CSSWrapShape { public: static PassRefPtr<CSSWrapShapeCircle> create() { return adoptRef(new CSSWrapShapeCircle); } - CSSPrimitiveValue* left() const { return m_left.get(); } - CSSPrimitiveValue* top() const { return m_top.get(); } + CSSPrimitiveValue* centerX() const { return m_centerX.get(); } + CSSPrimitiveValue* centerY() const { return m_centerY.get(); } CSSPrimitiveValue* radius() const { return m_radius.get(); } - void setLeft(PassRefPtr<CSSPrimitiveValue> left) { m_left = left; } - void setTop(PassRefPtr<CSSPrimitiveValue> top) { m_top = top; } + void setCenterX(PassRefPtr<CSSPrimitiveValue> centerX) { m_centerX = centerX; } + void setCenterY(PassRefPtr<CSSPrimitiveValue> centerY) { m_centerY = centerY; } void setRadius(PassRefPtr<CSSPrimitiveValue> radius) { m_radius = radius; } - virtual Type type() { return CSS_WRAP_SHAPE_CIRCLE; } + virtual Type type() const { return CSS_WRAP_SHAPE_CIRCLE; } virtual String cssText() const; private: CSSWrapShapeCircle() { } - RefPtr<CSSPrimitiveValue> m_top; - RefPtr<CSSPrimitiveValue> m_left; + RefPtr<CSSPrimitiveValue> m_centerY; + RefPtr<CSSPrimitiveValue> m_centerX; RefPtr<CSSPrimitiveValue> m_radius; }; @@ -116,24 +116,24 @@ class CSSWrapShapeEllipse : public CSSWrapShape { public: static PassRefPtr<CSSWrapShapeEllipse> create() { return adoptRef(new CSSWrapShapeEllipse); } - CSSPrimitiveValue* left() const { return m_left.get(); } - CSSPrimitiveValue* top() const { return m_top.get(); } + CSSPrimitiveValue* centerX() const { return m_centerX.get(); } + CSSPrimitiveValue* centerY() const { return m_centerY.get(); } CSSPrimitiveValue* radiusX() const { return m_radiusX.get(); } CSSPrimitiveValue* radiusY() const { return m_radiusY.get(); } - void setLeft(PassRefPtr<CSSPrimitiveValue> left) { m_left = left; } - void setTop(PassRefPtr<CSSPrimitiveValue> top) { m_top = top; } + void setCenterX(PassRefPtr<CSSPrimitiveValue> centerX) { m_centerX = centerX; } + void setCenterY(PassRefPtr<CSSPrimitiveValue> centerY) { m_centerY = centerY; } void setRadiusX(PassRefPtr<CSSPrimitiveValue> radiusX) { m_radiusX = radiusX; } void setRadiusY(PassRefPtr<CSSPrimitiveValue> radiusY) { m_radiusY = radiusY; } - virtual Type type() { return CSS_WRAP_SHAPE_ELLIPSE; } + virtual Type type() const { return CSS_WRAP_SHAPE_ELLIPSE; } virtual String cssText() const; private: CSSWrapShapeEllipse() { } - RefPtr<CSSPrimitiveValue> m_top; - RefPtr<CSSPrimitiveValue> m_left; + RefPtr<CSSPrimitiveValue> m_centerX; + RefPtr<CSSPrimitiveValue> m_centerY; RefPtr<CSSPrimitiveValue> m_radiusX; RefPtr<CSSPrimitiveValue> m_radiusY; }; @@ -148,13 +148,14 @@ public: m_values.append(y); } - PassRefPtr<CSSPrimitiveValue> getXAt(unsigned i) { return m_values.at(i * 2); } - PassRefPtr<CSSPrimitiveValue> getYAt(unsigned i) { return m_values.at(i * 2 + 1); } + PassRefPtr<CSSPrimitiveValue> getXAt(unsigned i) const { return m_values.at(i * 2); } + PassRefPtr<CSSPrimitiveValue> getYAt(unsigned i) const { return m_values.at(i * 2 + 1); } + const Vector<RefPtr<CSSPrimitiveValue> >& values() const { return m_values; } void setWindRule(WindRule w) { m_windRule = w; } WindRule windRule() const { return m_windRule; } - virtual Type type() { return CSS_WRAP_SHAPE_POLYGON; } + virtual Type type() const { return CSS_WRAP_SHAPE_POLYGON; } virtual String cssText() const; private: diff --git a/Source/WebCore/css/StyleBuilder.cpp b/Source/WebCore/css/StyleBuilder.cpp index 16f08d6d0..b6bf332a5 100644 --- a/Source/WebCore/css/StyleBuilder.cpp +++ b/Source/WebCore/css/StyleBuilder.cpp @@ -44,6 +44,12 @@ #include <wtf/StdLibExtras.h> #include <wtf/UnusedParam.h> +#if ENABLE(CSS_EXCLUSIONS) +#include "CSSWrapShapes.h" +#include "WrapShapeFunctions.h" +#include "WrapShapes.h" +#endif + using namespace std; namespace WebCore { @@ -762,6 +768,10 @@ public: if (size < 0) return; + // Overly large font sizes will cause crashes on some platforms (such as Windows). + // Cap font size here to make sure that doesn't happen. + size = min(1000000.0f, size); + styleResolver->setFontSize(fontDescription, size); styleResolver->setFontDescription(fontDescription); return; @@ -1726,23 +1736,25 @@ public: }; #if ENABLE(CSS_EXCLUSIONS) -template <CSSWrapShape* (RenderStyle::*getterFunction)() const, void (RenderStyle::*setterFunction)(PassRefPtr<CSSWrapShape>), CSSWrapShape* (*initialFunction)()> +template <WrapShape* (RenderStyle::*getterFunction)() const, void (RenderStyle::*setterFunction)(PassRefPtr<WrapShape>), WrapShape* (*initialFunction)()> class ApplyPropertyWrapShape { public: - static void setValue(RenderStyle* style, PassRefPtr<CSSWrapShape> value) { (style->*setterFunction)(value); } + static void setValue(RenderStyle* style, PassRefPtr<WrapShape> value) { (style->*setterFunction)(value); } static void applyValue(StyleResolver* styleResolver, CSSValue* value) { if (value->isPrimitiveValue()) { CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); if (primitiveValue->getIdent() == CSSValueAuto) setValue(styleResolver->style(), 0); - else if (primitiveValue->isShape()) - setValue(styleResolver->style(), primitiveValue->getShapeValue()); + else if (primitiveValue->isShape()) { + RefPtr<WrapShape> wrapShape = wrapShapeForValue(styleResolver, primitiveValue->getShapeValue()); + setValue(styleResolver->style(), wrapShape.release()); + } } } static PropertyHandler createHandler() { - PropertyHandler handler = ApplyPropertyDefaultBase<CSSWrapShape*, getterFunction, PassRefPtr<CSSWrapShape>, setterFunction, CSSWrapShape*, initialFunction>::createHandler(); + PropertyHandler handler = ApplyPropertyDefaultBase<WrapShape*, getterFunction, PassRefPtr<WrapShape>, setterFunction, WrapShape*, initialFunction>::createHandler(); return PropertyHandler(handler.inheritFunction(), handler.initialFunction(), &applyValue); } }; @@ -1872,6 +1884,9 @@ StyleBuilder::StyleBuilder() setPropertyHandler(CSSPropertyFontVariant, ApplyPropertyFont<FontSmallCaps, &FontDescription::smallCaps, &FontDescription::setSmallCaps, FontSmallCapsOff>::createHandler()); setPropertyHandler(CSSPropertyFontWeight, ApplyPropertyFontWeight::createHandler()); setPropertyHandler(CSSPropertyHeight, ApplyPropertyLength<&RenderStyle::height, &RenderStyle::setHeight, &RenderStyle::initialSize, AutoEnabled, LegacyIntrinsicEnabled, IntrinsicDisabled, NoneDisabled, UndefinedDisabled>::createHandler()); +#if ENABLE(CSS_IMAGE_ORIENTATION) + setPropertyHandler(CSSPropertyImageOrientation, ApplyPropertyDefault<ImageOrientationEnum, &RenderStyle::imageOrientation, ImageOrientationEnum, &RenderStyle::setImageOrientation, ImageOrientationEnum, &RenderStyle::initialImageOrientation>::createHandler()); +#endif setPropertyHandler(CSSPropertyImageRendering, ApplyPropertyDefault<EImageRendering, &RenderStyle::imageRendering, EImageRendering, &RenderStyle::setImageRendering, EImageRendering, &RenderStyle::initialImageRendering>::createHandler()); #if ENABLE(CSS_IMAGE_RESOLUTION) setPropertyHandler(CSSPropertyImageResolution, ApplyPropertyImageResolution::createHandler()); diff --git a/Source/WebCore/css/StylePropertySet.h b/Source/WebCore/css/StylePropertySet.h index 559cfe661..7098f7232 100644 --- a/Source/WebCore/css/StylePropertySet.h +++ b/Source/WebCore/css/StylePropertySet.h @@ -118,9 +118,9 @@ public: void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::CSS); + MemoryClassInfo<StylePropertySet> info(memoryObjectInfo, this, MemoryInstrumentation::CSS); if (m_isMutable) - memoryObjectInfo->reportPointer(m_mutablePropertyVector, MemoryInstrumentation::CSS); + info.addMember(m_mutablePropertyVector); } private: diff --git a/Source/WebCore/css/StyleResolver.cpp b/Source/WebCore/css/StyleResolver.cpp index 8bc5efee8..b4cbd8a21 100644 --- a/Source/WebCore/css/StyleResolver.cpp +++ b/Source/WebCore/css/StyleResolver.cpp @@ -4105,11 +4105,6 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value) m_style->setGridItemRow(row); return; } -#if ENABLE(CSS_VARIABLES) - case CSSPropertyVariable: - // FIXME: This should have an actual implementation. - return; -#endif // These properties are implemented in the StyleBuilder lookup table. case CSSPropertyBackgroundAttachment: case CSSPropertyBackgroundClip: @@ -4174,6 +4169,9 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value) case CSSPropertyFontVariant: case CSSPropertyFontWeight: case CSSPropertyHeight: +#if ENABLE(CSS_IMAGE_ORIENTATION) + case CSSPropertyImageOrientation: +#endif case CSSPropertyImageRendering: #if ENABLE(CSS_IMAGE_RESOLUTION) case CSSPropertyImageResolution: @@ -4226,6 +4224,9 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value) case CSSPropertyTextTransform: case CSSPropertyTop: case CSSPropertyUnicodeBidi: +#if ENABLE(CSS_VARIABLES) + case CSSPropertyVariable: +#endif case CSSPropertyVerticalAlign: case CSSPropertyVisibility: case CSSPropertyWebkitAnimationDelay: @@ -4559,9 +4560,7 @@ float StyleResolver::getComputedSizeFromSpecifiedSize(Document* document, float if (useSmartMinimumForFontSize && zoomedSize < minLogicalSize && (specifiedSize >= minLogicalSize || !isAbsoluteSize)) zoomedSize = minLogicalSize; - // Also clamp to a reasonable maximum to prevent insane font sizes from causing crashes on various - // platforms (I'm looking at you, Windows.) - return min(1000000.0f, zoomedSize); + return zoomedSize; } const int fontSizeTableMax = 16; diff --git a/Source/WebCore/css/WrapShapeFunctions.cpp b/Source/WebCore/css/WrapShapeFunctions.cpp new file mode 100644 index 000000000..6ca634169 --- /dev/null +++ b/Source/WebCore/css/WrapShapeFunctions.cpp @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" +#include "WrapShapeFunctions.h" + +#include "CSSPrimitiveValueMappings.h" +#include "CSSValuePool.h" +#include "CSSWrapShapes.h" +#include "StyleResolver.h" +#include "WrapShapes.h" + +namespace WebCore { + +PassRefPtr<CSSValue> valueForWrapShape(const WrapShape* wrapShape) +{ + RefPtr<CSSWrapShape> wrapShapeValue; + switch (wrapShape->type()) { + case WrapShape::WRAP_SHAPE_RECTANGLE: { + const WrapShapeRectangle* rectangle = static_cast<const WrapShapeRectangle*>(wrapShape); + RefPtr<CSSWrapShapeRectangle> rectangleValue = CSSWrapShapeRectangle::create(); + + rectangleValue->setX(cssValuePool().createValue(rectangle->x())); + rectangleValue->setY(cssValuePool().createValue(rectangle->y())); + rectangleValue->setWidth(cssValuePool().createValue(rectangle->width())); + rectangleValue->setHeight(cssValuePool().createValue(rectangle->height())); + if (!rectangle->cornerRadiusX().isUndefined()) { + rectangleValue->setRadiusX(cssValuePool().createValue(rectangle->cornerRadiusX())); + if (!rectangle->cornerRadiusY().isUndefined()) + rectangleValue->setRadiusY(cssValuePool().createValue(rectangle->cornerRadiusY())); + } + + wrapShapeValue = rectangleValue.release(); + break; + } + case WrapShape::WRAP_SHAPE_CIRCLE: { + const WrapShapeCircle* circle = static_cast<const WrapShapeCircle*>(wrapShape); + RefPtr<CSSWrapShapeCircle> circleValue = CSSWrapShapeCircle::create(); + + circleValue->setCenterX(cssValuePool().createValue(circle->centerX())); + circleValue->setCenterY(cssValuePool().createValue(circle->centerY())); + circleValue->setRadius(cssValuePool().createValue(circle->radius())); + + wrapShapeValue = circleValue.release(); + break; + } + case WrapShape::WRAP_SHAPE_ELLIPSE: { + const WrapShapeEllipse* ellipse = static_cast<const WrapShapeEllipse*>(wrapShape); + RefPtr<CSSWrapShapeEllipse> ellipseValue = CSSWrapShapeEllipse::create(); + + ellipseValue->setCenterX(cssValuePool().createValue(ellipse->centerX())); + ellipseValue->setCenterY(cssValuePool().createValue(ellipse->centerY())); + ellipseValue->setRadiusX(cssValuePool().createValue(ellipse->radiusX())); + ellipseValue->setRadiusY(cssValuePool().createValue(ellipse->radiusY())); + + wrapShapeValue = ellipseValue.release(); + break; + } + case WrapShape::WRAP_SHAPE_POLYGON: { + const WrapShapePolygon* polygon = static_cast<const WrapShapePolygon*>(wrapShape); + RefPtr<CSSWrapShapePolygon> polygonValue = CSSWrapShapePolygon::create(); + + polygonValue->setWindRule(polygon->windRule()); + const Vector<Length>& values = polygon->values(); + for (unsigned i = 0; i < values.size(); i += 2) + polygonValue->appendPoint(cssValuePool().createValue(values.at(i)), cssValuePool().createValue(values.at(i + 1))); + + wrapShapeValue = polygonValue.release(); + break; + } + default: + break; + } + return cssValuePool().createValue<PassRefPtr<CSSWrapShape> >(wrapShapeValue.release()); +} + +static Length convertToLength(const StyleResolver* styleResolver, CSSPrimitiveValue* value) +{ + return value->convertToLength<FixedIntegerConversion | FixedFloatConversion | PercentConversion | ViewportPercentageConversion>(styleResolver->style(), styleResolver->rootElementStyle(), styleResolver->style()->effectiveZoom()); +} + +PassRefPtr<WrapShape> wrapShapeForValue(const StyleResolver* styleResolver, const CSSWrapShape* wrapShapeValue) +{ + RefPtr<WrapShape> wrapShape; + + switch (wrapShapeValue->type()) { + case CSSWrapShape::CSS_WRAP_SHAPE_RECTANGLE: { + const CSSWrapShapeRectangle* rectValue = static_cast<const CSSWrapShapeRectangle *>(wrapShapeValue); + RefPtr<WrapShapeRectangle> rect = WrapShapeRectangle::create(); + + rect->setX(convertToLength(styleResolver, rectValue->x())); + rect->setY(convertToLength(styleResolver, rectValue->y())); + rect->setWidth(convertToLength(styleResolver, rectValue->width())); + rect->setHeight(convertToLength(styleResolver, rectValue->height())); + if (rectValue->radiusX()) { + rect->setCornerRadiusX(convertToLength(styleResolver, rectValue->radiusX())); + if (rectValue->radiusY()) + rect->setCornerRadiusY(convertToLength(styleResolver, rectValue->radiusY())); + } + wrapShape = rect.release(); + break; + } + case CSSWrapShape::CSS_WRAP_SHAPE_CIRCLE: { + const CSSWrapShapeCircle* circleValue = static_cast<const CSSWrapShapeCircle *>(wrapShapeValue); + RefPtr<WrapShapeCircle> circle = WrapShapeCircle::create(); + + circle->setCenterX(convertToLength(styleResolver, circleValue->centerX())); + circle->setCenterY(convertToLength(styleResolver, circleValue->centerY())); + circle->setRadius(convertToLength(styleResolver, circleValue->radius())); + + wrapShape = circle.release(); + break; + } + case CSSWrapShape::CSS_WRAP_SHAPE_ELLIPSE: { + const CSSWrapShapeEllipse* ellipseValue = static_cast<const CSSWrapShapeEllipse *>(wrapShapeValue); + RefPtr<WrapShapeEllipse> ellipse = WrapShapeEllipse::create(); + + ellipse->setCenterX(convertToLength(styleResolver, ellipseValue->centerX())); + ellipse->setCenterY(convertToLength(styleResolver, ellipseValue->centerY())); + ellipse->setRadiusX(convertToLength(styleResolver, ellipseValue->radiusX())); + ellipse->setRadiusY(convertToLength(styleResolver, ellipseValue->radiusY())); + + wrapShape = ellipse.release(); + break; + } + case CSSWrapShape::CSS_WRAP_SHAPE_POLYGON: { + const CSSWrapShapePolygon* polygonValue = static_cast<const CSSWrapShapePolygon *>(wrapShapeValue); + RefPtr<WrapShapePolygon> polygon = WrapShapePolygon::create(); + + polygon->setWindRule(polygonValue->windRule()); + const Vector<RefPtr<CSSPrimitiveValue> >& values = polygonValue->values(); + for (unsigned i = 0; i < values.size(); i += 2) + polygon->appendPoint(convertToLength(styleResolver, values.at(i).get()), convertToLength(styleResolver, values.at(i + 1).get())); + + wrapShape = polygon.release(); + break; + } + default: + break; + } + return wrapShape.release(); +} +} diff --git a/Source/WebCore/css/WrapShapeFunctions.h b/Source/WebCore/css/WrapShapeFunctions.h new file mode 100644 index 000000000..d3b953c61 --- /dev/null +++ b/Source/WebCore/css/WrapShapeFunctions.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef WrapShapeFunctions_h +#define WrapShapeFunctions_h + +#include <wtf/PassRefPtr.h> + +namespace WebCore { + +class CSSValue; +class CSSWrapShape; +class StyleResolver; +class WrapShape; + +PassRefPtr<CSSValue> valueForWrapShape(const WrapShape*); +PassRefPtr<WrapShape> wrapShapeForValue(const StyleResolver*, const CSSWrapShape*); + +} +#endif diff --git a/Source/WebCore/css/html.css b/Source/WebCore/css/html.css index 1769d49f1..5aab06fc7 100644 --- a/Source/WebCore/css/html.css +++ b/Source/WebCore/css/html.css @@ -851,6 +851,10 @@ progress::-webkit-progress-value { /* inline elements */ +img { + display: inline-block; +} + u, ins { text-decoration: underline } diff --git a/Source/WebCore/dom/CharacterData.cpp b/Source/WebCore/dom/CharacterData.cpp index 225a1399d..af1d8fed4 100644 --- a/Source/WebCore/dom/CharacterData.cpp +++ b/Source/WebCore/dom/CharacterData.cpp @@ -94,9 +94,9 @@ unsigned CharacterData::parserAppendData(const UChar* data, unsigned dataLength, void CharacterData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::DOM); - Node::reportMemoryUsage(memoryObjectInfo); - memoryObjectInfo->reportString(m_data); + MemoryClassInfo<CharacterData> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + info.visitBaseClass<Node>(this); + info.addString(m_data); } void CharacterData::appendData(const String& data, ExceptionCode&) diff --git a/Source/WebCore/dom/ContainerNode.h b/Source/WebCore/dom/ContainerNode.h index 5f55c7beb..9abaf2373 100644 --- a/Source/WebCore/dom/ContainerNode.h +++ b/Source/WebCore/dom/ContainerNode.h @@ -101,10 +101,10 @@ public: virtual void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::DOM); - Node::reportMemoryUsage(memoryObjectInfo); - memoryObjectInfo->reportInstrumentedPointer(m_firstChild); - memoryObjectInfo->reportInstrumentedPointer(m_lastChild); + MemoryClassInfo<ContainerNode> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + info.visitBaseClass<Node>(this); + info.addInstrumentedMember(m_firstChild); + info.addInstrumentedMember(m_lastChild); } protected: diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp index 64167fcec..fc8e1b537 100644 --- a/Source/WebCore/dom/Document.cpp +++ b/Source/WebCore/dom/Document.cpp @@ -3904,11 +3904,11 @@ bool Document::shouldInvalidateNodeListCaches(const QualifiedName* attrName) con return false; } -void Document::clearNodeListCaches() +void Document::invalidateNodeListCaches(const QualifiedName* attrName) { HashSet<DynamicNodeListCacheBase*>::iterator end = m_listsInvalidatedAtDocument.end(); for (HashSet<DynamicNodeListCacheBase*>::iterator it = m_listsInvalidatedAtDocument.begin(); it != end; ++it) - (*it)->invalidateCache(); + (*it)->invalidateCache(attrName); } void Document::attachNodeIterator(NodeIterator* ni) @@ -4894,8 +4894,31 @@ PassRefPtr<XPathResult> Document::evaluate(const String& expression, return m_xpathEvaluator->evaluate(expression, contextNode, resolver, type, result, ec); } -const Vector<IconURL>& Document::iconURLs() const +const Vector<IconURL>& Document::iconURLs() { + m_iconURLs.clear(); + + if (!head() || !(head()->children())) + return m_iconURLs; + + // Include any icons where type = link, rel = "shortcut icon". + RefPtr<HTMLCollection> children = head()->children(); + unsigned int length = children->length(); + for (unsigned int i = 0; i < length; ++i) { + Node* child = children->item(i); + if (!child->hasTagName(linkTag)) + continue; + HTMLLinkElement* linkElement = static_cast<HTMLLinkElement*>(child); + if (linkElement->iconType() != Favicon) + continue; + if (linkElement->href().isEmpty()) + continue; + + // Put it at the front to ensure that icons seen later take precedence as required by the spec. + IconURL newURL(linkElement->href(), linkElement->iconSizes(), linkElement->type(), linkElement->iconType()); + m_iconURLs.prepend(newURL); + } + return m_iconURLs; } @@ -4906,7 +4929,6 @@ void Document::addIconURL(const String& url, const String& mimeType, const Strin // FIXME - <rdar://problem/4727645> - At some point in the future, we might actually honor the "mimeType" IconURL newURL(KURL(ParsedURLString, url), sizes, mimeType, iconType); - m_iconURLs.append(newURL); if (Frame* f = frame()) { IconURL iconURL = f->loader()->icon()->iconURL(iconType); @@ -4919,7 +4941,7 @@ void Document::setUseSecureKeyboardEntryWhenActive(bool usesSecureKeyboard) { if (m_useSecureKeyboardEntryWhenActive == usesSecureKeyboard) return; - + m_useSecureKeyboardEntryWhenActive = usesSecureKeyboard; m_frame->selection()->updateSecureKeyboardEntryIfActive(); } @@ -5374,7 +5396,7 @@ void Document::requestFullScreenForElement(Element* element, unsigned short flag // The context object's node document, or an ancestor browsing context's document does not have // the fullscreen enabled flag set. - if (checkType == EnforceIFrameAllowFulScreenRequirement && !fullScreenIsAllowedForElement(element)) + if (checkType == EnforceIFrameAllowFullScreenRequirement && !fullScreenIsAllowedForElement(element)) break; // The context object's node document fullscreen element stack is not empty and its top element @@ -6062,38 +6084,38 @@ void Document::setContextFeatures(PassRefPtr<ContextFeatures> features) void Document::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::DOM); - ContainerNode::reportMemoryUsage(memoryObjectInfo); - memoryObjectInfo->reportVector(m_customFonts); - memoryObjectInfo->reportString(m_documentURI); - memoryObjectInfo->reportString(m_baseTarget); + MemoryClassInfo<Document> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + info.visitBaseClass<ContainerNode>(this); + info.addVector(m_customFonts); + info.addString(m_documentURI); + info.addString(m_baseTarget); if (m_pageGroupUserSheets) - memoryObjectInfo->reportVector(*m_pageGroupUserSheets.get()); + info.addVector(*m_pageGroupUserSheets.get()); if (m_userSheets) - memoryObjectInfo->reportVector(*m_userSheets.get()); - memoryObjectInfo->reportHashSet(m_nodeIterators); - memoryObjectInfo->reportHashSet(m_ranges); - memoryObjectInfo->reportListHashSet(m_styleSheetCandidateNodes); - memoryObjectInfo->reportString(m_preferredStylesheetSet); - memoryObjectInfo->reportString(m_selectedStylesheetSet); - memoryObjectInfo->reportString(m_title.string()); - memoryObjectInfo->reportString(m_rawTitle.string()); - memoryObjectInfo->reportString(m_xmlEncoding); - memoryObjectInfo->reportString(m_xmlVersion); - memoryObjectInfo->reportString(m_contentLanguage); - memoryObjectInfo->reportHashMap(m_documentNamedItemCollections); - memoryObjectInfo->reportHashMap(m_windowNamedItemCollections); + info.addVector(*m_userSheets.get()); + info.addHashSet(m_nodeIterators); + info.addHashSet(m_ranges); + info.addListHashSet(m_styleSheetCandidateNodes); + info.addString(m_preferredStylesheetSet); + info.addString(m_selectedStylesheetSet); + info.addString(m_title.string()); + info.addString(m_rawTitle.string()); + info.addString(m_xmlEncoding); + info.addString(m_xmlVersion); + info.addString(m_contentLanguage); + info.addHashMap(m_documentNamedItemCollections); + info.addHashMap(m_windowNamedItemCollections); #if ENABLE(DASHBOARD_SUPPORT) - memoryObjectInfo->reportVector(m_dashboardRegions); + info.addVector(m_dashboardRegions); #endif - memoryObjectInfo->reportHashMap(m_cssCanvasElements); - memoryObjectInfo->reportVector(m_iconURLs); - memoryObjectInfo->reportHashSet(m_documentSuspensionCallbackElements); - memoryObjectInfo->reportHashSet(m_mediaVolumeCallbackElements); - memoryObjectInfo->reportHashSet(m_privateBrowsingStateChangedElements); - memoryObjectInfo->reportHashMap(m_elementsByAccessKey); - memoryObjectInfo->reportHashSet(m_mediaCanStartListeners); - memoryObjectInfo->reportVector(m_pendingTasks); + info.addHashMap(m_cssCanvasElements); + info.addVector(m_iconURLs); + info.addHashSet(m_documentSuspensionCallbackElements); + info.addHashSet(m_mediaVolumeCallbackElements); + info.addHashSet(m_privateBrowsingStateChangedElements); + info.addHashMap(m_elementsByAccessKey); + info.addHashSet(m_mediaCanStartListeners); + info.addVector(m_pendingTasks); } #if ENABLE(UNDO_MANAGER) diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h index 2f4db13ce..b63618492 100644 --- a/Source/WebCore/dom/Document.h +++ b/Source/WebCore/dom/Document.h @@ -738,7 +738,7 @@ public: void registerNodeListCache(DynamicNodeListCacheBase*); void unregisterNodeListCache(DynamicNodeListCacheBase*); bool shouldInvalidateNodeListCaches(const QualifiedName* attrName = 0) const; - void clearNodeListCaches(); + void invalidateNodeListCaches(const QualifiedName* attrName); void attachNodeIterator(NodeIterator*); void detachNodeIterator(NodeIterator*); @@ -952,7 +952,7 @@ public: void setHasNodesWithPlaceholderStyle() { m_hasNodesWithPlaceholderStyle = true; } - const Vector<IconURL>& iconURLs() const; + const Vector<IconURL>& iconURLs(); void addIconURL(const String& url, const String& mimeType, const String& size, IconType); void setUseSecureKeyboardEntryWhenActive(bool); @@ -1061,8 +1061,8 @@ public: Element* webkitCurrentFullScreenElement() const { return m_fullScreenElement.get(); } enum FullScreenCheckType { - EnforceIFrameAllowFulScreenRequirement, - ExemptIFrameAllowFulScreenRequirement, + EnforceIFrameAllowFullScreenRequirement, + ExemptIFrameAllowFullScreenRequirement, }; void requestFullScreenForElement(Element*, unsigned short flags, FullScreenCheckType); diff --git a/Source/WebCore/dom/DynamicNodeList.h b/Source/WebCore/dom/DynamicNodeList.h index a3c12c2d9..c1c05f4c5 100644 --- a/Source/WebCore/dom/DynamicNodeList.h +++ b/Source/WebCore/dom/DynamicNodeList.h @@ -68,6 +68,11 @@ public: ALWAYS_INLINE NodeListInvalidationType invalidationType() const { return static_cast<NodeListInvalidationType>(m_invalidationType); } ALWAYS_INLINE CollectionType type() const { return static_cast<CollectionType>(m_collectionType); } + ALWAYS_INLINE void invalidateCache(const QualifiedName* attrName) const + { + if (!attrName || shouldInvalidateTypeOnAttributeChange(invalidationType(), *attrName)) + invalidateCache(); + } void invalidateCache() const; static bool shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType, const QualifiedName&); @@ -124,7 +129,8 @@ ALWAYS_INLINE bool DynamicNodeListCacheBase::shouldInvalidateTypeOnAttributeChan case InvalidateOnForAttrChange: return attrName == HTMLNames::forAttr; case InvalidateForFormControls: - return attrName == HTMLNames::nameAttr || attrName == HTMLNames::idAttr || attrName == HTMLNames::forAttr || attrName == HTMLNames::typeAttr; + return attrName == HTMLNames::nameAttr || attrName == HTMLNames::idAttr || attrName == HTMLNames::forAttr + || attrName == HTMLNames::formAttr || attrName == HTMLNames::typeAttr; case InvalidateOnHRefAttrChange: return attrName == HTMLNames::hrefAttr; case InvalidateOnItemAttrChange: diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp index eb1733b5d..42b468f98 100644 --- a/Source/WebCore/dom/Element.cpp +++ b/Source/WebCore/dom/Element.cpp @@ -1858,12 +1858,12 @@ bool Element::childShouldCreateRenderer(const NodeRenderingContext& childContext #if ENABLE(FULLSCREEN_API) void Element::webkitRequestFullscreen() { - document()->requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, Document::EnforceIFrameAllowFulScreenRequirement); + document()->requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, Document::EnforceIFrameAllowFullScreenRequirement); } void Element::webkitRequestFullScreen(unsigned short flags) { - document()->requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), Document::EnforceIFrameAllowFulScreenRequirement); + document()->requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), Document::EnforceIFrameAllowFullScreenRequirement); } bool Element::containsFullScreenElement() const diff --git a/Source/WebCore/dom/Element.h b/Source/WebCore/dom/Element.h index 0c338d6cb..80a1b3cab 100644 --- a/Source/WebCore/dom/Element.h +++ b/Source/WebCore/dom/Element.h @@ -429,10 +429,10 @@ public: virtual void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::DOM); - ContainerNode::reportMemoryUsage(memoryObjectInfo); - memoryObjectInfo->reportInstrumentedObject(m_tagName); - memoryObjectInfo->reportInstrumentedPointer(m_attributeData.get()); + MemoryClassInfo<Element> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + info.visitBaseClass<ContainerNode>(this); + info.addInstrumentedMember(m_tagName); + info.addInstrumentedMember(m_attributeData.get()); } protected: diff --git a/Source/WebCore/dom/ElementAttributeData.h b/Source/WebCore/dom/ElementAttributeData.h index a13d4d258..57cf368e1 100644 --- a/Source/WebCore/dom/ElementAttributeData.h +++ b/Source/WebCore/dom/ElementAttributeData.h @@ -102,12 +102,12 @@ public: void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::DOM); - memoryObjectInfo->reportInstrumentedPointer(m_inlineStyleDecl.get()); - memoryObjectInfo->reportInstrumentedPointer(m_attributeStyle.get()); - memoryObjectInfo->reportObject(m_classNames); - memoryObjectInfo->reportObject(m_idForStyleResolution); - memoryObjectInfo->reportObject(m_attributes); + MemoryClassInfo<ElementAttributeData> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + info.addInstrumentedMember(m_inlineStyleDecl.get()); + info.addInstrumentedMember(m_attributeStyle.get()); + info.addMember(m_classNames); + info.addString(m_idForStyleResolution); + info.addVector(m_attributes); } private: diff --git a/Source/WebCore/dom/ElementShadow.cpp b/Source/WebCore/dom/ElementShadow.cpp index 68a9b0189..6f5e33245 100644 --- a/Source/WebCore/dom/ElementShadow.cpp +++ b/Source/WebCore/dom/ElementShadow.cpp @@ -79,7 +79,7 @@ void ElementShadow::addShadowRoot(Element* shadowHost, PassRefPtr<ShadowRoot> sh shadowRoot->setHost(shadowHost); shadowRoot->setParentTreeScope(shadowHost->treeScope()); m_shadowRoots.push(shadowRoot.get()); - invalidateDistribution(shadowHost); + invalidateDistribution(shadowHost, InvalidateIfNeeded); ChildNodeInsertionNotifier(shadowHost).notify(shadowRoot.get()); if (shadowHost->attached() && !shadowRoot->attached()) @@ -108,7 +108,7 @@ void ElementShadow::removeAllShadowRoots() ChildNodeRemovalNotifier(shadowHost).notify(oldRoot.get()); } - invalidateDistribution(shadowHost); + invalidateDistribution(shadowHost, InvalidateIfNeeded); } void ElementShadow::attach() @@ -188,22 +188,26 @@ void ElementShadow::ensureDistribution() m_distributor.distribute(host()); } -void ElementShadow::invalidateDistribution() +void ElementShadow::invalidateDistribution(InvalidationType type) { - invalidateDistribution(host()); + invalidateDistribution(host(), type); } -void ElementShadow::invalidateDistribution(Element* host) +void ElementShadow::invalidateDistribution(Element* host, InvalidationType type) { - if (!m_distributor.needsInvalidation()) - return; - bool needsReattach = m_distributor.invalidate(host); + bool needsReattach = (type == InvalidateAndForceReattach); + bool needsInvalidation = m_distributor.needsInvalidation(); + + if (needsInvalidation) + needsReattach |= m_distributor.invalidate(host); + if (needsReattach && host->attached()) { host->detach(); host->lazyAttach(Node::DoNotSetAttached); } - m_distributor.finishInivalidation(); + if (needsInvalidation) + m_distributor.finishInivalidation(); } } // namespace diff --git a/Source/WebCore/dom/ElementShadow.h b/Source/WebCore/dom/ElementShadow.h index 6f650112a..3ab5c075d 100644 --- a/Source/WebCore/dom/ElementShadow.h +++ b/Source/WebCore/dom/ElementShadow.h @@ -62,8 +62,13 @@ public: bool needsStyleRecalc(); void recalcStyle(Node::StyleChange); + enum InvalidationType { + InvalidateIfNeeded, + InvalidateAndForceReattach + }; + + void invalidateDistribution(InvalidationType = InvalidateIfNeeded); void ensureDistribution(); - void invalidateDistribution(); InsertionPoint* insertionPointFor(const Node*) const; @@ -71,7 +76,7 @@ public: const ContentDistributor& distributor() const; private: - void invalidateDistribution(Element* host); + void invalidateDistribution(Element* host, InvalidationType); DoublyLinkedList<ShadowRoot> m_shadowRoots; ContentDistributor m_distributor; diff --git a/Source/WebCore/dom/EventDispatcher.cpp b/Source/WebCore/dom/EventDispatcher.cpp index 607fda9f5..62541d8b5 100644 --- a/Source/WebCore/dom/EventDispatcher.cpp +++ b/Source/WebCore/dom/EventDispatcher.cpp @@ -365,7 +365,14 @@ EventDispatchBehavior EventDispatcher::determineDispatchBehavior(Event* event, S // WebKit never allowed selectstart event to cross the the shadow DOM boundary. // Changing this breaks existing sites. // See https://bugs.webkit.org/show_bug.cgi?id=52195 for details. - if (event->type() == eventNames().selectstartEvent) + const AtomicString eventType = event->type(); + if (eventType == eventNames().abortEvent + || eventType == eventNames().changeEvent + || eventType == eventNames().resetEvent + || eventType == eventNames().resizeEvent + || eventType == eventNames().scrollEvent + || eventType == eventNames().selectEvent + || eventType == eventNames().selectstartEvent) return StayInsideShadowDOM; return RetargetEvent; diff --git a/Source/WebCore/dom/MemoryInstrumentation.h b/Source/WebCore/dom/MemoryInstrumentation.h index 7a0d41c50..114f96e69 100644 --- a/Source/WebCore/dom/MemoryInstrumentation.h +++ b/Source/WebCore/dom/MemoryInstrumentation.h @@ -30,7 +30,9 @@ #ifndef MemoryInstrumentation_h #define MemoryInstrumentation_h +#include <stdio.h> +#include <wtf/Assertions.h> #include <wtf/Forward.h> #include <wtf/OwnPtr.h> #include <wtf/PassOwnPtr.h> @@ -49,24 +51,64 @@ public: DOM, CSS, Binding, + Loader, LastTypeEntry }; - template <typename T> void reportInstrumentedObject(const T&); - template <typename T> void reportObject(const T&) { } - template <typename T> void reportInstrumentedPointer(const T*); - template <typename T> void reportPointer(const T* object, ObjectType objectType) + template <typename T> void addInstrumentedMember(const T& t) + { + OwningTraits<T>::addInstrumentedMember(this, t); + } + + template <typename T> void addMember(const T& t, ObjectType objectType) + { + OwningTraits<T>::addMember(this, t, objectType); + } + + template <typename HashMapType> void addHashMap(const HashMapType&, ObjectType, bool contentOnly = false); + template <typename HashSetType> void addHashSet(const HashSetType&, ObjectType, bool contentOnly = false); + template <typename HashSetType> void addInstrumentedHashSet(const HashSetType&, ObjectType, bool contentOnly = false); + template <typename ListHashSetType> void addListHashSet(const ListHashSetType&, ObjectType, bool contentOnly = false); + template <typename VectorType> void addVector(const VectorType&, ObjectType, bool contentOnly = false); + void addRawBuffer(const void* const& buffer, ObjectType objectType, size_t size) + { + if (!buffer || visited(buffer)) + return; + countObjectSize(objectType, size); + } + +protected: + enum OwningType { + byPointer, + byReference + }; + + template <typename T> + struct OwningTraits { // Default byReference implementation. + static void addInstrumentedMember(MemoryInstrumentation* instrumentation, const T& t) { instrumentation->addInstrumentedMemberImpl(&t, byReference); } + static void addMember(MemoryInstrumentation* instrumentation, const T& t, MemoryInstrumentation::ObjectType objectType) { instrumentation->addMemberImpl(&t, objectType, byReference); } + }; + + template <typename T> + struct OwningTraits<T*> { // Custom byPointer implementation. + static void addInstrumentedMember(MemoryInstrumentation* instrumentation, const T* const& t) { instrumentation->addInstrumentedMemberImpl(t, byPointer); } + static void addMember(MemoryInstrumentation* instrumentation, const T* const& t, MemoryInstrumentation::ObjectType objectType) { instrumentation->addMemberImpl(t, objectType, byPointer); } + }; + + template <typename T> void addInstrumentedMemberImpl(const T* const&, OwningType); + template <typename T> void addInstrumentedMemberImpl(const OwnPtr<T>* const& object, MemoryInstrumentation::OwningType owningType) { addInstrumentedMemberImpl(object->get(), owningType); } + template <typename T> void addInstrumentedMemberImpl(const RefPtr<T>* const& object, MemoryInstrumentation::OwningType owningType) { addInstrumentedMemberImpl(object->get(), owningType); } + + template <typename T> + void addMemberImpl(const T* const& object, ObjectType objectType, OwningType owningType) { if (!object || visited(object)) return; + if (owningType == byReference) + return; countObjectSize(objectType, sizeof(T)); } - template <typename HashMapType> void reportHashMap(const HashMapType&, ObjectType, bool contentOnly = false); - template <typename HashSetType> void reportHashSet(const HashSetType&, ObjectType, bool contentOnly = false); - template <typename ListHashSetType> void reportListHashSet(const ListHashSetType&, ObjectType, bool contentOnly = false); - template <typename VectorType> void reportVector(const VectorType&, ObjectType, bool contentOnly = false); -protected: class InstrumentedPointerBase { public: virtual ~InstrumentedPointerBase() { } @@ -81,8 +123,7 @@ protected: } private: - friend class MemoryObjectInfo; - + template <typename T> friend class MemoryClassInfo; template <typename T> class InstrumentedPointer : public InstrumentedPointerBase { public: @@ -94,7 +135,7 @@ private: const T* m_pointer; }; - virtual void reportString(ObjectType, const String&) = 0; + virtual void addString(const String&, ObjectType) = 0; virtual void countObjectSize(ObjectType, size_t) = 0; virtual void deferInstrumentedPointer(PassOwnPtr<InstrumentedPointerBase>) = 0; virtual bool visited(const void*) = 0; @@ -108,29 +149,15 @@ public: , m_objectSize(0) { } - template <typename P> - void reportInstrumentedPointer(const P* memberPointer) - { - m_memoryInstrumentation->reportInstrumentedPointer(memberPointer); - } - - template <typename P> - void reportPointer(const P* pointer, MemoryInstrumentation::ObjectType objectType) - { - m_memoryInstrumentation->reportPointer(pointer, objectType); - } + MemoryInstrumentation::ObjectType objectType() const { return m_objectType; } + size_t objectSize() const { return m_objectSize; } - template <typename T> - void reportInstrumentedObject(const T& memberObject) - { - m_memoryInstrumentation->reportInstrumentedObject(memberObject); - } + MemoryInstrumentation* memoryInstrumentation() { return m_memoryInstrumentation; } - template <typename T> - void reportObject(const T& object) { m_memoryInstrumentation->reportObject(object); } +private: + template <typename T> friend class MemoryClassInfo; - template <typename T> - void reportObjectInfo(const T*, MemoryInstrumentation::ObjectType objectType) + template <typename T> void reportObjectInfo(const T*, MemoryInstrumentation::ObjectType objectType) { if (m_objectType != MemoryInstrumentation::Other) return; @@ -138,79 +165,87 @@ public: m_objectSize = sizeof(T); } - template <typename HashMapType> - void reportHashMap(const HashMapType& map) - { - m_memoryInstrumentation->reportHashMap(map, objectType(), true); - } + MemoryInstrumentation* m_memoryInstrumentation; + MemoryInstrumentation::ObjectType m_objectType; + size_t m_objectSize; +}; - template <typename HashSetType> - void reportHashSet(const HashSetType& set) - { - m_memoryInstrumentation->reportHashSet(set, objectType(), true); - } +// Link time guard for string members. They produce link error is a string is reported via addMember. +template <> void MemoryInstrumentation::addMemberImpl<AtomicString>(const AtomicString* const&, MemoryInstrumentation::ObjectType, MemoryInstrumentation::OwningType); +template <> void MemoryInstrumentation::addMemberImpl<String>(const String* const&, MemoryInstrumentation::ObjectType, MemoryInstrumentation::OwningType); - template <typename ListHashSetType> - void reportListHashSet(const ListHashSetType& set) - { - m_memoryInstrumentation->reportListHashSet(set, objectType(), true); - } - template <typename VectorType> - void reportVector(const VectorType& vector) - { - m_memoryInstrumentation->reportVector(vector, objectType(), true); - } +template <typename T> +void MemoryInstrumentation::addInstrumentedMemberImpl(const T* const& object, MemoryInstrumentation::OwningType owningType) +{ + if (!object || visited(object)) + return; + if (owningType == byReference) { + MemoryObjectInfo memoryObjectInfo(this); + object->reportMemoryUsage(&memoryObjectInfo); + } else + deferInstrumentedPointer(adoptPtr(new InstrumentedPointer<T>(object))); +} - void reportString(const String& string) + +template <typename T> +class MemoryClassInfo { +public: + MemoryClassInfo(MemoryObjectInfo* memoryObjectInfo, const T* ptr, MemoryInstrumentation::ObjectType objectType) + : m_memoryObjectInfo(memoryObjectInfo) + , m_memoryInstrumentation(memoryObjectInfo->memoryInstrumentation()) { - m_memoryInstrumentation->reportString(objectType(), string); + m_memoryObjectInfo->reportObjectInfo(ptr, objectType); + m_objectType = memoryObjectInfo->objectType(); } - MemoryInstrumentation::ObjectType objectType() const { return m_objectType; } - size_t objectSize() const { return m_objectSize; } + template <typename P> void visitBaseClass(const P* ptr) { ptr->P::reportMemoryUsage(m_memoryObjectInfo); } - MemoryInstrumentation* memoryInstrumentation() { return m_memoryInstrumentation; } + template <typename M> void addInstrumentedMember(const M& member) { m_memoryInstrumentation->addInstrumentedMember(member); } + template <typename M> void addMember(const M& member) { m_memoryInstrumentation->addMember(member, m_objectType); } + + template <typename HashMapType> void addHashMap(const HashMapType& map) { m_memoryInstrumentation->addHashMap(map, m_objectType, true); } + template <typename HashSetType> void addHashSet(const HashSetType& set) { m_memoryInstrumentation->addHashSet(set, m_objectType, true); } + template <typename HashSetType> void addInstrumentedHashSet(const HashSetType& set) { m_memoryInstrumentation->addInstrumentedHashSet(set, m_objectType, true); } + template <typename ListHashSetType> void addListHashSet(const ListHashSetType& set) { m_memoryInstrumentation->addListHashSet(set, m_objectType, true); } + template <typename VectorType> void addVector(const VectorType& vector) { m_memoryInstrumentation->addVector(vector, m_objectType, true); } + void addRawBuffer(const void* const& buffer, size_t size) { m_memoryInstrumentation->addRawBuffer(buffer, m_objectType, size); } + + void addString(const String& string) { m_memoryInstrumentation->addString(string, m_objectType); } + void addString(const AtomicString& string) { m_memoryInstrumentation->addString((const String&)string, m_objectType); } - private: +private: + MemoryObjectInfo* m_memoryObjectInfo; MemoryInstrumentation* m_memoryInstrumentation; MemoryInstrumentation::ObjectType m_objectType; - size_t m_objectSize; }; -template <typename T> -void MemoryInstrumentation::reportInstrumentedPointer(const T* const object) +template<typename HashMapType> +void MemoryInstrumentation::addHashMap(const HashMapType& hashMap, ObjectType objectType, bool contentOnly) { - if (!object || visited(object)) - return; - deferInstrumentedPointer(adoptPtr(new InstrumentedPointer<T>(object))); + countObjectSize(objectType, calculateContainerSize(hashMap, contentOnly)); } -template<typename T> -void MemoryInstrumentation::reportInstrumentedObject(const T& object) +template<typename HashSetType> +void MemoryInstrumentation::addHashSet(const HashSetType& hashSet, ObjectType objectType, bool contentOnly) { - if (visited(&object)) + if (visited(&hashSet)) return; - MemoryObjectInfo memoryObjectInfo(this); - object.reportMemoryUsage(&memoryObjectInfo); -} - -template<typename HashMapType> -void MemoryInstrumentation::reportHashMap(const HashMapType& hashMap, ObjectType objectType, bool contentOnly) -{ - countObjectSize(objectType, calculateContainerSize(hashMap, contentOnly)); + countObjectSize(objectType, calculateContainerSize(hashSet, contentOnly)); } template<typename HashSetType> -void MemoryInstrumentation::reportHashSet(const HashSetType& hashSet, ObjectType objectType, bool contentOnly) +void MemoryInstrumentation::addInstrumentedHashSet(const HashSetType& hashSet, ObjectType objectType, bool contentOnly) { if (visited(&hashSet)) return; countObjectSize(objectType, calculateContainerSize(hashSet, contentOnly)); + for (typename HashSetType::const_iterator i = hashSet.begin(); i != hashSet.end(); ++i) + addInstrumentedMember(*i); } template<typename ListHashSetType> -void MemoryInstrumentation::reportListHashSet(const ListHashSetType& hashSet, ObjectType objectType, bool contentOnly) +void MemoryInstrumentation::addListHashSet(const ListHashSetType& hashSet, ObjectType objectType, bool contentOnly) { if (visited(&hashSet)) return; @@ -219,9 +254,9 @@ void MemoryInstrumentation::reportListHashSet(const ListHashSetType& hashSet, Ob } template <typename VectorType> -void MemoryInstrumentation::reportVector(const VectorType& vector, ObjectType objectType, bool contentOnly) +void MemoryInstrumentation::addVector(const VectorType& vector, ObjectType objectType, bool contentOnly) { - if (visited(vector.data())) + if (!vector.data() || visited(vector.data())) return; countObjectSize(objectType, calculateContainerSize(vector, contentOnly)); } @@ -234,6 +269,7 @@ void MemoryInstrumentation::InstrumentedPointer<T>::process(MemoryInstrumentatio memoryInstrumentation->countObjectSize(memoryObjectInfo.objectType(), memoryObjectInfo.objectSize()); } + } // namespace WebCore #endif // !defined(MemoryInstrumentation_h) diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp index 7d2aa6f09..8fd6d5c4f 100644 --- a/Source/WebCore/dom/Node.cpp +++ b/Source/WebCore/dom/Node.cpp @@ -974,7 +974,7 @@ void Node::invalidateNodeListCachesInAncestors(const QualifiedName* attrName, El if (!document()->shouldInvalidateNodeListCaches()) return; - document()->clearNodeListCaches(); + document()->invalidateNodeListCaches(attrName); for (Node* node = this; node; node = node->parentNode()) { if (!node->hasRareData()) @@ -1397,15 +1397,6 @@ bool Node::canStartSelection() const Node* Node::shadowAncestorNode() const { -#if ENABLE(SVG) - // SVG elements living in a shadow tree only occur when <use> created them. - // For these cases we do NOT want to return the shadowParentNode() here - // but the actual shadow tree element - as main difference to the HTML forms - // shadow tree concept. (This function _could_ be made virtual - opinions?) - if (isSVGElement()) - return const_cast<Node*>(this); -#endif - if (ShadowRoot* root = shadowRoot()) return root->host(); @@ -2223,18 +2214,12 @@ void Node::showTreeForThisAcrossFrame() const void NodeListsNodeData::invalidateCaches(const QualifiedName* attrName) { NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_atomicNameCaches.end(); - for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begin(); it != atomicNameCacheEnd; ++it) { - DynamicNodeList* list = it->second; - if (!attrName || DynamicNodeListCacheBase::shouldInvalidateTypeOnAttributeChange(list->invalidationType(), *attrName)) - list->invalidateCache(); - } + for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begin(); it != atomicNameCacheEnd; ++it) + it->second->invalidateCache(attrName); NodeListNameCacheMap::const_iterator nameCacheEnd = m_nameCaches.end(); - for (NodeListNameCacheMap::const_iterator it = m_nameCaches.begin(); it != nameCacheEnd; ++it) { - DynamicNodeList* list = it->second; - if (!attrName || DynamicNodeListCacheBase::shouldInvalidateTypeOnAttributeChange(list->invalidationType(), *attrName)) - list->invalidateCache(); - } + for (NodeListNameCacheMap::const_iterator it = m_nameCaches.begin(); it != nameCacheEnd; ++it) + it->second->invalidateCache(attrName); if (!attrName) return; @@ -2768,12 +2753,12 @@ void Node::removedLastRef() void Node::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::DOM); - TreeShared<Node, ContainerNode>::reportMemoryUsage(memoryObjectInfo); - ScriptWrappable::reportMemoryUsage(memoryObjectInfo); - memoryObjectInfo->reportPointer(m_document, MemoryInstrumentation::DOM); - memoryObjectInfo->reportInstrumentedPointer(m_next); - memoryObjectInfo->reportInstrumentedPointer(m_previous); + MemoryClassInfo<Node> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + info.visitBaseClass<TreeShared<Node, ContainerNode> >(this); + info.visitBaseClass<ScriptWrappable>(this); + info.addInstrumentedMember(m_document); + info.addInstrumentedMember(m_next); + info.addInstrumentedMember(m_previous); } } // namespace WebCore diff --git a/Source/WebCore/dom/QualifiedName.h b/Source/WebCore/dom/QualifiedName.h index 1907b8774..0fc651721 100644 --- a/Source/WebCore/dom/QualifiedName.h +++ b/Source/WebCore/dom/QualifiedName.h @@ -52,11 +52,11 @@ public: void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::DOM); - memoryObjectInfo->reportObject(m_prefix); - memoryObjectInfo->reportObject(m_localName); - memoryObjectInfo->reportObject(m_namespace); - memoryObjectInfo->reportObject(m_localNameUpper); + MemoryClassInfo<QualifiedNameImpl> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + info.addString(m_prefix); + info.addString(m_localName); + info.addString(m_namespace); + info.addString(m_localNameUpper); } private: QualifiedNameImpl(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI) @@ -104,8 +104,8 @@ public: void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::DOM); - memoryObjectInfo->reportInstrumentedPointer(m_impl); + MemoryClassInfo<QualifiedName> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + info.addInstrumentedMember(m_impl); } private: void init(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI); diff --git a/Source/WebCore/dom/ShadowRoot.cpp b/Source/WebCore/dom/ShadowRoot.cpp index 7b5d95331..67bb8618e 100644 --- a/Source/WebCore/dom/ShadowRoot.cpp +++ b/Source/WebCore/dom/ShadowRoot.cpp @@ -75,11 +75,6 @@ ShadowRoot::~ShadowRoot() static bool allowsAuthorShadowRoot(Element* element) { - // FIXME: MEDIA recreates shadow root dynamically. - // https://bugs.webkit.org/show_bug.cgi?id=77936 - if (element->hasTagName(HTMLNames::videoTag) || element->hasTagName(HTMLNames::audioTag)) - return false; - // FIXME: ValidationMessage recreates shadow root dynamically. // https://bugs.webkit.org/show_bug.cgi?id=77937 // Especially, INPUT recreates shadow root dynamically. diff --git a/Source/WebCore/fileapi/WebKitBlobBuilder.cpp b/Source/WebCore/fileapi/WebKitBlobBuilder.cpp index 5f7a858f4..5c54c4b6f 100644 --- a/Source/WebCore/fileapi/WebKitBlobBuilder.cpp +++ b/Source/WebCore/fileapi/WebKitBlobBuilder.cpp @@ -35,6 +35,7 @@ #include "Blob.h" #include "ExceptionCode.h" #include "File.h" +#include "HistogramSupport.h" #include "LineEnding.h" #include "ScriptExecutionContext.h" #include "TextEncoding.h" @@ -47,6 +48,12 @@ namespace WebCore { +enum BlobConstructorArrayBufferOrView { + BlobConstructorArrayBuffer, + BlobConstructorArrayBufferView, + BlobConstructorArrayBufferOrViewMax, +}; + // static PassRefPtr<WebKitBlobBuilder> WebKitBlobBuilder::create(ScriptExecutionContext* context) { @@ -101,22 +108,23 @@ void WebKitBlobBuilder::append(ScriptExecutionContext* context, ArrayBuffer* arr { String consoleMessage("ArrayBuffer values are deprecated in Blob Constructor. Use ArrayBufferView instead."); context->addConsoleMessage(JSMessageSource, LogMessageType, WarningMessageLevel, consoleMessage); + + HistogramSupport::histogramEnumeration("WebCore.Blob.constructor.ArrayBufferOrView", BlobConstructorArrayBuffer, BlobConstructorArrayBufferOrViewMax); + if (!arrayBuffer) return; - Vector<char>& buffer = getBuffer(); - size_t oldSize = buffer.size(); - buffer.append(static_cast<const char*>(arrayBuffer->data()), arrayBuffer->byteLength()); - m_size += buffer.size() - oldSize; + + appendBytesData(arrayBuffer->data(), arrayBuffer->byteLength()); } void WebKitBlobBuilder::append(ArrayBufferView* arrayBufferView) { + HistogramSupport::histogramEnumeration("WebCore.Blob.constructor.ArrayBufferOrView", BlobConstructorArrayBufferView, BlobConstructorArrayBufferOrViewMax); + if (!arrayBufferView) return; - Vector<char>& buffer = getBuffer(); - size_t oldSize = buffer.size(); - buffer.append(static_cast<const char*>(arrayBufferView->baseAddress()), arrayBufferView->byteLength()); - m_size += buffer.size() - oldSize; + + appendBytesData(arrayBufferView->baseAddress(), arrayBufferView->byteLength()); } #endif @@ -141,6 +149,15 @@ void WebKitBlobBuilder::append(Blob* blob) } } + +void WebKitBlobBuilder::appendBytesData(const void* data, size_t length) +{ + Vector<char>& buffer = getBuffer(); + size_t oldSize = buffer.size(); + buffer.append(static_cast<const char*>(data), length); + m_size += buffer.size() - oldSize; +} + PassRefPtr<Blob> WebKitBlobBuilder::getBlob(const String& contentType) { OwnPtr<BlobData> blobData = BlobData::create(); diff --git a/Source/WebCore/fileapi/WebKitBlobBuilder.h b/Source/WebCore/fileapi/WebKitBlobBuilder.h index b78c7a696..c0b5e128b 100644 --- a/Source/WebCore/fileapi/WebKitBlobBuilder.h +++ b/Source/WebCore/fileapi/WebKitBlobBuilder.h @@ -64,6 +64,8 @@ public: private: WebKitBlobBuilder(); + void appendBytesData(const void*, size_t); + Vector<char>& getBuffer(); long long m_size; diff --git a/Source/WebCore/html/BaseDateAndTimeInputType.cpp b/Source/WebCore/html/BaseDateAndTimeInputType.cpp index 48471cb65..921fcdba7 100644 --- a/Source/WebCore/html/BaseDateAndTimeInputType.cpp +++ b/Source/WebCore/html/BaseDateAndTimeInputType.cpp @@ -62,7 +62,8 @@ void BaseDateAndTimeInputType::setValueAsDate(double value, ExceptionCode&) cons double BaseDateAndTimeInputType::valueAsDouble() const { - return parseToDouble(element()->value()); + const Decimal value = parseToNumber(element()->value(), Decimal::nan()); + return value.isFinite() ? value.toDouble() : DateComponents::invalidMilliseconds(); } void BaseDateAndTimeInputType::setValueAsDecimal(const Decimal& newValue, TextFieldEventBehavior eventBehavior, ExceptionCode&) const @@ -108,20 +109,14 @@ void BaseDateAndTimeInputType::handleWheelEvent(WheelEvent* event) handleWheelEventForSpinButton(event); } -double BaseDateAndTimeInputType::parseToDouble(const String& source) const +Decimal BaseDateAndTimeInputType::parseToNumber(const String& source, const Decimal& defaultValue) const { DateComponents date; if (!parseToDateComponents(source, &date)) - return DateComponents::invalidMilliseconds(); + return defaultValue; double msec = date.millisecondsSinceEpoch(); ASSERT(isfinite(msec)); - return msec; -} - -Decimal BaseDateAndTimeInputType::parseToNumber(const String& source, const Decimal& defaultValue) const -{ - const double doubleValue = parseToDouble(source); - return isfinite(doubleValue) ? Decimal::fromDouble(doubleValue) : defaultValue; + return Decimal::fromDouble(msec); } bool BaseDateAndTimeInputType::parseToDateComponents(const String& source, DateComponents* out) const diff --git a/Source/WebCore/html/BaseDateAndTimeInputType.h b/Source/WebCore/html/BaseDateAndTimeInputType.h index 1658c1fe0..af335fa42 100644 --- a/Source/WebCore/html/BaseDateAndTimeInputType.h +++ b/Source/WebCore/html/BaseDateAndTimeInputType.h @@ -65,7 +65,6 @@ private: virtual String visibleValue() const OVERRIDE; virtual String convertFromVisibleValue(const String&) const OVERRIDE; virtual String sanitizeValue(const String&) const OVERRIDE; - double parseToDouble(const String&) const; }; } // namespace WebCore diff --git a/Source/WebCore/html/FormController.cpp b/Source/WebCore/html/FormController.cpp index c30845be5..46241be1a 100644 --- a/Source/WebCore/html/FormController.cpp +++ b/Source/WebCore/html/FormController.cpp @@ -77,6 +77,154 @@ FormControlState FormControlState::deserialize(const Vector<String>& stateVector // ---------------------------------------------------------------------------- +class FormElementKey { +public: + FormElementKey(AtomicStringImpl* = 0, AtomicStringImpl* = 0, AtomicStringImpl* = 0); + ~FormElementKey(); + FormElementKey(const FormElementKey&); + FormElementKey& operator=(const FormElementKey&); + + AtomicStringImpl* name() const { return m_name; } + AtomicStringImpl* type() const { return m_type; } + AtomicStringImpl* formKey() const { return m_formKey; } + + // Hash table deleted values, which are only constructed and never copied or destroyed. + FormElementKey(WTF::HashTableDeletedValueType) : m_name(hashTableDeletedValue()) { } + bool isHashTableDeletedValue() const { return m_name == hashTableDeletedValue(); } + +private: + void ref() const; + void deref() const; + + static AtomicStringImpl* hashTableDeletedValue() { return reinterpret_cast<AtomicStringImpl*>(-1); } + + AtomicStringImpl* m_name; + AtomicStringImpl* m_type; + AtomicStringImpl* m_formKey; +}; + +FormElementKey::FormElementKey(AtomicStringImpl* name, AtomicStringImpl* type, AtomicStringImpl* formKey) + : m_name(name) + , m_type(type) + , m_formKey(formKey) +{ + ref(); +} + +FormElementKey::~FormElementKey() +{ + deref(); +} + +FormElementKey::FormElementKey(const FormElementKey& other) + : m_name(other.name()) + , m_type(other.type()) + , m_formKey(other.formKey()) +{ + ref(); +} + +FormElementKey& FormElementKey::operator=(const FormElementKey& other) +{ + other.ref(); + deref(); + m_name = other.name(); + m_type = other.type(); + m_formKey = other.formKey(); + return *this; +} + +void FormElementKey::ref() const +{ + if (name()) + name()->ref(); + if (type()) + type()->ref(); + if (formKey()) + formKey()->ref(); +} + +void FormElementKey::deref() const +{ + if (name()) + name()->deref(); + if (type()) + type()->deref(); + if (formKey()) + formKey()->deref(); +} + +inline bool operator==(const FormElementKey& a, const FormElementKey& b) +{ + return a.name() == b.name() && a.type() == b.type() && a.formKey() == b.formKey(); +} + +struct FormElementKeyHash { + static unsigned hash(const FormElementKey&); + static bool equal(const FormElementKey& a, const FormElementKey& b) { return a == b; } + static const bool safeToCompareToEmptyOrDeleted = true; +}; + +unsigned FormElementKeyHash::hash(const FormElementKey& key) +{ + return StringHasher::hashMemory<sizeof(FormElementKey)>(&key); +} + +struct FormElementKeyHashTraits : WTF::GenericHashTraits<FormElementKey> { + static void constructDeletedValue(FormElementKey& slot) { new (NotNull, &slot) FormElementKey(WTF::HashTableDeletedValue); } + static bool isDeletedValue(const FormElementKey& value) { return value.isHashTableDeletedValue(); } +}; + +// ---------------------------------------------------------------------------- + +class SavedFormState { +public: + static PassOwnPtr<SavedFormState> create(); + bool isEmpty() const { return m_stateForNewFormElements.isEmpty(); } + void appendControlState(const AtomicString& name, const AtomicString& type, const AtomicString& formKey, const FormControlState&); + FormControlState takeControlState(const AtomicString& name, const AtomicString& type, const AtomicString& formKey); + +private: + SavedFormState() { } + + typedef HashMap<FormElementKey, Deque<FormControlState>, FormElementKeyHash, FormElementKeyHashTraits> FormElementStateMap; + FormElementStateMap m_stateForNewFormElements; +}; + +PassOwnPtr<SavedFormState> SavedFormState::create() +{ + return adoptPtr(new SavedFormState); +} + +void SavedFormState::appendControlState(const AtomicString& name, const AtomicString& type, const AtomicString& formKey, const FormControlState& state) +{ + FormElementKey key(name.impl(), type.impl(), formKey.impl()); + FormElementStateMap::iterator it = m_stateForNewFormElements.find(key); + if (it != m_stateForNewFormElements.end()) + it->second.append(state); + else { + Deque<FormControlState> stateList; + stateList.append(state); + m_stateForNewFormElements.set(key, stateList); + } +} + +FormControlState SavedFormState::takeControlState(const AtomicString& name, const AtomicString& type, const AtomicString& formKey) +{ + if (m_stateForNewFormElements.isEmpty()) + return FormControlState(); + FormElementStateMap::iterator it = m_stateForNewFormElements.find(FormElementKey(name.impl(), type.impl(), formKey.impl())); + if (it == m_stateForNewFormElements.end()) + return FormControlState(); + ASSERT(it->second.size()); + FormControlState state = it->second.takeFirst(); + if (!it->second.size()) + m_stateForNewFormElements.remove(it); + return state; +} + +// ---------------------------------------------------------------------------- + class FormKeyGenerator { WTF_MAKE_NONCOPYABLE(FormKeyGenerator); WTF_MAKE_FAST_ALLOCATED; @@ -190,7 +338,6 @@ static bool isNotFormControlTypeCharacter(UChar ch) void FormController::setStateForNewFormElements(const Vector<String>& stateVector) { - typedef FormElementStateMap::iterator Iterator; m_formElementsWithState.clear(); size_t i = 0; @@ -204,38 +351,23 @@ void FormController::setStateForNewFormElements(const Vector<String>& stateVecto FormControlState state = FormControlState::deserialize(stateVector, i); if (type.isEmpty() || type.impl()->find(isNotFormControlTypeCharacter) != notFound || state.isFailure()) break; - - FormElementKey key(name.impl(), type.impl(), formKey.impl()); - Iterator it = m_stateForNewFormElements.find(key); - if (it != m_stateForNewFormElements.end()) - it->second.append(state); - else { - Deque<FormControlState> stateList; - stateList.append(state); - m_stateForNewFormElements.set(key, stateList); - } + if (!m_savedFormState) + m_savedFormState = SavedFormState::create(); + m_savedFormState->appendControlState(name, type, formKey, state); } if (i != stateVector.size()) - m_stateForNewFormElements.clear(); + m_savedFormState.clear(); } FormControlState FormController::takeStateForFormElement(const HTMLFormControlElementWithState& control) { - if (m_stateForNewFormElements.isEmpty()) + if (!m_savedFormState) return FormControlState(); if (!m_formKeyGenerator) m_formKeyGenerator = FormKeyGenerator::create(); - typedef FormElementStateMap::iterator Iterator; - Iterator it = m_stateForNewFormElements.find(FormElementKey(control.name().impl(), control.type().impl(), m_formKeyGenerator->formKey(control).impl())); - if (it == m_stateForNewFormElements.end()) - return FormControlState(); - ASSERT(it->second.size()); - FormControlState state = it->second.takeFirst(); - if (!it->second.size()) { - m_stateForNewFormElements.remove(it); - if (m_stateForNewFormElements.isEmpty()) - m_formKeyGenerator.clear(); - } + FormControlState state = m_savedFormState->takeControlState(control.name(), control.type(), m_formKeyGenerator->formKey(control)); + if (m_savedFormState->isEmpty()) + m_savedFormState.clear(); return state; } @@ -276,61 +408,5 @@ void FormController::restoreControlStateIn(HTMLFormElement& form) } } -FormElementKey::FormElementKey(AtomicStringImpl* name, AtomicStringImpl* type, AtomicStringImpl* formKey) - : m_name(name) - , m_type(type) - , m_formKey(formKey) -{ - ref(); -} - -FormElementKey::~FormElementKey() -{ - deref(); -} - -FormElementKey::FormElementKey(const FormElementKey& other) - : m_name(other.name()) - , m_type(other.type()) - , m_formKey(other.formKey()) -{ - ref(); -} - -FormElementKey& FormElementKey::operator=(const FormElementKey& other) -{ - other.ref(); - deref(); - m_name = other.name(); - m_type = other.type(); - m_formKey = other.formKey(); - return *this; -} - -void FormElementKey::ref() const -{ - if (name()) - name()->ref(); - if (type()) - type()->ref(); - if (formKey()) - formKey()->ref(); -} - -void FormElementKey::deref() const -{ - if (name()) - name()->deref(); - if (type()) - type()->deref(); - if (formKey()) - formKey()->deref(); -} - -unsigned FormElementKeyHash::hash(const FormElementKey& key) -{ - return StringHasher::hashMemory<sizeof(FormElementKey)>(&key); -} - } // namespace WebCore diff --git a/Source/WebCore/html/FormController.h b/Source/WebCore/html/FormController.h index 4528483ed..2dd7b2202 100644 --- a/Source/WebCore/html/FormController.h +++ b/Source/WebCore/html/FormController.h @@ -35,48 +35,7 @@ class FormAssociatedElement; class FormKeyGenerator; class HTMLFormControlElementWithState; class HTMLFormElement; - -class FormElementKey { -public: - FormElementKey(AtomicStringImpl* = 0, AtomicStringImpl* = 0, AtomicStringImpl* = 0); - ~FormElementKey(); - FormElementKey(const FormElementKey&); - FormElementKey& operator=(const FormElementKey&); - - AtomicStringImpl* name() const { return m_name; } - AtomicStringImpl* type() const { return m_type; } - AtomicStringImpl* formKey() const { return m_formKey; } - - // Hash table deleted values, which are only constructed and never copied or destroyed. - FormElementKey(WTF::HashTableDeletedValueType) : m_name(hashTableDeletedValue()) { } - bool isHashTableDeletedValue() const { return m_name == hashTableDeletedValue(); } - -private: - void ref() const; - void deref() const; - - static AtomicStringImpl* hashTableDeletedValue() { return reinterpret_cast<AtomicStringImpl*>(-1); } - - AtomicStringImpl* m_name; - AtomicStringImpl* m_type; - AtomicStringImpl* m_formKey; -}; - -inline bool operator==(const FormElementKey& a, const FormElementKey& b) -{ - return a.name() == b.name() && a.type() == b.type() && a.formKey() == b.formKey(); -} - -struct FormElementKeyHash { - static unsigned hash(const FormElementKey&); - static bool equal(const FormElementKey& a, const FormElementKey& b) { return a == b; } - static const bool safeToCompareToEmptyOrDeleted = true; -}; - -struct FormElementKeyHashTraits : WTF::GenericHashTraits<FormElementKey> { - static void constructDeletedValue(FormElementKey& slot) { new (NotNull, &slot) FormElementKey(WTF::HashTableDeletedValue); } - static bool isDeletedValue(const FormElementKey& value) { return value.isHashTableDeletedValue(); } -}; +class SavedFormState; class FormControlState { public: @@ -142,8 +101,7 @@ private: typedef ListHashSet<HTMLFormControlElementWithState*, 64> FormElementListHashSet; FormElementListHashSet m_formElementsWithState; - typedef HashMap<FormElementKey, Deque<FormControlState>, FormElementKeyHash, FormElementKeyHashTraits> FormElementStateMap; - FormElementStateMap m_stateForNewFormElements; + OwnPtr<SavedFormState> m_savedFormState; OwnPtr<FormKeyGenerator> m_formKeyGenerator; }; diff --git a/Source/WebCore/html/HTMLCollection.cpp b/Source/WebCore/html/HTMLCollection.cpp index ef5f270a7..2b53edd98 100644 --- a/Source/WebCore/html/HTMLCollection.cpp +++ b/Source/WebCore/html/HTMLCollection.cpp @@ -246,13 +246,29 @@ static Node* nextNode(Node* base, Node* previous, bool onlyIncludeDirectChildren return onlyIncludeDirectChildren ? previous->previousSibling() : previous->traversePreviousNode(base); } +static inline Node* lastDescendent(Node* node) +{ + node = node->lastChild(); + for (Node* current = node; current; current = current->lastChild()) + node = current; + return node; +} + template<bool forward> static Element* itemBeforeOrAfter(CollectionType type, Node* base, unsigned& offsetInArray, Node* previous) { ASSERT_UNUSED(offsetInArray, !offsetInArray); bool onlyIncludeDirectChildren = shouldOnlyIncludeDirectChildren(type); Node* rootNode = base; - Node* current = previous ? nextNode<forward>(rootNode, previous, onlyIncludeDirectChildren) : (forward ? base->firstChild() : base->lastChild()); + Node* current; + if (previous) + current = nextNode<forward>(rootNode, previous, onlyIncludeDirectChildren); + else { + if (forward) + current = rootNode->firstChild(); + else + current = onlyIncludeDirectChildren ? rootNode->lastChild() : lastDescendent(rootNode); + } for (; current; current = nextNode<forward>(rootNode, current, onlyIncludeDirectChildren)) { if (current->isElementNode() && isAcceptableElement(type, toElement(current))) @@ -308,8 +324,8 @@ unsigned HTMLCollection::length() const do { offset++; } while (itemBeforeOrAfterCachedItem(offset)); + ASSERT(isLengthCacheValid()); - setLengthCache(offset); return offset; } @@ -381,7 +397,8 @@ Element* HTMLCollection::itemBeforeOrAfterCachedItem(unsigned offset) const } } - setLengthCache(currentOffset); + unsigned offsetOfLastItem = currentOffset; + setLengthCache(offsetOfLastItem + 1); return 0; } diff --git a/Source/WebCore/html/HTMLImageElement.cpp b/Source/WebCore/html/HTMLImageElement.cpp index 012d9ec69..2992b6a17 100644 --- a/Source/WebCore/html/HTMLImageElement.cpp +++ b/Source/WebCore/html/HTMLImageElement.cpp @@ -26,14 +26,17 @@ #include "Attribute.h" #include "CSSPropertyNames.h" #include "CSSValueKeywords.h" +#include "ElementShadow.h" #include "EventNames.h" #include "FrameView.h" #include "HTMLDocument.h" #include "HTMLFormElement.h" #include "HTMLNames.h" #include "HTMLParserIdioms.h" +#include "ImageInnerElement.h" #include "RenderImage.h" #include "ScriptEventListener.h" +#include "ShadowRoot.h" using namespace std; @@ -41,6 +44,29 @@ namespace WebCore { using namespace HTMLNames; +void ImageElement::setImageIfNecessary(RenderObject* renderObject, ImageLoader* imageLoader) +{ + if (renderObject && renderObject->isImage() && !imageLoader->hasPendingBeforeLoadEvent()) { + RenderImage* renderImage = toRenderImage(renderObject); + RenderImageResource* renderImageResource = renderImage->imageResource(); + if (renderImageResource->hasImage()) + return; + renderImageResource->setCachedImage(imageLoader->image()); + + // If we have no image at all because we have no src attribute, set + // image height and width for the alt text instead. + if (!imageLoader->image() && !renderImageResource->cachedImage()) + renderImage->setImageSizeForAltText(); + } +} + +RenderObject* ImageElement::createRendererForImage(HTMLElement* element, RenderArena* arena) +{ + RenderImage* image = new (arena) RenderImage(element); + image->setImageResource(RenderImageResource::create()); + return image; +} + HTMLImageElement::HTMLImageElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form) : HTMLElement(tagName, document) , m_imageLoader(this) @@ -68,6 +94,32 @@ HTMLImageElement::~HTMLImageElement() m_form->removeImgElement(this); } +void HTMLImageElement::willAddAuthorShadowRoot() +{ + if (shadow()->oldestShadowRoot()) + return; + + createShadowSubtree(); +} + +void HTMLImageElement::createShadowSubtree() +{ + RefPtr<ImageInnerElement> innerElement = ImageInnerElement::create(document()); + + RefPtr<ShadowRoot> root = ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot); + root->appendChild(innerElement); +} + +Element* HTMLImageElement::imageElement() +{ + if (ElementShadow* elementShadow = shadow()) { + ASSERT(elementShadow->oldestShadowRoot()->firstChild()->hasTagName(webkitInnerImageTag)); + return toElement(elementShadow->oldestShadowRoot()->firstChild()); + } + + return this; +} + PassRefPtr<HTMLImageElement> HTMLImageElement::createForJSConstructor(Document* document, const int* optionalWidth, const int* optionalHeight) { RefPtr<HTMLImageElement> image = adoptRef(new HTMLImageElement(imgTag, document)); @@ -110,11 +162,14 @@ void HTMLImageElement::collectStyleForAttribute(const Attribute& attribute, Styl void HTMLImageElement::parseAttribute(const Attribute& attribute) { if (attribute.name() == altAttr) { - if (renderer() && renderer()->isImage()) - toRenderImage(renderer())->updateAltText(); - } else if (attribute.name() == srcAttr) + RenderObject* renderObject = shadow() ? innerElement()->renderer() : renderer(); + if (renderObject && renderObject->isImage()) + toRenderImage(renderObject)->updateAltText(); + } else if (attribute.name() == srcAttr) { m_imageLoader.updateFromElementIgnoringPreviousError(); - else if (attribute.name() == usemapAttr) + if (ElementShadow* elementShadow = shadow()) + elementShadow->invalidateDistribution(); + } else if (attribute.name() == usemapAttr) setIsLink(!attribute.isNull()); else if (attribute.name() == onloadAttr) setAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(this, attribute)); @@ -141,30 +196,16 @@ String HTMLImageElement::altText() const RenderObject* HTMLImageElement::createRenderer(RenderArena* arena, RenderStyle* style) { - if (style->hasContent()) + if (style->hasContent() || shadow()) return RenderObject::createObject(this, style); - RenderImage* image = new (arena) RenderImage(this); - image->setImageResource(RenderImageResource::create()); - return image; + return createRendererForImage(this, arena); } void HTMLImageElement::attach() { HTMLElement::attach(); - - if (renderer() && renderer()->isImage() && !m_imageLoader.hasPendingBeforeLoadEvent()) { - RenderImage* renderImage = toRenderImage(renderer()); - RenderImageResource* renderImageResource = renderImage->imageResource(); - if (renderImageResource->hasImage()) - return; - renderImageResource->setCachedImage(m_imageLoader.image()); - - // If we have no image at all because we have no src attribute, set - // image height and width for the alt text instead. - if (!m_imageLoader.image() && !renderImageResource->cachedImage()) - renderImage->setImageSizeForAltText(); - } + setImageIfNecessary(renderer(), imageLoader()); } Node::InsertionNotificationRequest HTMLImageElement::insertedInto(ContainerNode* insertionPoint) @@ -366,4 +407,10 @@ void HTMLImageElement::setItemValueText(const String& value, ExceptionCode&) } #endif +inline ImageInnerElement* HTMLImageElement::innerElement() const +{ + ASSERT(shadow()); + return toImageInnerElement(shadow()->oldestShadowRoot()->firstChild()); +} + } diff --git a/Source/WebCore/html/HTMLImageElement.h b/Source/WebCore/html/HTMLImageElement.h index 9c6ff5af4..07a297372 100644 --- a/Source/WebCore/html/HTMLImageElement.h +++ b/Source/WebCore/html/HTMLImageElement.h @@ -27,13 +27,22 @@ #include "GraphicsTypes.h" #include "HTMLElement.h" #include "HTMLImageLoader.h" +#include "ImageLoaderClient.h" namespace WebCore { class HTMLFormElement; +class ImageInnerElement; -class HTMLImageElement : public HTMLElement { +class ImageElement { +protected: + void setImageIfNecessary(RenderObject*, ImageLoader*); + RenderObject* createRendererForImage(HTMLElement*, RenderArena*); +}; + +class HTMLImageElement : public HTMLElement, public ImageElement, public ImageLoaderClient { friend class HTMLFormElement; + friend class ImageInnerElement; public: static PassRefPtr<HTMLImageElement> create(Document*); static PassRefPtr<HTMLImageElement> create(const QualifiedName&, Document*, HTMLFormElement*); @@ -41,6 +50,8 @@ public: virtual ~HTMLImageElement(); + virtual void willAddAuthorShadowRoot() OVERRIDE; + int width(bool ignorePendingStylesheets = false); int height(bool ignorePendingStylesheets = false); @@ -84,6 +95,14 @@ protected: virtual void didMoveToNewDocument(Document* oldDocument) OVERRIDE; private: + virtual void createShadowSubtree(); + + // Implementation of ImageLoaderClient + Element* sourceElement() { return this; } + Element* imageElement(); + void refSourceElement() { ref(); } + void derefSourceElement() { deref(); } + virtual void parseAttribute(const Attribute&) OVERRIDE; virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE; virtual void collectStyleForAttribute(const Attribute&, StylePropertySet*) OVERRIDE; @@ -109,11 +128,26 @@ private: virtual void setItemValueText(const String&, ExceptionCode&) OVERRIDE; #endif + RenderObject* imageRenderer() const { return HTMLElement::renderer(); } + HTMLImageLoader* imageLoader() { return &m_imageLoader; } + ImageInnerElement* innerElement() const; + HTMLImageLoader m_imageLoader; HTMLFormElement* m_form; CompositeOperator m_compositeOperator; }; +inline bool isHTMLImageElement(Node* node) +{ + return node->hasTagName(HTMLNames::imgTag); +} + +inline HTMLImageElement* toHTMLImageElement(Node* node) +{ + ASSERT(!node || isHTMLImageElement(node)); + return static_cast<HTMLImageElement*>(node); +} + } //namespace #endif diff --git a/Source/WebCore/html/HTMLImageLoader.cpp b/Source/WebCore/html/HTMLImageLoader.cpp index 9bf013d5b..e69c3e091 100644 --- a/Source/WebCore/html/HTMLImageLoader.cpp +++ b/Source/WebCore/html/HTMLImageLoader.cpp @@ -38,8 +38,8 @@ namespace WebCore { -HTMLImageLoader::HTMLImageLoader(Element* node) - : ImageLoader(node) +HTMLImageLoader::HTMLImageLoader(ImageLoaderClient* client) + : ImageLoader(client) { } @@ -50,19 +50,19 @@ HTMLImageLoader::~HTMLImageLoader() void HTMLImageLoader::dispatchLoadEvent() { // HTMLVideoElement uses this class to load the poster image, but it should not fire events for loading or failure. - if (element()->hasTagName(HTMLNames::videoTag)) + if (client()->sourceElement()->hasTagName(HTMLNames::videoTag)) return; bool errorOccurred = image()->errorOccurred(); if (!errorOccurred && image()->response().httpStatusCode() >= 400) - errorOccurred = element()->hasTagName(HTMLNames::objectTag); // An <object> considers a 404 to be an error and should fire onerror. - element()->dispatchEvent(Event::create(errorOccurred ? eventNames().errorEvent : eventNames().loadEvent, false, false)); + errorOccurred = client()->sourceElement()->hasTagName(HTMLNames::objectTag); // An <object> considers a 404 to be an error and should fire onerror. + client()->imageElement()->dispatchEvent(Event::create(errorOccurred ? eventNames().errorEvent : eventNames().loadEvent, false, false)); } String HTMLImageLoader::sourceURI(const AtomicString& attr) const { #if ENABLE(DASHBOARD_SUPPORT) - Settings* settings = element()->document()->settings(); + Settings* settings = client()->sourceElement()->document()->settings(); if (settings && settings->usesDashboardBackwardCompatibilityMode() && attr.length() > 7 && attr.startsWith("url(\"") && attr.endsWith("\")")) return attr.string().substring(5, attr.length() - 7); #endif @@ -74,7 +74,7 @@ void HTMLImageLoader::notifyFinished(CachedResource*) { CachedImage* cachedImage = image(); - Element* elem = element(); + Element* elem = client()->sourceElement(); ImageLoader::notifyFinished(cachedImage); bool loadError = cachedImage->errorOccurred() || cachedImage->response().httpStatusCode() >= 400; diff --git a/Source/WebCore/html/HTMLImageLoader.h b/Source/WebCore/html/HTMLImageLoader.h index d3b606871..89399a62a 100644 --- a/Source/WebCore/html/HTMLImageLoader.h +++ b/Source/WebCore/html/HTMLImageLoader.h @@ -29,7 +29,7 @@ namespace WebCore { class HTMLImageLoader : public ImageLoader { public: - HTMLImageLoader(Element*); + HTMLImageLoader(ImageLoaderClient*); virtual ~HTMLImageLoader(); virtual void dispatchLoadEvent(); diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h index 20f0b42d1..2fd43d863 100644 --- a/Source/WebCore/html/HTMLInputElement.h +++ b/Source/WebCore/html/HTMLInputElement.h @@ -26,6 +26,7 @@ #define HTMLInputElement_h #include "HTMLTextFormControlElement.h" +#include "ImageLoaderClient.h" #include "StepRange.h" namespace WebCore { @@ -39,7 +40,7 @@ class Icon; class InputType; class KURL; -class HTMLInputElement : public HTMLTextFormControlElement { +class HTMLInputElement : public HTMLTextFormControlElement, public ImageLoaderClientBase<HTMLInputElement> { public: static PassRefPtr<HTMLInputElement> create(const QualifiedName&, Document*, HTMLFormElement*, bool createdByParser); virtual ~HTMLInputElement(); diff --git a/Source/WebCore/html/HTMLLinkElement.cpp b/Source/WebCore/html/HTMLLinkElement.cpp index f378de5dc..096ecca48 100644 --- a/Source/WebCore/html/HTMLLinkElement.cpp +++ b/Source/WebCore/html/HTMLLinkElement.cpp @@ -418,6 +418,16 @@ String HTMLLinkElement::type() const return getAttribute(typeAttr); } +IconType HTMLLinkElement::iconType() const +{ + return m_relAttribute.m_iconType; +} + +String HTMLLinkElement::iconSizes() const +{ + return m_sizes->toString(); +} + void HTMLLinkElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const { HTMLElement::addSubresourceAttributeURLs(urls); diff --git a/Source/WebCore/html/HTMLLinkElement.h b/Source/WebCore/html/HTMLLinkElement.h index bb69e129f..e330e73d1 100644 --- a/Source/WebCore/html/HTMLLinkElement.h +++ b/Source/WebCore/html/HTMLLinkElement.h @@ -55,6 +55,11 @@ public: String type() const; + IconType iconType() const; + + // the icon size string as parsed from the HTML attribute + String iconSizes() const; + CSSStyleSheet* sheet() const { return m_sheet.get(); } bool styleSheetIsLoading() const; diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp index 31d46df3f..705a05c5f 100644 --- a/Source/WebCore/html/HTMLMediaElement.cpp +++ b/Source/WebCore/html/HTMLMediaElement.cpp @@ -490,7 +490,10 @@ bool HTMLMediaElement::childShouldCreateRenderer(const NodeRenderingContext& chi { if (!hasMediaControls()) return false; - // Only allows nodes from the controls shadow subtree. + // <media> doesn't allow its content, including shadow subtree, to + // be rendered. So this should return false for most of the children. + // One exception is a shadow tree built for rendering controls which should be visible. + // So we let them go here by comparing its subtree root with one of the controls. return (mediaControls()->treeScope() == childContext.node()->treeScope() && childContext.isOnUpperEncapsulationBoundary() && HTMLElement::childShouldCreateRenderer(childContext)); } @@ -759,6 +762,7 @@ void HTMLMediaElement::loadInternal() // If we can't start a load right away, start it later. Page* page = document()->page(); if (pageConsentRequiredForLoad() && page && !page->canStartMedia()) { + setShouldDelayLoadEvent(false); if (m_isWaitingUntilMediaCanStart) return; document()->addMediaCanStartListener(this); @@ -1856,6 +1860,24 @@ void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*) } } +void HTMLMediaElement::createShadowSubtree() +{ + ASSERT(!shadow() || !shadow()->oldestShadowRoot()); + + ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot); +} + +void HTMLMediaElement::willAddAuthorShadowRoot() +{ + ASSERT(shadow()); + if (shadow()->oldestShadowRoot()) { + ASSERT(shadow()->oldestShadowRoot()->type() == ShadowRoot::UserAgentShadowRoot); + return; + } + + createShadowSubtree(); +} + void HTMLMediaElement::rewind(float timeDelta) { LOG(Media, "HTMLMediaElement::rewind(%f)", timeDelta); @@ -3985,7 +4007,7 @@ void HTMLMediaElement::enterFullscreen() #if ENABLE(FULLSCREEN_API) if (document() && document()->settings() && document()->settings()->fullScreenEnabled()) { - document()->requestFullScreenForElement(this, 0, Document::ExemptIFrameAllowFulScreenRequirement); + document()->requestFullScreenForElement(this, 0, Document::ExemptIFrameAllowFullScreenRequirement); return; } #endif @@ -4186,7 +4208,11 @@ bool HTMLMediaElement::createMediaControls() if (isFullscreen()) controls->enteredFullscreen(); - ensureShadowRoot()->appendChild(controls, ec); + if (!shadow()) + createShadowSubtree(); + + ASSERT(shadow()->oldestShadowRoot()->type() == ShadowRoot::UserAgentShadowRoot); + shadow()->oldestShadowRoot()->appendChild(controls, ec); return true; } diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h index 9f8150a9b..335bfbd36 100644 --- a/Source/WebCore/html/HTMLMediaElement.h +++ b/Source/WebCore/html/HTMLMediaElement.h @@ -83,7 +83,10 @@ class HTMLMediaElement : public HTMLElement, public MediaPlayerClient, public Me { public: MediaPlayer* player() const { return m_player.get(); } - + + void createShadowSubtree(); + virtual void willAddAuthorShadowRoot() OVERRIDE; + virtual bool isVideo() const = 0; virtual bool hasVideo() const { return false; } virtual bool hasAudio() const; diff --git a/Source/WebCore/html/HTMLObjectElement.h b/Source/WebCore/html/HTMLObjectElement.h index 932e5bccd..e12785d10 100644 --- a/Source/WebCore/html/HTMLObjectElement.h +++ b/Source/WebCore/html/HTMLObjectElement.h @@ -25,6 +25,7 @@ #include "FormAssociatedElement.h" #include "HTMLPlugInImageElement.h" +#include "ImageLoaderClient.h" namespace WebCore { diff --git a/Source/WebCore/html/HTMLPlugInElement.h b/Source/WebCore/html/HTMLPlugInElement.h index 813f8063d..067e9aef9 100644 --- a/Source/WebCore/html/HTMLPlugInElement.h +++ b/Source/WebCore/html/HTMLPlugInElement.h @@ -24,6 +24,7 @@ #define HTMLPlugInElement_h #include "HTMLFrameOwnerElement.h" +#include "ImageLoaderClient.h" #include "ScriptInstance.h" #if ENABLE(NETSCAPE_PLUGIN_API) @@ -36,7 +37,7 @@ class RenderEmbeddedObject; class RenderWidget; class Widget; -class HTMLPlugInElement : public HTMLFrameOwnerElement { +class HTMLPlugInElement : public HTMLFrameOwnerElement, public ImageLoaderClientBase<HTMLPlugInElement> { public: virtual ~HTMLPlugInElement(); diff --git a/Source/WebCore/html/HTMLTagNames.in b/Source/WebCore/html/HTMLTagNames.in index bfdcd3571..4119ba9b6 100644 --- a/Source/WebCore/html/HTMLTagNames.in +++ b/Source/WebCore/html/HTMLTagNames.in @@ -68,6 +68,7 @@ i interfaceName=HTMLElement iframe interfaceName=HTMLIFrameElement image mapToTagName=img img interfaceName=HTMLImageElement, constructorNeedsFormElement +webkitInnerImage interfaceName=HTMLElement, noConstructor input constructorNeedsFormElement, constructorNeedsCreatedByParser intent conditional=WEB_INTENTS_TAG ins interfaceName=HTMLModElement diff --git a/Source/WebCore/html/HTMLVideoElement.h b/Source/WebCore/html/HTMLVideoElement.h index f14670527..b4c0391a7 100644 --- a/Source/WebCore/html/HTMLVideoElement.h +++ b/Source/WebCore/html/HTMLVideoElement.h @@ -29,12 +29,13 @@ #if ENABLE(VIDEO) #include "HTMLMediaElement.h" +#include "ImageLoaderClient.h" namespace WebCore { class HTMLImageLoader; -class HTMLVideoElement : public HTMLMediaElement { +class HTMLVideoElement : public HTMLMediaElement, public ImageLoaderClientBase<HTMLVideoElement> { public: static PassRefPtr<HTMLVideoElement> create(const QualifiedName&, Document*, bool); diff --git a/Source/WebCore/html/MonthInputType.cpp b/Source/WebCore/html/MonthInputType.cpp index c9bebb135..70afa692e 100644 --- a/Source/WebCore/html/MonthInputType.cpp +++ b/Source/WebCore/html/MonthInputType.cpp @@ -101,7 +101,7 @@ StepRange MonthInputType::createStepRange(AnyStepHandling anyStepHandling) const { DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (monthDefaultStep, monthDefaultStepBase, monthStepScaleFactor, StepRange::ParsedStepValueShouldBeInteger)); - const Decimal stepBase = parseToNumber(element()->fastGetAttribute(minAttr), Decimal::fromDouble(DateComponents::minimumMonth())); + const Decimal stepBase = parseToNumber(element()->fastGetAttribute(minAttr), Decimal::fromDouble(monthDefaultStepBase)); const Decimal minimum = parseToNumber(element()->fastGetAttribute(minAttr), Decimal::fromDouble(DateComponents::minimumMonth())); const Decimal maximum = parseToNumber(element()->fastGetAttribute(maxAttr), Decimal::fromDouble(DateComponents::maximumMonth())); const Decimal step = StepRange::parseStep(anyStepHandling, stepDescription, element()->fastGetAttribute(stepAttr)); diff --git a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp index cbdc4352f..803b0e7d3 100644 --- a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp +++ b/Source/WebCore/html/parser/HTMLTreeBuilder.cpp @@ -1468,21 +1468,9 @@ void HTMLTreeBuilder::processAnyOtherEndTagForInBody(AtomicHTMLToken& token) while (1) { RefPtr<ContainerNode> node = record->node(); if (node->hasLocalName(token.name())) { - m_tree.generateImpliedEndTags(); - // FIXME: The ElementRecord pointed to by record might be deleted by - // the preceding call. Perhaps we should hold a RefPtr so that it - // stays alive for the duration of record's scope. - record = 0; - if (!m_tree.currentNode()->hasLocalName(token.name())) { + m_tree.generateImpliedEndTagsWithExclusion(token.name()); + if (!m_tree.currentNode()->hasLocalName(token.name())) parseError(token); - // FIXME: This is either a bug in the spec, or a bug in our - // implementation. Filed a bug with HTML5: - // http://www.w3.org/Bugs/Public/show_bug.cgi?id=10080 - // We might have already popped the node for the token in - // generateImpliedEndTags, just abort. - if (!m_tree.openElements()->contains(toElement(node.get()))) - return; - } m_tree.openElements()->popUntilPopped(toElement(node.get())); return; } diff --git a/Source/WebCore/html/shadow/CalendarPickerElement.cpp b/Source/WebCore/html/shadow/CalendarPickerElement.cpp index 5358ccaf7..b4176b296 100644 --- a/Source/WebCore/html/shadow/CalendarPickerElement.cpp +++ b/Source/WebCore/html/shadow/CalendarPickerElement.cpp @@ -88,6 +88,8 @@ inline HTMLInputElement* CalendarPickerElement::hostInput() void CalendarPickerElement::defaultEventHandler(Event* event) { + if (!renderer()) + return; HTMLInputElement* input = hostInput(); if (input->readOnly() || input->disabled()) return; diff --git a/Source/WebCore/html/shadow/ImageInnerElement.cpp b/Source/WebCore/html/shadow/ImageInnerElement.cpp new file mode 100644 index 000000000..4ca44e9c1 --- /dev/null +++ b/Source/WebCore/html/shadow/ImageInnerElement.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ImageInnerElement.h" + +#include "HTMLImageElement.h" +#include "ImageLoader.h" +#include "RenderImage.h" + +namespace WebCore { + +using namespace HTMLNames; + +ImageInnerElement::ImageInnerElement(Document* document) + : HTMLElement(HTMLNames::webkitInnerImageTag, document) +{ +} + +inline HTMLImageElement* ImageInnerElement::hostImage() +{ + return toHTMLImageElement(shadowAncestorNode()); +} + +inline ImageLoader* ImageInnerElement::imageLoader() +{ + return hostImage()->imageLoader(); +} + +void ImageInnerElement::attach() +{ + HTMLElement::attach(); + setImageIfNecessary(renderer(), imageLoader()); +} + +RenderObject* ImageInnerElement::createRenderer(RenderArena* arena, RenderStyle* style) +{ + if (style->hasContent()) + return RenderObject::createObject(this, style); + + return createRendererForImage(this, arena); +} + +} diff --git a/Source/WebCore/html/shadow/ImageInnerElement.h b/Source/WebCore/html/shadow/ImageInnerElement.h new file mode 100644 index 000000000..2586306e5 --- /dev/null +++ b/Source/WebCore/html/shadow/ImageInnerElement.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ImageInnerElement_h +#define ImageInnerElement_h + +#include "HTMLImageElement.h" + +namespace WebCore { + +class HTMLImageElement; +class ImageLoader; +class RenderObject; + +class ImageInnerElement : public HTMLElement, public ImageElement { +public: + static PassRefPtr<ImageInnerElement> create(Document*); + +private: + ImageInnerElement(Document*); + + HTMLImageElement* hostImage(); + + ImageLoader* imageLoader(); + RenderObject* imageRenderer() const { return HTMLElement::renderer(); } + + virtual void attach() OVERRIDE; + virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) OVERRIDE; +}; + +inline PassRefPtr<ImageInnerElement> ImageInnerElement::create(Document* document) +{ + return adoptRef(new ImageInnerElement(document)); +} + +inline bool isImageInnerElement(Node* node) +{ + return !node || node->hasTagName(HTMLNames::webkitInnerImageTag); +} + +inline ImageInnerElement* toImageInnerElement(Node* node) +{ + ASSERT(isImageInnerElement(node)); + return static_cast<ImageInnerElement*>(node); +} + +} + +#endif diff --git a/Source/WebCore/html/shadow/InsertionPoint.cpp b/Source/WebCore/html/shadow/InsertionPoint.cpp index c1e020023..fadbb457b 100644 --- a/Source/WebCore/html/shadow/InsertionPoint.cpp +++ b/Source/WebCore/html/shadow/InsertionPoint.cpp @@ -119,7 +119,7 @@ Node::InsertionNotificationRequest InsertionPoint::insertedInto(ContainerNode* i HTMLElement::insertedInto(insertionPoint); if (insertionPoint->inDocument()) { if (ShadowRoot* root = shadowRoot()) - root->owner()->invalidateDistribution(); + root->owner()->invalidateDistribution(ElementShadow::InvalidateAndForceReattach); } return InsertionDone; diff --git a/Source/WebCore/html/shadow/MediaControlElements.cpp b/Source/WebCore/html/shadow/MediaControlElements.cpp index 236384f16..74f6788a2 100644 --- a/Source/WebCore/html/shadow/MediaControlElements.cpp +++ b/Source/WebCore/html/shadow/MediaControlElements.cpp @@ -1010,7 +1010,7 @@ void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event) if (document()->webkitIsFullScreen() && document()->webkitCurrentFullScreenElement() == toParentMediaElement(this)) document()->webkitCancelFullScreen(); else - document()->requestFullScreenForElement(toParentMediaElement(this), 0, Document::ExemptIFrameAllowFulScreenRequirement); + document()->requestFullScreenForElement(toParentMediaElement(this), 0, Document::ExemptIFrameAllowFullScreenRequirement); } else #endif mediaController()->enterFullscreen(); diff --git a/Source/WebCore/inspector/InspectorClient.h b/Source/WebCore/inspector/InspectorClient.h index 7671b0018..fc8d0247f 100644 --- a/Source/WebCore/inspector/InspectorClient.h +++ b/Source/WebCore/inspector/InspectorClient.h @@ -27,23 +27,23 @@ #ifndef InspectorClient_h #define InspectorClient_h -#include "InspectorFrontendChannel.h" #include "InspectorStateClient.h" #include <wtf/Forward.h> namespace WebCore { class InspectorController; +class InspectorFrontendChannel; class Frame; class Page; -class InspectorClient : public InspectorFrontendChannel, public InspectorStateClient { +class InspectorClient : public InspectorStateClient { public: virtual ~InspectorClient() { } virtual void inspectorDestroyed() = 0; - virtual void openInspectorFrontend(InspectorController*) = 0; + virtual InspectorFrontendChannel* openInspectorFrontend(InspectorController*) = 0; virtual void closeInspectorFrontend() = 0; virtual void bringFrontendToFront() = 0; virtual void didResizeMainFrame(Frame*) { } diff --git a/Source/WebCore/inspector/InspectorController.cpp b/Source/WebCore/inspector/InspectorController.cpp index 095e1cc51..912bbaad6 100644 --- a/Source/WebCore/inspector/InspectorController.cpp +++ b/Source/WebCore/inspector/InspectorController.cpp @@ -208,9 +208,11 @@ void InspectorController::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWo m_inspectorFrontendClient->windowObjectCleared(); } -void InspectorController::connectFrontend() +void InspectorController::connectFrontend(InspectorFrontendChannel* frontendChannel) { - m_inspectorFrontend = adoptPtr(new InspectorFrontend(m_inspectorClient)); + ASSERT(frontendChannel); + + m_inspectorFrontend = adoptPtr(new InspectorFrontend(frontendChannel)); // We can reconnect to existing front-end -> unmute state. m_state->unmute(); @@ -223,7 +225,7 @@ void InspectorController::connectFrontend() InspectorInstrumentation::frontendCreated(); ASSERT(m_inspectorClient); - m_inspectorBackendDispatcher = InspectorBackendDispatcher::create(m_inspectorClient); + m_inspectorBackendDispatcher = InspectorBackendDispatcher::create(frontendChannel); InspectorBackendDispatcher* dispatcher = m_inspectorBackendDispatcher.get(); for (Agents::iterator it = m_agents.begin(); it != m_agents.end(); ++it) @@ -259,8 +261,9 @@ void InspectorController::show() if (m_inspectorFrontend) m_inspectorClient->bringFrontendToFront(); else { - m_inspectorClient->openInspectorFrontend(this); - connectFrontend(); + InspectorFrontendChannel* frontendChannel = m_inspectorClient->openInspectorFrontend(this); + if (frontendChannel) + connectFrontend(frontendChannel); } } @@ -272,10 +275,10 @@ void InspectorController::close() m_inspectorClient->closeInspectorFrontend(); } -void InspectorController::restoreInspectorStateFromCookie(const String& inspectorStateCookie) +void InspectorController::reconnectFrontend(InspectorFrontendChannel* frontendChannel, const String& inspectorStateCookie) { ASSERT(!m_inspectorFrontend); - connectFrontend(); + connectFrontend(frontendChannel); m_state->loadFromCookie(inspectorStateCookie); for (Agents::iterator it = m_agents.begin(); it != m_agents.end(); ++it) diff --git a/Source/WebCore/inspector/InspectorController.h b/Source/WebCore/inspector/InspectorController.h index 473bb8de2..b7e1cbfd8 100644 --- a/Source/WebCore/inspector/InspectorController.h +++ b/Source/WebCore/inspector/InspectorController.h @@ -50,6 +50,7 @@ class InspectorClient; class InspectorDOMAgent; class InspectorDebuggerAgent; class InspectorFrontend; +class InspectorFrontendChannel; class InspectorFrontendClient; class InspectorPageAgent; class InspectorProfilerAgent; @@ -85,9 +86,9 @@ public: void dispatchMessageFromFrontend(const String& message); bool hasFrontend() const { return m_inspectorFrontend; } - void connectFrontend(); + void connectFrontend(InspectorFrontendChannel*); void disconnectFrontend(); - void restoreInspectorStateFromCookie(const String& inspectorCookie); + void reconnectFrontend(InspectorFrontendChannel*, const String& inspectorStateCookie); void setProcessId(long); void inspect(Node*); diff --git a/Source/WebCore/inspector/InspectorMemoryAgent.cpp b/Source/WebCore/inspector/InspectorMemoryAgent.cpp index 5b3e3662d..bf1d5ae1b 100644 --- a/Source/WebCore/inspector/InspectorMemoryAgent.cpp +++ b/Source/WebCore/inspector/InspectorMemoryAgent.cpp @@ -96,6 +96,7 @@ static const char domTreeOther[] = "DOMTreeOther"; static const char domTreeDOM[] = "DOMTreeDOM"; static const char domTreeCSS[] = "DOMTreeCSS"; static const char domTreeBinding[] = "DOMTreeBinding"; +static const char domTreeLoader[] = "DOMTreeLoader"; } namespace { @@ -483,6 +484,7 @@ public: addMemoryBlockFor(domChildren.get(), m_totalSizes[DOM], MemoryBlockName::domTreeDOM); addMemoryBlockFor(domChildren.get(), m_totalSizes[CSS], MemoryBlockName::domTreeCSS); addMemoryBlockFor(domChildren.get(), m_totalSizes[Binding], MemoryBlockName::domTreeBinding); + addMemoryBlockFor(domChildren.get(), m_totalSizes[Loader], MemoryBlockName::domTreeLoader); RefPtr<InspectorMemoryBlock> dom = InspectorMemoryBlock::create().setName(MemoryBlockName::dom); dom->setSize(totalSize); @@ -500,7 +502,7 @@ public: } private: - virtual void reportString(ObjectType objectType, const String& string) + virtual void addString(const String& string, ObjectType objectType) { if (string.isNull() || visited(string.impl())) return; @@ -541,7 +543,13 @@ public: if (node->document() && node->document()->frame() && m_page != node->document()->frame()->page()) return; - m_domMemoryUsage.reportInstrumentedPointer(node); + m_domMemoryUsage.addInstrumentedMember(node); + m_domMemoryUsage.processDeferredInstrumentedPointers(); + } + + void visitFrame(Frame* frame) + { + m_domMemoryUsage.addInstrumentedMember(frame); m_domMemoryUsage.processDeferredInstrumentedPointers(); } @@ -570,8 +578,10 @@ static PassRefPtr<InspectorMemoryBlock> domTreeInfo(Page* page, VisitedObjects& // Make sure all documents reachable from the main frame are accounted. for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) { - if (Document* doc = frame->document()) + if (Document* doc = frame->document()) { domTreesIterator.visitNode(doc); + domTreesIterator.visitFrame(frame); + } } domTreesIterator.visitBindings(); diff --git a/Source/WebCore/inspector/InspectorStyleSheet.cpp b/Source/WebCore/inspector/InspectorStyleSheet.cpp index 5f5bb050c..b2643992d 100644 --- a/Source/WebCore/inspector/InspectorStyleSheet.cpp +++ b/Source/WebCore/inspector/InspectorStyleSheet.cpp @@ -1116,7 +1116,8 @@ bool InspectorStyleSheet::ensureSourceData() return false; RefPtr<StyleSheetContents> newStyleSheet = StyleSheetContents::create(); - CSSParser p(m_pageStyleSheet->ownerDocument()); + Document* ownerDocument = m_pageStyleSheet->ownerDocument(); + CSSParser p(ownerDocument ? CSSParserContext(ownerDocument) : strictCSSParserContext()); OwnPtr<RuleSourceDataList> ruleSourceDataResult = adoptPtr(new RuleSourceDataList()); p.parseSheet(newStyleSheet.get(), m_parsedStyleSheet->text(), 0, ruleSourceDataResult.get()); m_parsedStyleSheet->setSourceData(ruleSourceDataResult.release()); diff --git a/Source/WebCore/inspector/front-end/ConsolePanel.js b/Source/WebCore/inspector/front-end/ConsolePanel.js index fc3b85317..54ef63d68 100644 --- a/Source/WebCore/inspector/front-end/ConsolePanel.js +++ b/Source/WebCore/inspector/front-end/ConsolePanel.js @@ -76,7 +76,11 @@ WebInspector.ConsolePanel.prototype = { delete this._searchRegex; }, - performSearch: function(query) + /** + * @param {string} query + * @param {boolean} loop + */ + performSearch: function(query, loop) { WebInspector.searchController.updateSearchMatchesCount(0, this); this.searchCanceled(); @@ -96,21 +100,36 @@ WebInspector.ConsolePanel.prototype = { this._jumpToSearchResult(0); }, - jumpToNextSearchResult: function() + /** + * @param {boolean} loop + * @return {boolean} + */ + jumpToNextSearchResult: function(loop) { if (!this._searchResults || !this._searchResults.length) - return; + return false; + if (!loop && this._currentSearchResultIndex + 1 >= this._searchResults.length) + return false; this._jumpToSearchResult((this._currentSearchResultIndex + 1) % this._searchResults.length); + return true; }, - jumpToPreviousSearchResult: function() + /** + * @param {boolean} loop + * @return {boolean} + */ + jumpToPreviousSearchResult: function(loop) { if (!this._searchResults || !this._searchResults.length) - return; + return false; var index = this._currentSearchResultIndex - 1; - if (index === -1) + if (index === -1) { + if (!loop) + return false; index = this._searchResults.length - 1; + } this._jumpToSearchResult(index); + return true; }, _clearCurrentSearchResultHighlight: function() diff --git a/Source/WebCore/inspector/front-end/ElementsPanel.js b/Source/WebCore/inspector/front-end/ElementsPanel.js index 3feaf354f..740185e9a 100644 --- a/Source/WebCore/inspector/front-end/ElementsPanel.js +++ b/Source/WebCore/inspector/front-end/ElementsPanel.js @@ -292,7 +292,11 @@ WebInspector.ElementsPanel.prototype = { WebInspector.domAgent.cancelSearch(); }, - performSearch: function(query) + /** + * @param {string} query + * @param {boolean} loop + */ + performSearch: function(query, loop) { // Call searchCanceled since it will reset everything we need before doing a new search. this.searchCanceled(); @@ -489,28 +493,44 @@ WebInspector.ElementsPanel.prototype = { } }, - jumpToNextSearchResult: function() + /** + * @param {boolean} loop + * @return {boolean} + */ + jumpToNextSearchResult: function(loop) { if (!this._searchResults) - return; + return false; this._hideSearchHighlights(); - if (++this._currentSearchResultIndex >= this._searchResults.length) + if (++this._currentSearchResultIndex >= this._searchResults.length) { + if (!loop) + return false; this._currentSearchResultIndex = 0; + } this._highlightCurrentSearchResult(); + return true; }, - jumpToPreviousSearchResult: function() + /** + * @param {boolean} loop + * @return {boolean} + */ + jumpToPreviousSearchResult: function(loop) { if (!this._searchResults) - return; + return false; this._hideSearchHighlights(); - if (--this._currentSearchResultIndex < 0) + if (--this._currentSearchResultIndex < 0) { + if (!loop) + return false; this._currentSearchResultIndex = (this._searchResults.length - 1); + } this._highlightCurrentSearchResult(); + return true; }, _highlightCurrentSearchResult: function() diff --git a/Source/WebCore/inspector/front-end/ExtensionPanel.js b/Source/WebCore/inspector/front-end/ExtensionPanel.js index 551e39437..d828d336e 100644 --- a/Source/WebCore/inspector/front-end/ExtensionPanel.js +++ b/Source/WebCore/inspector/front-end/ExtensionPanel.js @@ -151,22 +151,36 @@ WebInspector.ExtensionPanel.prototype = { WebInspector.Panel.prototype.searchCanceled.apply(this, arguments); }, - performSearch: function(query) + /** + * @param {string} query + * @param {boolean} loop + */ + performSearch: function(query, loop) { WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.PerformSearch, query); WebInspector.Panel.prototype.performSearch.apply(this, arguments); }, - jumpToNextSearchResult: function() + /** + * @param {boolean} loop + * @return {boolean} + */ + jumpToNextSearchResult: function(loop) { WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.NextSearchResult); - WebInspector.Panel.prototype.jumpToNextSearchResult.call(this); + WebInspector.Panel.prototype.jumpToNextSearchResult.call(this, loop); + return true; }, - jumpToPreviousSearchResult: function() + /** + * @param {boolean} loop + * @return {boolean} + */ + jumpToPreviousSearchResult: function(loop) { WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.PreviousSearchResult); - WebInspector.Panel.prototype.jumpToPreviousSearchResult.call(this); + WebInspector.Panel.prototype.jumpToPreviousSearchResult.call(this, loop); + return true; }, _addStyleRule: function(selector, body) diff --git a/Source/WebCore/inspector/front-end/InspectorView.js b/Source/WebCore/inspector/front-end/InspectorView.js index de3345501..efa01d49e 100644 --- a/Source/WebCore/inspector/front-end/InspectorView.js +++ b/Source/WebCore/inspector/front-end/InspectorView.js @@ -85,7 +85,7 @@ WebInspector.InspectorView.prototype = { x.show(); this.dispatchEventToListeners(WebInspector.InspectorView.Events.PanelSelected); // FIXME: remove search controller. - WebInspector.searchController.activePanelChanged(); + WebInspector.searchController.cancelSearch(); } for (var panelName in WebInspector.panels) { if (WebInspector.panels[panelName] === x) { diff --git a/Source/WebCore/inspector/front-end/JavaScriptSourceFrame.js b/Source/WebCore/inspector/front-end/JavaScriptSourceFrame.js index 435ae2185..ade0491fa 100644 --- a/Source/WebCore/inspector/front-end/JavaScriptSourceFrame.js +++ b/Source/WebCore/inspector/front-end/JavaScriptSourceFrame.js @@ -150,13 +150,13 @@ WebInspector.JavaScriptSourceFrame.prototype = { afterTextChanged: function(oldRange, newRange) { WebInspector.SourceFrame.prototype.afterTextChanged.call(this, oldRange, newRange); - this._javaScriptSource.setWorkingCopy(this.textModel.text); + this._javaScriptSource.setWorkingCopy(this.textModel.text()); this._restoreBreakpointsAfterEditing(); }, - beforeTextChanged: function() + beforeTextChanged: function(userInput) { - WebInspector.SourceFrame.prototype.beforeTextChanged.call(this); + WebInspector.SourceFrame.prototype.beforeTextChanged.call(this, userInput); this._removeBreakpointsBeforeEditing(); }, diff --git a/Source/WebCore/inspector/front-end/NetworkPanel.js b/Source/WebCore/inspector/front-end/NetworkPanel.js index 4d2c9ea3c..0bfa3bb0c 100644 --- a/Source/WebCore/inspector/front-end/NetworkPanel.js +++ b/Source/WebCore/inspector/front-end/NetworkPanel.js @@ -295,7 +295,7 @@ WebInspector.NetworkLogView.prototype = { this._timelineSortSelector.selectedIndex = 0; this._updateOffscreenRows(); - this.performSearch(null, true); + this.performSearch(null); }, _sortByTimeline: function() @@ -441,7 +441,7 @@ WebInspector.NetworkLogView.prototype = { selectMultiple = true; this._filter(e.target, selectMultiple); - this.performSearch(null, true); + this.performSearch(null); this._updateSummaryBar(); }, @@ -1139,15 +1139,14 @@ WebInspector.NetworkLogView.prototype = { this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.SearchIndexUpdated, this._currentMatchedRequestIndex); }, - performSearch: function(searchQuery, sortOrFilterApplied) + performSearch: function(searchQuery) { var newMatchedRequestIndex = 0; var currentMatchedRequestId; if (this._currentMatchedRequestIndex !== -1) currentMatchedRequestId = this._matchedRequests[this._currentMatchedRequestIndex]; - if (!sortOrFilterApplied) - this._searchRegExp = createPlainTextSearchRegex(searchQuery, "i"); + this._searchRegExp = createPlainTextSearchRegex(searchQuery, "i"); this._clearSearchMatchedList(); @@ -1164,21 +1163,35 @@ WebInspector.NetworkLogView.prototype = { } this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.SearchCountUpdated, this._matchedRequests.length); - this._highlightNthMatchedRequest(newMatchedRequestIndex, !sortOrFilterApplied); + this._highlightNthMatchedRequest(newMatchedRequestIndex, false); }, - jumpToPreviousSearchResult: function() + /** + * @param {boolean} loop + * @return {boolean} + */ + jumpToPreviousSearchResult: function(loop) { if (!this._matchedRequests.length) - return; + return false; + if (!loop && this._currentMatchedRequestIndex <= 0) + return false; this._highlightNthMatchedRequest((this._currentMatchedRequestIndex + this._matchedRequests.length - 1) % this._matchedRequests.length, true); + return true; }, - jumpToNextSearchResult: function() + /** + * @param {boolean} loop + * @return {boolean} + */ + jumpToNextSearchResult: function(loop) { if (!this._matchedRequests.length) - return; + return false; + if (!loop && this._currentMatchedRequestIndex + 1 >= this._matchedRequests.length) + return false; this._highlightNthMatchedRequest((this._currentMatchedRequestIndex + 1) % this._matchedRequests.length, true); + return true; }, searchCanceled: function() @@ -1420,19 +1433,25 @@ WebInspector.NetworkPanel.prototype = { this._networkLogView.switchToBriefView(); }, - performSearch: function(searchQuery, sortOrFilterApplied) + performSearch: function(searchQuery) { - this._networkLogView.performSearch(searchQuery, sortOrFilterApplied); + this._networkLogView.performSearch(searchQuery); }, - jumpToPreviousSearchResult: function() + /** + * @param {boolean} loop + */ + jumpToPreviousSearchResult: function(loop) { - this._networkLogView.jumpToPreviousSearchResult(); + this._networkLogView.jumpToPreviousSearchResult(loop); }, - jumpToNextSearchResult: function() + /** + * @param {boolean} loop + */ + jumpToNextSearchResult: function(loop) { - this._networkLogView.jumpToNextSearchResult(); + this._networkLogView.jumpToNextSearchResult(loop); }, searchCanceled: function() diff --git a/Source/WebCore/inspector/front-end/Panel.js b/Source/WebCore/inspector/front-end/Panel.js index ecfb3e889..a14641c8a 100644 --- a/Source/WebCore/inspector/front-end/Panel.js +++ b/Source/WebCore/inspector/front-end/Panel.js @@ -106,17 +106,53 @@ WebInspector.Panel.prototype = { WebInspector.searchController.updateSearchMatchesCount(0, this); }, - performSearch: function(query) + /** + * @param {string} query + * @param {boolean} loop + */ + performSearch: function(query, loop) { // Call searchCanceled since it will reset everything we need before doing a new search. this.searchCanceled(); }, - jumpToNextSearchResult: function() + /** + * @param {boolean} loop + * @return {boolean} true iff operation is successful + */ + jumpToNextSearchResult: function(loop) { + return false; }, - jumpToPreviousSearchResult: function() + /** + * @param {boolean} loop + * @return {boolean} true iff operation is successful + */ + jumpToPreviousSearchResult: function(loop) + { + return false; + }, + + /** + * @return {boolean} + */ + canSearchAndReplace: function() + { + return false; + }, + + /** + * @param {string} text + */ + replaceSelectionWith: function(text) + { + }, + + /** + * @param {string} text + */ + replaceAllWith: function(text) { }, diff --git a/Source/WebCore/inspector/front-end/ProfilesPanel.js b/Source/WebCore/inspector/front-end/ProfilesPanel.js index 476a2d152..17c6e5300 100644 --- a/Source/WebCore/inspector/front-end/ProfilesPanel.js +++ b/Source/WebCore/inspector/front-end/ProfilesPanel.js @@ -737,7 +737,11 @@ WebInspector.ProfilesPanel.prototype = { return title; }, - performSearch: function(query) + /** + * @param {string} query + * @param {boolean} loop + */ + performSearch: function(query, loop) { this.searchCanceled(); @@ -812,10 +816,14 @@ WebInspector.ProfilesPanel.prototype = { this._currentSearchChunkIntervalIdentifier = chunkIntervalIdentifier; }, - jumpToNextSearchResult: function() + /** + * @param {boolean} loop + * @return {boolean} + */ + jumpToNextSearchResult: function(loop) { if (!this.showView || !this._searchResults || !this._searchResults.length) - return; + return false; var showFirstResult = false; @@ -838,19 +846,24 @@ WebInspector.ProfilesPanel.prototype = { if (currentView !== this.visibleView) { this.showView(currentView); - WebInspector.searchController.focusSearchField(); + WebInspector.searchController.showSearchField(); } if (showFirstResult) currentView.jumpToFirstSearchResult(); else currentView.jumpToNextSearchResult(); + return true; }, - jumpToPreviousSearchResult: function() + /** + * @param {boolean} loop + * @return {boolean} + */ + jumpToPreviousSearchResult: function(loop) { if (!this.showView || !this._searchResults || !this._searchResults.length) - return; + return false; var showLastResult = false; @@ -873,13 +886,14 @@ WebInspector.ProfilesPanel.prototype = { if (currentView !== this.visibleView) { this.showView(currentView); - WebInspector.searchController.focusSearchField(); + WebInspector.searchController.showSearchField(); } if (showLastResult) currentView.jumpToLastSearchResult(); else currentView.jumpToPreviousSearchResult(); + return true; }, _searchableViews: function() diff --git a/Source/WebCore/inspector/front-end/ResourcesPanel.js b/Source/WebCore/inspector/front-end/ResourcesPanel.js index 7e928cf40..71ff0a56d 100644 --- a/Source/WebCore/inspector/front-end/ResourcesPanel.js +++ b/Source/WebCore/inspector/front-end/ResourcesPanel.js @@ -635,7 +635,11 @@ WebInspector.ResourcesPanel.prototype = { this.storageViewStatusBarItemsContainer.style.left = width + "px"; }, - performSearch: function(query) + /** + * @param {string} query + * @param {boolean} loop + */ + performSearch: function(query, loop) { this._resetSearchResults(); var regex = WebInspector.SourceFrame.createSearchRegex(query); @@ -701,7 +705,7 @@ WebInspector.ResourcesPanel.prototype = { // At first show view for treeElement. if (searchResult.treeElement !== this.sidebarTree.selectedTreeElement) { this.showResource(searchResult.treeElement.representedObject); - WebInspector.searchController.focusSearchField(); + WebInspector.searchController.showSearchField(); } function callback(searchId) @@ -745,22 +749,32 @@ WebInspector.ResourcesPanel.prototype = { this._forAllResourceTreeElements(callback); }, - jumpToNextSearchResult: function() + /** + * @param {boolean} loop + * @return {boolean} + */ + jumpToNextSearchResult: function(loop) { if (!this.currentSearchMatches) - return; + return false; var currentTreeElement = this.sidebarTree.selectedTreeElement; var nextSearchResult = this._searchController.nextSearchResult(currentTreeElement); this._showSearchResult(nextSearchResult); + return true; }, - jumpToPreviousSearchResult: function() + /** + * @param {boolean} loop + * @return {boolean} + */ + jumpToPreviousSearchResult: function(loop) { if (!this.currentSearchMatches) - return; + return false; var currentTreeElement = this.sidebarTree.selectedTreeElement; var previousSearchResult = this._searchController.previousSearchResult(currentTreeElement); this._showSearchResult(previousSearchResult); + return true; }, _forAllResourceTreeElements: function(callback) diff --git a/Source/WebCore/inspector/front-end/ScriptsPanel.js b/Source/WebCore/inspector/front-end/ScriptsPanel.js index a7519247f..c2d8c0000 100644 --- a/Source/WebCore/inspector/front-end/ScriptsPanel.js +++ b/Source/WebCore/inspector/front-end/ScriptsPanel.js @@ -876,7 +876,11 @@ WebInspector.ScriptsPanel.prototype = { delete this._searchQuery; }, - performSearch: function(query) + /** + * @param {string} query + * @param {boolean} loop + */ + performSearch: function(query, loop) { WebInspector.searchController.updateSearchMatchesCount(0, this); @@ -895,49 +899,89 @@ WebInspector.ScriptsPanel.prototype = { return; WebInspector.searchController.updateSearchMatchesCount(searchMatches, this); - view.jumpToNextSearchResult(); + view.jumpToNextSearchResult(loop); WebInspector.searchController.updateCurrentMatchIndex(view.currentSearchResultIndex, this); } this._searchView.performSearch(query, finishedCallback.bind(this)); }, - jumpToNextSearchResult: function() + /** + * @param {boolean} loop + * @return {boolean} + */ + jumpToNextSearchResult: function(loop) { if (!this._searchView) - return; + return false; if (this._searchView !== this.visibleView) { - this.performSearch(this._searchQuery); - return; + this.performSearch(this._searchQuery, loop); + return false; } - if (this._searchView.showingLastSearchResult()) + if (this._searchView.showingLastSearchResult()) { + if (!loop) + return false; this._searchView.jumpToFirstSearchResult(); - else + } else this._searchView.jumpToNextSearchResult(); WebInspector.searchController.updateCurrentMatchIndex(this._searchView.currentSearchResultIndex, this); + return true; }, - jumpToPreviousSearchResult: function() + /** + * @param {boolean} loop + */ + jumpToPreviousSearchResult: function(loop) { if (!this._searchView) - return; + return false; if (this._searchView !== this.visibleView) { - this.performSearch(this._searchQuery); + this.performSearch(this._searchQuery, loop); if (this._searchView) this._searchView.jumpToLastSearchResult(); return; } - if (this._searchView.showingFirstSearchResult()) + if (this._searchView.showingFirstSearchResult()) { + if (!loop) + return false; this._searchView.jumpToLastSearchResult(); - else + } else this._searchView.jumpToPreviousSearchResult(); WebInspector.searchController.updateCurrentMatchIndex(this._searchView.currentSearchResultIndex, this); }, + /** + * @return {boolean} + */ + canSearchAndReplace: function() + { + var view = /** @type {WebInspector.SourceFrame} */ this.visibleView; + return !!view && view.canEditSource(); + }, + + /** + * @param {string} text + */ + replaceSelectionWith: function(text) + { + var view = /** @type {WebInspector.SourceFrame} */ this._searchView; + view.replaceSearchMatchWith(text); + }, + + /** + * @param {string} query + * @param {string} text + */ + replaceAllWith: function(query, text) + { + var view = /** @type {WebInspector.SourceFrame} */ this._searchView; + view.replaceAllWith(query, text); + }, + _toggleFormatSource: function() { this._toggleFormatSourceButton.toggled = !this._toggleFormatSourceButton.toggled; diff --git a/Source/WebCore/inspector/front-end/SearchController.js b/Source/WebCore/inspector/front-end/SearchController.js index 5bfad4cdf..6f4ec797c 100644 --- a/Source/WebCore/inspector/front-end/SearchController.js +++ b/Source/WebCore/inspector/front-end/SearchController.js @@ -42,13 +42,14 @@ WebInspector.SearchController = function() this._searchControlElement = this._element.createChild("div", "toolbar-search-control"); - this._searchInputElement = this._searchControlElement.createChild("input"); - this._searchInputElement.id = "search"; + this._searchInputElement = this._searchControlElement.createChild("input", "search-replace"); + this._searchInputElement.id = "search-input-field"; this._matchesElement = this._searchControlElement.createChild("label", "search-results-matches"); - this._matchesElement.setAttribute("for", "search"); + this._matchesElement.setAttribute("for", "search-input-field"); var searchNavigationElement = this._searchControlElement.createChild("div", "toolbar-search-navigation-controls"); + this._searchNavigationPrevElement = searchNavigationElement.createChild("div", "toolbar-search-navigation toolbar-search-navigation-prev"); this._searchNavigationPrevElement.addEventListener("click", this._onPrevButtonSearch.bind(this), false); this._searchNavigationPrevElement.title = WebInspector.UIString("Search Previous"); @@ -61,6 +62,35 @@ WebInspector.SearchController = function() this._searchInputElement.addEventListener("keydown", this._onKeyDown.bind(this), true); this._searchInputElement.addEventListener("input", this._onInput.bind(this), false); + this._replaceElement = this._element.createChild("span"); + + this._replaceCheckboxElement = this._replaceElement.createChild("input"); + this._replaceCheckboxElement.type = "checkbox"; + this._replaceCheckboxElement.id = "search-replace-trigger"; + this._replaceCheckboxElement.tabIndex = -1; + this._replaceCheckboxElement.addEventListener("click", this._toggleReplaceVisibility.bind(this), false); + + this._replaceLabelElement = this._replaceElement.createChild("label"); + this._replaceLabelElement.textContent = WebInspector.UIString("Replace"); + this._replaceLabelElement.setAttribute("for", "search-replace-trigger"); + + this._replaceDetailsElement = this._replaceElement.createChild("span", "hidden"); + + this._replaceInputElement = this._replaceDetailsElement.createChild("input", "search-replace toolbar-replace-control"); + this._replaceInputElement.addEventListener("keydown", this._onKeyDown.bind(this), true); + + this._replaceButtonElement = this._replaceDetailsElement.createChild("button"); + this._replaceButtonElement.textContent = WebInspector.UIString("Replace"); + this._replaceButtonElement.addEventListener("click", this._replace.bind(this), false); + + this._skipButtonElement = this._replaceDetailsElement.createChild("button"); + this._skipButtonElement.textContent = WebInspector.UIString("Skip"); + this._skipButtonElement.addEventListener("click", this._onNextButtonSearch.bind(this), false); + + this._replaceAllButtonElement = this._replaceDetailsElement.createChild("button"); + this._replaceAllButtonElement.textContent = WebInspector.UIString("Replace All"); + this._replaceAllButtonElement.addEventListener("click", this._replaceAll.bind(this), false); + var closeButtonElement = this._element.createChild("span", "drawer-header-close-button"); closeButtonElement.textContent = WebInspector.UIString("\u00D7"); closeButtonElement.addEventListener("click", this.cancelSearch.bind(this), false); @@ -86,14 +116,18 @@ WebInspector.SearchController.prototype = { cancelSearch: function() { - this._searchInputElement.value = ""; - this._performSearch(""); + if (!this._searchIsVisible) + return; + delete this._searchIsVisible; + this._performSearch("", false, false, false); WebInspector.inspectorView.setFooterElement(null); + this._replaceCheckboxElement.checked = false; + this._toggleReplaceVisibility(); }, disableSearchUntilExplicitAction: function(event) { - this._performSearch(""); + this._performSearch("", false, false, false); }, /** @@ -112,16 +146,15 @@ WebInspector.SearchController.prototype = { var isFindKey = event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey; if (isFindKey) { - this.focusSearchField(); + this.showSearchField(); event.consume(true); return true; } break; - case "F3": if (!isMac) { - this.focusSearchField(); + this.showSearchField(); event.consume(); } break; @@ -143,31 +176,9 @@ WebInspector.SearchController.prototype = { return false; }, - activePanelChanged: function() - { - if (!this._currentQuery) - return; - - var panel = WebInspector.inspectorView.currentPanel(); - if (panel.performSearch) { - function performPanelSearch() - { - this._updateSearchMatchesCountAndCurrentMatchIndex(0, -1); - - panel.currentQuery = this._currentQuery; - panel.performSearch(this._currentQuery); - } - - // Perform the search on a timeout so the panel switches fast. - setTimeout(performPanelSearch.bind(this), 0); - } else { - // Update to show Not found for panels that can't be searched. - this._updateSearchMatchesCountAndCurrentMatchIndex(0, -1); - } - }, - _updateSearchNavigationButtonState: function(enabled) { + var panel = WebInspector.inspectorView.currentPanel(); if (enabled) { this._searchNavigationPrevElement.addStyleClass("enabled"); this._searchNavigationNextElement.addStyleClass("enabled"); @@ -188,11 +199,22 @@ WebInspector.SearchController.prototype = { this._updateSearchNavigationButtonState(matches > 0); }, - focusSearchField: function() + showSearchField: function() { WebInspector.inspectorView.setFooterElement(this._element); + this._updateReplaceVisibility(); this._searchInputElement.focus(); this._searchInputElement.select(); + this._searchIsVisible = true; + }, + + _updateReplaceVisibility: function() + { + var panel = WebInspector.inspectorView.currentPanel(); + if (WebInspector.experimentsSettings.searchReplace.isEnabled() && panel.canSearchAndReplace()) + this._replaceElement.removeStyleClass("hidden"); + else + this._replaceElement.addStyleClass("hidden"); }, _onSearchFieldManualFocus: function(event) @@ -212,34 +234,40 @@ WebInspector.SearchController.prototype = { return false; } - if (isEnterKey(event)) - this._performSearch(event.target.value, true, event.shiftKey); + if (isEnterKey(event)) { + if (event.target === this._searchInputElement) + this._performSearch(event.target.value, true, event.shiftKey, true); + else if (event.target === this._replaceInputElement) + this._replace(); + } }, _onInput: function(event) { - this._performSearch(event.target.value, false, false); + this._performSearch(event.target.value, false, false, true); }, _onNextButtonSearch: function(event) { // Simulate next search on search-navigation-button click. - this._performSearch(this._searchInputElement.value, true, false); + this._performSearch(this._searchInputElement.value, true, false, true); this._searchInputElement.focus(); }, _onPrevButtonSearch: function(event) { // Simulate previous search on search-navigation-button click. - this._performSearch(this._searchInputElement.value, true, true); + this._performSearch(this._searchInputElement.value, true, true, true); this._searchInputElement.focus(); }, /** - * @param {boolean=} forceSearch - * @param {boolean=} isBackwardSearch + * @param {string} query + * @param {boolean} forceSearch + * @param {boolean} isBackwardSearch + * @param {boolean} loop */ - _performSearch: function(query, forceSearch, isBackwardSearch) + _performSearch: function(query, forceSearch, isBackwardSearch, loop) { if (!query || !query.length) { delete this._currentQuery; @@ -260,10 +288,10 @@ WebInspector.SearchController.prototype = { // When this is the same query and a forced search, jump to the next // search result for a good user experience. if (forceSearch) { - if (!isBackwardSearch && currentPanel.jumpToNextSearchResult) - currentPanel.jumpToNextSearchResult(); - else if (isBackwardSearch && currentPanel.jumpToPreviousSearchResult) - currentPanel.jumpToPreviousSearchResult(); + if (!isBackwardSearch) + currentPanel.jumpToNextSearchResult(loop); + else if (isBackwardSearch) + currentPanel.jumpToPreviousSearchResult(loop); } return; } @@ -273,13 +301,32 @@ WebInspector.SearchController.prototype = { this._currentQuery = query; - if (!currentPanel.performSearch) { - this._updateSearchMatchesCountAndCurrentMatchIndex(0, -1); - return; - } - currentPanel.currentQuery = query; - currentPanel.performSearch(query); + currentPanel.performSearch(query, loop); + }, + + _toggleReplaceVisibility: function() + { + if (this._replaceCheckboxElement.checked) { + this._replaceDetailsElement.removeStyleClass("hidden"); + this._replaceInputElement.focus(); + } else + this._replaceDetailsElement.addStyleClass("hidden"); + }, + + _replace: function() + { + var currentPanel = WebInspector.inspectorView.currentPanel(); + currentPanel.replaceSelectionWith(this._replaceInputElement.value); + var query = this._currentQuery; + delete this._currentQuery; + this._performSearch(query, true, false, false); + }, + + _replaceAll: function() + { + var currentPanel = WebInspector.inspectorView.currentPanel(); + currentPanel.replaceAllWith(this._currentQuery, this._replaceInputElement.value); } } diff --git a/Source/WebCore/inspector/front-end/Settings.js b/Source/WebCore/inspector/front-end/Settings.js index a37829daf..ba0b266a2 100644 --- a/Source/WebCore/inspector/front-end/Settings.js +++ b/Source/WebCore/inspector/front-end/Settings.js @@ -187,6 +187,8 @@ WebInspector.ExperimentsSettings = function() this.nativeMemorySnapshots = this._createExperiment("nativeMemorySnapshots", "Native memory profiling"); this.liveNativeMemoryChart = this._createExperiment("liveNativeMemoryChart", "Live native memory chart"); this.fileSystemInspection = this._createExperiment("fileSystemInspection", "FileSystem inspection"); + this.mainThreadMonitoring = this._createExperiment("mainThreadMonitoring", "Show CPU activity in Timeline"); + this.searchReplace = this._createExperiment("searchReplace", "Search / Replace"); this._cleanUpSetting(); } diff --git a/Source/WebCore/inspector/front-end/SourceFrame.js b/Source/WebCore/inspector/front-end/SourceFrame.js index 580012450..a8994f9d7 100644 --- a/Source/WebCore/inspector/front-end/SourceFrame.js +++ b/Source/WebCore/inspector/front-end/SourceFrame.js @@ -56,21 +56,26 @@ WebInspector.SourceFrame = function(contentProvider) this._textEditor.setReadOnly(!this.canEditSource()); } -WebInspector.SourceFrame.createSearchRegex = function(query) +/** + * @param {string} query + * @param {string=} modifiers + */ +WebInspector.SourceFrame.createSearchRegex = function(query, modifiers) { var regex; + modifiers = modifiers || ""; // First try creating regex if user knows the / / hint. try { if (/^\/.*\/$/.test(query)) - regex = new RegExp(query.substring(1, query.length - 1)); + regex = new RegExp(query.substring(1, query.length - 1), modifiers); } catch (e) { // Silent catch. } // Otherwise just do case-insensitive search. if (!regex) - regex = createPlainTextSearchRegex(query, "i"); + regex = createPlainTextSearchRegex(query, "i" + modifiers); return regex; } @@ -265,9 +270,13 @@ WebInspector.SourceFrame.prototype = { this._innerSetSelectionIfNeeded(); }, - beforeTextChanged: function() + /** + * @param {boolean} userInput + */ + beforeTextChanged: function(userInput) { - WebInspector.searchController.cancelSearch(); + if (userInput) + WebInspector.searchController.cancelSearch(); this.clearMessages(); }, @@ -319,6 +328,10 @@ WebInspector.SourceFrame.prototype = { this._textEditor.endUpdates(); }, + /** + * @param {string} query + * @param {function(WebInspector.View, number)} callback + */ performSearch: function(query, callback) { // Call searchCanceled since it will reset everything we need before doing a new search. @@ -331,14 +344,18 @@ WebInspector.SourceFrame.prototype = { var regex = WebInspector.SourceFrame.createSearchRegex(query); this._searchResults = this._collectRegexMatches(regex); + var shiftToIndex = 0; var selection = this._textEditor.lastSelection(); for (var i = 0; selection && i < this._searchResults.length; ++i) { if (this._searchResults[i].compareTo(selection) >= 0) { - this._currentSearchResultIndex = i - 1; + shiftToIndex = i; break; } } + if (shiftToIndex) + this._searchResults = this._searchResults.rotate(shiftToIndex); + callback(this, this._searchResults.length); } @@ -409,6 +426,38 @@ WebInspector.SourceFrame.prototype = { this._textEditor.markAndRevealRange(this._searchResults[this._currentSearchResultIndex]); }, + /** + * @param {string} text + */ + replaceSearchMatchWith: function(text) + { + this.beforeTextChanged(false); + + var range = this._searchResults[this._currentSearchResultIndex]; + if (!range) + return; + this._textEditor.markAndRevealRange(null); + var newRange = this._textModel.editRange(range, text); + this.afterTextChanged(range, newRange); + + // Collapse current match so that we don't replace things twice. + this._textEditor.markAndRevealRange(newRange.collapseToEnd()); + }, + + /** + * @param {string} query + * @param {string} replacement + */ + replaceAllWith: function(query, replacement) + { + this.beforeTextChanged(false); + var text = this._textModel.text(); + var range = this._textModel.range(); + text = text.replace(WebInspector.SourceFrame.createSearchRegex(query, "g"), replacement); + var newRange = this._textModel.editRange(range, text); + this.afterTextChanged(range, newRange); + }, + _collectRegexMatches: function(regexObject) { var ranges = []; @@ -596,7 +645,7 @@ WebInspector.TextEditorDelegateForSourceFrame = function(sourceFrame) WebInspector.TextEditorDelegateForSourceFrame.prototype = { beforeTextChanged: function() { - this._sourceFrame.beforeTextChanged(); + this._sourceFrame.beforeTextChanged(true); }, afterTextChanged: function(oldRange, newRange) @@ -606,7 +655,7 @@ WebInspector.TextEditorDelegateForSourceFrame.prototype = { commitEditing: function() { - this._sourceFrame.commitEditing(this._sourceFrame._textModel.text); + this._sourceFrame.commitEditing(this._sourceFrame._textModel.text()); }, /** diff --git a/Source/WebCore/inspector/front-end/StylesPanel.js b/Source/WebCore/inspector/front-end/StylesPanel.js index 0c00b1534..d3ee08f0b 100644 --- a/Source/WebCore/inspector/front-end/StylesPanel.js +++ b/Source/WebCore/inspector/front-end/StylesPanel.js @@ -201,7 +201,7 @@ WebInspector.StyleSourceFrame.prototype = { afterTextChanged: function(oldRange, newRange) { - this._styleSource.setWorkingCopy(this.textModel.text); + this._styleSource.setWorkingCopy(this.textModel.text()); }, _didEditContent: function(error) diff --git a/Source/WebCore/inspector/front-end/TextEditor.js b/Source/WebCore/inspector/front-end/TextEditor.js index f0b0544b9..9ca824d1e 100644 --- a/Source/WebCore/inspector/front-end/TextEditor.js +++ b/Source/WebCore/inspector/front-end/TextEditor.js @@ -357,7 +357,7 @@ WebInspector.TextEditor.prototype = { this._delegate.commitEditing(); if (this._url && WebInspector.fileManager.isURLSaved(this._url)) - WebInspector.fileManager.save(this._url, this._textModel.text, false); + WebInspector.fileManager.save(this._url, this._textModel.text(), false); return true; }, diff --git a/Source/WebCore/inspector/front-end/TextEditorModel.js b/Source/WebCore/inspector/front-end/TextEditorModel.js index 55205db4c..4ab3c995b 100644 --- a/Source/WebCore/inspector/front-end/TextEditorModel.js +++ b/Source/WebCore/inspector/front-end/TextEditorModel.js @@ -179,12 +179,20 @@ WebInspector.TextEditorModel.prototype = { /** * @return {string} */ - get text() + text: function() { return this._lines.join(this._lineBreak); }, /** + * @return {WebInspector.TextRange} + */ + range: function() + { + return new WebInspector.TextRange(0, 0, this._lines.length - 1, this._lines[this._lines.length - 1].length); + }, + + /** * @return {string} */ get lineBreak() @@ -218,7 +226,7 @@ WebInspector.TextEditorModel.prototype = { setText: function(text) { text = text || ""; - var range = new WebInspector.TextRange(0, 0, this._lines.length - 1, this._lines[this._lines.length - 1].length); + var range = this.range(); this._lineBreak = /\r\n/.test(text) ? "\r\n" : "\n"; var newRange = this._innerSetText(range, text); this.dispatchEventToListeners(WebInspector.TextEditorModel.Events.TextChanged, { oldRange: range, newRange: newRange}); @@ -372,7 +380,7 @@ WebInspector.TextEditorModel.prototype = { copyRange: function(range) { if (!range) - range = new WebInspector.TextRange(0, 0, this._lines.length - 1, this._lines[this._lines.length - 1].length); + range = this.range(); var clip = []; if (range.startLine === range.endLine) { diff --git a/Source/WebCore/inspector/front-end/TimelineGrid.js b/Source/WebCore/inspector/front-end/TimelineGrid.js index 3d4ad7544..a823adef6 100644 --- a/Source/WebCore/inspector/front-end/TimelineGrid.js +++ b/Source/WebCore/inspector/front-end/TimelineGrid.js @@ -67,6 +67,11 @@ WebInspector.TimelineGrid.prototype = { return this._dividersElement; }, + get dividersLabelBarElement() + { + return this._dividersLabelBarElement; + }, + get gridHeaderElement() { return this._gridHeaderElement; diff --git a/Source/WebCore/inspector/front-end/TimelinePanel.js b/Source/WebCore/inspector/front-end/TimelinePanel.js index 0d2358792..360ac113b 100644 --- a/Source/WebCore/inspector/front-end/TimelinePanel.js +++ b/Source/WebCore/inspector/front-end/TimelinePanel.js @@ -120,6 +120,13 @@ WebInspector.TimelinePanel = function() this._timeStampRecords = []; this._expandOffset = 15; + this._headerLineCount = 1; + + this._mainThreadTasks = []; + this._mainThreadMonitoringEnabled = false; + if (WebInspector.experimentsSettings.mainThreadMonitoring.isEnabled()) + this._enableMainThreadMonitoring(); + this._createFileSelector(); this._model.addEventListener(WebInspector.TimelineModel.Events.RecordAdded, this._onTimelineEventRecorded, this); @@ -365,9 +372,11 @@ WebInspector.TimelinePanel.prototype = { if (this._frameContainer) this._frameContainer.removeChildren(); else { + const frameContainerBorderWidth = 1; this._frameContainer = document.createElement("div"); this._frameContainer.addStyleClass("fill"); this._frameContainer.addStyleClass("timeline-frame-container"); + this._frameContainer.style.height = this._headerLineCount * WebInspector.TimelinePanel.rowHeight + frameContainerBorderWidth + "px"; this._frameContainer.addEventListener("dblclick", this._onFrameDoubleClicked.bind(this), false); } @@ -497,9 +506,15 @@ WebInspector.TimelinePanel.prototype = { _innerAddRecordToTimeline: function(record, parentRecord) { + if (record.type === WebInspector.TimelineModel.RecordType.Program) { + this._mainThreadTasks.push({ + startTime: WebInspector.TimelineModel.startTimeInSeconds(record), + endTime: WebInspector.TimelineModel.endTimeInSeconds(record) + }); + } + var records = this._presentationModel.addRecord(record, parentRecord); this._allRecordsCount += records.length; - var recordTypes = WebInspector.TimelineModel.RecordType; var timeStampRecords = this._timeStampRecords; var hasVisibleRecords = false; var presentationModel = this._presentationModel; @@ -560,6 +575,7 @@ WebInspector.TimelinePanel.prototype = { this._closeRecordDetails(); this._allRecordsCount = 0; this._automaticallySizeWindow = true; + this._mainThreadTasks = []; }, elementsToRestoreScrollPositionsFor: function() @@ -618,8 +634,9 @@ WebInspector.TimelinePanel.prototype = { delete this._refreshTimeout; } + this._timelinePaddingLeft = !this._overviewPane.windowLeft() ? this._expandOffset : 0; this._calculator.setWindow(this._overviewPane.windowStartTime(), this._overviewPane.windowEndTime()); - this._calculator.setDisplayWindow(!this._overviewPane.windowLeft() ? this._expandOffset : 0, this._graphRowsElementWidth); + this._calculator.setDisplayWindow(this._timelinePaddingLeft, this._graphRowsElementWidth); var recordsInWindowCount = this._refreshRecords(); this._updateRecordsCounter(recordsInWindowCount); @@ -631,6 +648,8 @@ WebInspector.TimelinePanel.prototype = { } else { this._timelineGrid.updateDividers(this._calculator); } + if (this._mainThreadMonitoringEnabled) + this._refreshMainThreadBars(); } if (this._memoryStatistics.visible()) this._memoryStatistics.refresh(); @@ -676,9 +695,9 @@ WebInspector.TimelinePanel.prototype = { const rowHeight = WebInspector.TimelinePanel.rowHeight; // Convert visible area to visible indexes. Always include top-level record for a visible nested record. - var startIndex = Math.max(0, Math.min(Math.floor(visibleTop / rowHeight) - 1, recordsInWindow.length - 1)); + var startIndex = Math.max(0, Math.min(Math.floor(visibleTop / rowHeight) - this._headerLineCount, recordsInWindow.length - 1)); var endIndex = Math.min(recordsInWindow.length, Math.ceil(visibleBottom / rowHeight)); - var lastVisibleLine = Math.max(0, Math.floor(visibleBottom / rowHeight) - 1); + var lastVisibleLine = Math.max(0, Math.floor(visibleBottom / rowHeight) - this._headerLineCount); if (this._automaticallySizeWindow && recordsInWindow.length > lastVisibleLine) { this._automaticallySizeWindow = false; // If we're at the top, always use real timeline start as a left window bound so that expansion arrow padding logic works. @@ -746,11 +765,103 @@ WebInspector.TimelinePanel.prototype = { this._itemsGraphsElement.insertBefore(this._graphRowsElement, this._bottomGapElement); this._itemsGraphsElement.appendChild(this._expandElements); - this._adjustScrollPosition((recordsInWindow.length + 1) * rowHeight); + this._adjustScrollPosition((recordsInWindow.length + this._headerLineCount) * rowHeight); return recordsInWindow.length; }, + _refreshMainThreadBars: function() + { + const barOffset = 3; + const minGap = 3; + + var minWidth = WebInspector.TimelineCalculator._minWidth; + var widthAdjustment = minWidth / 2; + + var width = this._graphRowsElementWidth; + var boundarySpan = this._overviewPane.windowEndTime() - this._overviewPane.windowStartTime(); + var scale = boundarySpan / (width - minWidth - this._timelinePaddingLeft); + var startTime = this._overviewPane.windowStartTime() - this._timelinePaddingLeft * scale; + var endTime = startTime + width * scale; + + var tasks = this._mainThreadTasks; + if (!tasks.length) + return; + + function compareEndTime(value, task) + { + return value < task.endTime ? -1 : 1; + } + + var taskIndex = insertionIndexForObjectInListSortedByFunction(startTime, tasks, compareEndTime); + if (taskIndex === tasks.length) + return; + + var container = this._cpuBarsElement; + var element = container.firstChild.nextSibling; + var lastElement; + var lastLeft; + var lastRight; + + while (taskIndex < tasks.length) { + var task = tasks[taskIndex]; + if (task.startTime > endTime) + break; + taskIndex++; + + var left = Math.max(0, this._calculator.computePosition(task.startTime) + barOffset - widthAdjustment); + var right = Math.min(width, this._calculator.computePosition(task.endTime) + barOffset + widthAdjustment); + + if (lastElement) { + var gap = Math.floor(left) - Math.ceil(lastRight); + if (gap < minGap) { + lastRight = right; + continue; + } + lastElement.style.width = (lastRight - lastLeft) + "px"; + } + + if (!element) + element = container.createChild("div", "timeline-graph-bar"); + + element.style.left = left + "px"; + lastLeft = left; + lastRight = right; + + lastElement = element; + element = element.nextSibling; + } + + if (lastElement) + lastElement.style.width = (lastRight - lastLeft) + "px"; + + while (element) { + var nextElement = element.nextSibling; + container.removeChild(element); + element = nextElement; + } + }, + + _enableMainThreadMonitoring: function() + { + ++this._headerLineCount; + + var container = this._timelineGrid.gridHeaderElement; + this._cpuBarsElement = container.createChild("div", "timeline-cpu-bars timeline-category-program"); + var cpuBarsLabel = this._cpuBarsElement.createChild("span", "timeline-cpu-bars-label"); + cpuBarsLabel.textContent = WebInspector.UIString("CPU"); + + const headerBorderWidth = 1; + const headerMargin = 2; + + var headerHeight = this._headerLineCount * WebInspector.TimelinePanel.rowHeight; + this.sidebarElement.firstChild.style.height = headerHeight + "px"; + this._timelineGrid.dividersLabelBarElement.style.height = headerHeight + headerMargin + "px"; + this._itemsGraphsElement.style.top = headerHeight + headerBorderWidth + "px"; + + this._mainThreadMonitoringEnabled = true; + }, + _adjustScrollPosition: function(totalHeight) { // Prevent the container from being scrolled off the end. @@ -806,8 +917,8 @@ WebInspector.TimelinePanel.prototype = { var frame = anchor._frame; popover.show(WebInspector.TimelinePresentationModel.generatePopupContentForFrame(frame), anchor); } else { - var record = anchor.row._record; - popover.show(record.generatePopupContent(), anchor); + if (anchor.row && anchor.row._record) + popover.show(anchor.row._record.generatePopupContent(), anchor); } }, diff --git a/Source/WebCore/inspector/front-end/inspector.css b/Source/WebCore/inspector/front-end/inspector.css index 8da534c08..f8faae15b 100644 --- a/Source/WebCore/inspector/front-end/inspector.css +++ b/Source/WebCore/inspector/front-end/inspector.css @@ -263,15 +263,17 @@ body.detached.platform-mac-snowleopard #toolbar-dropdown { border-radius: 5px; } -#search { +.search-replace { -webkit-appearance: none; border: 0; padding: 0 2px; margin: 0; width: 165px; + position: relative; + top: 1px; } -#search:focus { +.search-replace:focus { outline: none; } @@ -280,7 +282,7 @@ body.detached.platform-mac-snowleopard #toolbar-dropdown { top: 0; right: 0; height: 18px; - background-image: -webkit-linear-gradient(rgb(228, 228, 228), rgb(204, 204, 204) 75%, rgb(206, 206, 206)); + background-image: -webkit-linear-gradient(rgb(228, 228, 228), rgb(206, 206, 206)); } .toolbar-search-navigation { @@ -293,45 +295,72 @@ body.detached.platform-mac-snowleopard #toolbar-dropdown { opacity: 0.3; } -.toolbar-search-navigation.enabled:hover { - border-left: 1px solid rgb(190, 190, 190); - opacity: 0.9; +.toolbar-search-navigation.enabled { + opacity: 1.0; } -.toolbar-search-navigation.enabled, .toolbar-search-navigation.enabled:active { - border-left: 1px solid rgb(170, 170, 170); - opacity: 0.7; +.toolbar-search { + line-height: 19px; + height: 22px; } -#search:focus { - outline: none; +.toolbar-search input[type="checkbox"] { + position: relative; + margin-top: -1px; + margin-left: 15px; + top: 2px; } -.toolbar-search { - line-height: 19px; +.toolbar-search button { + border: 1px solid rgb(163, 163, 163); + border-radius: 12px; + margin: 0 0 0 6px; + font-size: 11px; + background-image: -webkit-linear-gradient(rgb(241, 241, 241), rgb(220, 220, 220)); +} + +.toolbar-search button:active { + background-image: -webkit-linear-gradient(rgb(185, 185, 185), rgb(156, 156, 156)); } .toolbar-search-control { display: inline-block; position: relative; background-color: white; - border: 1px solid rgb(202, 202, 202); - margin: 1px 2px; + border: 1px solid rgb(163, 163, 163); + margin: 1px 2px 1px 5px; height: 20px; border-radius: 2px; padding-right: 36px; } +.toolbar-replace-control { + border: 1px solid rgb(163, 163, 163); + height: 20px; + border-radius: 2px; + margin-left: 5px; +} + +.toolbar-search-navigation.enabled:active { + background-position: 4px 7px, 0px 0px; +} + .toolbar-search-navigation.toolbar-search-navigation-prev { background-image: url(Images/searchPrev.png); + border-left: 1px solid rgb(163, 163, 163); +} + +.toolbar-search-navigation.toolbar-search-navigation-prev.enabled:active { + background-image: url(Images/searchPrev.png), -webkit-linear-gradient(rgb(168, 168, 168), rgb(116, 116, 116)); } .toolbar-search-navigation.toolbar-search-navigation-next { background-image: url(Images/searchNext.png); + border-left: 1px solid rgb(230, 230, 230); } -body.compact #search { - font-size: 11px; +.toolbar-search-navigation.toolbar-search-navigation-next.enabled:active { + background-image: url(Images/searchNext.png), -webkit-linear-gradient(rgb(168, 168, 168), rgb(116, 116, 116)); } .search-results-matches { @@ -2514,7 +2543,7 @@ body.platform-mac .search-drawer-header input[type="checkbox"].search-config-che .drawer-header-close-button { font-family: Arial, monospace; - padding: 3px 6px; + padding: 3px 8px; font-size: 14px; color:rgb(80, 80, 80); opacity: 0.5; @@ -2836,5 +2865,6 @@ body.platform-mac #drawer-status-bar .search-status-bar-progress { left: 0; right: 0; font-size: 11px; + height: auto; padding-left: 5px; } diff --git a/Source/WebCore/inspector/front-end/timelinePanel.css b/Source/WebCore/inspector/front-end/timelinePanel.css index 70965bef2..ed80781a9 100644 --- a/Source/WebCore/inspector/front-end/timelinePanel.css +++ b/Source/WebCore/inspector/front-end/timelinePanel.css @@ -595,11 +595,6 @@ border-color: transparent; } -.timeline.timeline-frame-overview .resources-divider { - height: 19px; - bottom: auto; -} - .timeline .resources-event-divider.timeline-frame-divider { background-color: rgba(180, 180, 180, 0.8); border-style: none; @@ -638,3 +633,25 @@ bottom: 0; pointer-events: none; } + +.timeline-cpu-bars { + position: absolute; + top: 19px; + height: 18px; + z-index: 350; + width: 100%; + overflow: hidden; +} + +.timeline-cpu-bars-label { + font-weight: bold; + font-family: monospace; + font-size: 9px; + line-height: 7px; + position: absolute; + top: 5px; + left: 4px; + color: rgb(51, 51, 51); + background-color: rgba(255, 255, 255, 0.75); + z-index: 350; +} diff --git a/Source/WebCore/inspector/front-end/utilities.js b/Source/WebCore/inspector/front-end/utilities.js index 6314e5ac5..01ed7e86c 100644 --- a/Source/WebCore/inspector/front-end/utilities.js +++ b/Source/WebCore/inspector/front-end/utilities.js @@ -232,6 +232,22 @@ Object.defineProperty(Array.prototype, "upperBound", } }); +Object.defineProperty(Array.prototype, "rotate", +{ + /** + * @this {Array.<*>} + * @param {number} index + * @return {Array.<*>} + */ + value: function(index) + { + var result = []; + for (var i = index; i < index + this.length; ++i) + result.push(this[i % this.length]); + return result; + } +}); + Object.defineProperty(Uint32Array.prototype, "sort", { value: Array.prototype.sort }); diff --git a/Source/WebCore/loader/DocumentLoader.cpp b/Source/WebCore/loader/DocumentLoader.cpp index bf6cb9efd..3f493c1ec 100644 --- a/Source/WebCore/loader/DocumentLoader.cpp +++ b/Source/WebCore/loader/DocumentLoader.cpp @@ -47,6 +47,7 @@ #include "InspectorInstrumentation.h" #include "Logging.h" #include "MainResourceLoader.h" +#include "MemoryInstrumentation.h" #include "Page.h" #include "PlatformString.h" #include "Settings.h" @@ -354,6 +355,24 @@ void DocumentLoader::commitData(const char* bytes, size_t length) m_writer.addData(bytes, length); } +void DocumentLoader::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const +{ + MemoryClassInfo<DocumentLoader> info(memoryObjectInfo, this, MemoryInstrumentation::Loader); + info.addInstrumentedMember(m_frame); + info.addInstrumentedMember(m_mainResourceLoader); + info.addInstrumentedHashSet(m_subresourceLoaders); + info.addInstrumentedHashSet(m_multipartSubresourceLoaders); + info.addInstrumentedHashSet(m_plugInStreamLoaders); + info.addString(m_pageTitle.string()); + info.addString(m_overrideEncoding); + info.addVector(m_responses); + info.addHashMap(m_pendingSubstituteResources); + info.addHashSet(m_resourcesClientKnowsAbout); + info.addVector(m_resourcesLoadedFromMemoryCacheForClientNotification); + info.addString(m_clientRedirectSourceForHistory); + info.addInstrumentedMember(m_mainResourceData); +} + bool DocumentLoader::doesProgressiveLoad(const String& MIMEType) const { return !frameLoader()->isReplacing() || MIMEType == "text/html"; diff --git a/Source/WebCore/loader/DocumentLoader.h b/Source/WebCore/loader/DocumentLoader.h index b0b50eafb..94180fd5d 100644 --- a/Source/WebCore/loader/DocumentLoader.h +++ b/Source/WebCore/loader/DocumentLoader.h @@ -55,6 +55,7 @@ namespace WebCore { class Frame; class FrameLoader; class MainResourceLoader; + class MemoryObjectInfo; class Page; class ResourceLoader; class SchedulePair; @@ -242,6 +243,8 @@ namespace WebCore { ApplicationCacheHost* applicationCacheHost() const { return m_applicationCacheHost.get(); } + virtual void reportMemoryUsage(MemoryObjectInfo*) const; + protected: DocumentLoader(const ResourceRequest&, const SubstituteData&); diff --git a/Source/WebCore/loader/EmptyClients.h b/Source/WebCore/loader/EmptyClients.h index a96f26e5f..a17e9493c 100644 --- a/Source/WebCore/loader/EmptyClients.h +++ b/Source/WebCore/loader/EmptyClients.h @@ -128,15 +128,6 @@ public: virtual void resetPagePopupDriver() OVERRIDE { } #endif -#if ENABLE(REGISTER_PROTOCOL_HANDLER) - virtual void registerProtocolHandler(const String&, const String&, const String&, const String&) { } -#endif - -#if ENABLE(CUSTOM_SCHEME_HANDLER) - virtual CustomHandlersState isProtocolHandlerRegistered(const String&, const String&, const String&) { return CustomHandlersDeclined; } - virtual void unregisterProtocolHandler(const String&, const String&, const String&) { } -#endif - virtual void setStatusbarText(const String&) { } virtual KeyboardUIMode keyboardUIMode() { return KeyboardAccessDefault; } @@ -569,14 +560,12 @@ public: virtual void inspectorDestroyed() { } - virtual void openInspectorFrontend(InspectorController*) { } + virtual InspectorFrontendChannel* openInspectorFrontend(InspectorController*) { return 0; } virtual void closeInspectorFrontend() { } virtual void bringFrontendToFront() { } virtual void highlight() { } virtual void hideHighlight() { } - - virtual bool sendMessageToFrontend(const String&) { return false; } }; class EmptyDeviceMotionClient : public DeviceMotionClient { diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp index b640f0854..b76f8c5d8 100644 --- a/Source/WebCore/loader/FrameLoader.cpp +++ b/Source/WebCore/loader/FrameLoader.cpp @@ -77,6 +77,7 @@ #include "Logging.h" #include "MIMETypeRegistry.h" #include "MainResourceLoader.h" +#include "MemoryInstrumentation.h" #include "Page.h" #include "PageCache.h" #include "PageGroup.h" @@ -3220,6 +3221,16 @@ NetworkingContext* FrameLoader::networkingContext() const return m_networkingContext.get(); } +void FrameLoader::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const +{ + MemoryClassInfo<FrameLoader> info(memoryObjectInfo, this, MemoryInstrumentation::Loader); + info.addInstrumentedMember(m_documentLoader.get()); + info.addInstrumentedMember(m_provisionalDocumentLoader.get()); + info.addInstrumentedMember(m_policyDocumentLoader.get()); + info.addString(m_outgoingReferrer); + info.addInstrumentedHashSet(m_openedFrames); +} + bool FrameLoaderClient::hasHTMLView() const { return true; diff --git a/Source/WebCore/loader/FrameLoader.h b/Source/WebCore/loader/FrameLoader.h index 880a5a2a4..e12cf3017 100644 --- a/Source/WebCore/loader/FrameLoader.h +++ b/Source/WebCore/loader/FrameLoader.h @@ -61,6 +61,7 @@ class FormState; class FormSubmission; class FrameLoaderClient; class FrameNetworkingContext; +class MemoryObjectInfo; class NavigationAction; class NetworkingContext; class Page; @@ -283,6 +284,8 @@ public: NetworkingContext* networkingContext() const; + void reportMemoryUsage(MemoryObjectInfo*) const; + private: bool allChildrenAreComplete() const; // immediate children, not all descendants diff --git a/Source/WebCore/loader/ImageLoader.cpp b/Source/WebCore/loader/ImageLoader.cpp index 0e3781cdb..f4d1209f0 100644 --- a/Source/WebCore/loader/ImageLoader.cpp +++ b/Source/WebCore/loader/ImageLoader.cpp @@ -27,11 +27,13 @@ #include "CrossOriginAccessControl.h" #include "Document.h" #include "Element.h" +#include "ElementShadow.h" #include "Event.h" #include "EventSender.h" #include "HTMLNames.h" #include "HTMLObjectElement.h" #include "HTMLParserIdioms.h" +#include "ImageLoaderClient.h" #include "RenderImage.h" #include "ScriptCallStack.h" #include "SecurityOrigin.h" @@ -53,8 +55,8 @@ template<> struct ValueCheck<WebCore::ImageLoader*> { { if (!p) return; - ASSERT(p->element()); - ValueCheck<WebCore::Element*>::checkConsistency(p->element()); + ASSERT(p->client()->imageElement()); + ValueCheck<WebCore::Element*>::checkConsistency(p->client()->imageElement()); } }; @@ -81,8 +83,8 @@ static ImageEventSender& errorEventSender() return sender; } -ImageLoader::ImageLoader(Element* element) - : m_element(element) +ImageLoader::ImageLoader(ImageLoaderClient* client) + : m_client(client) , m_image(0) , m_hasPendingBeforeLoadEvent(false) , m_hasPendingLoadEvent(false) @@ -113,7 +115,12 @@ ImageLoader::~ImageLoader() // If the ImageLoader is being destroyed but it is still protecting its image-loading Element, // remove that protection here. if (m_elementIsProtected) - m_element->deref(); + client()->derefSourceElement(); +} + +inline Document* ImageLoader::document() +{ + return client()->sourceElement()->document(); } void ImageLoader::setImage(CachedImage* newImage) @@ -153,11 +160,10 @@ void ImageLoader::updateFromElement() { // If we're not making renderers for the page, then don't load images. We don't want to slow // down the raw HTML parsing case by loading images we don't intend to display. - Document* document = m_element->document(); - if (!document->renderer()) + if (!document()->renderer()) return; - AtomicString attr = m_element->getAttribute(m_element->imageSourceAttributeName()); + AtomicString attr = client()->sourceElement()->getAttribute(client()->sourceElement()->imageSourceAttributeName()); if (attr == m_failedLoadURL) return; @@ -166,24 +172,24 @@ void ImageLoader::updateFromElement() // an empty string. CachedResourceHandle<CachedImage> newImage = 0; if (!attr.isNull() && !stripLeadingAndTrailingHTMLSpaces(attr).isEmpty()) { - ResourceRequest request = ResourceRequest(document->completeURL(sourceURI(attr))); + ResourceRequest request = ResourceRequest(document()->completeURL(sourceURI(attr))); - String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr); + String crossOriginMode = client()->sourceElement()->fastGetAttribute(HTMLNames::crossoriginAttr); if (!crossOriginMode.isNull()) { StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials; - updateRequestForAccessControl(request, document->securityOrigin(), allowCredentials); + updateRequestForAccessControl(request, document()->securityOrigin(), allowCredentials); } if (m_loadManually) { - bool autoLoadOtherImages = document->cachedResourceLoader()->autoLoadImages(); - document->cachedResourceLoader()->setAutoLoadImages(false); + bool autoLoadOtherImages = document()->cachedResourceLoader()->autoLoadImages(); + document()->cachedResourceLoader()->setAutoLoadImages(false); newImage = new CachedImage(request); newImage->setLoading(true); - newImage->setOwningCachedResourceLoader(document->cachedResourceLoader()); - document->cachedResourceLoader()->m_documentResources.set(newImage->url(), newImage.get()); - document->cachedResourceLoader()->setAutoLoadImages(autoLoadOtherImages); + newImage->setOwningCachedResourceLoader(document()->cachedResourceLoader()); + document()->cachedResourceLoader()->m_documentResources.set(newImage->url(), newImage.get()); + document()->cachedResourceLoader()->setAutoLoadImages(autoLoadOtherImages); } else - newImage = document->cachedResourceLoader()->requestImage(request); + newImage = document()->cachedResourceLoader()->requestImage(request); // If we do not have an image here, it means that a cross-site // violation occurred. @@ -191,7 +197,7 @@ void ImageLoader::updateFromElement() } else if (!attr.isNull()) { // Fire an error event if the url is empty. // FIXME: Should we fire this event asynchronoulsy via errorEventSender()? - m_element->dispatchEvent(Event::create(eventNames().errorEvent, false, false)); + client()->imageElement()->dispatchEvent(Event::create(eventNames().errorEvent, false, false)); } CachedImage* oldImage = m_image.get(); @@ -204,13 +210,13 @@ void ImageLoader::updateFromElement() errorEventSender().cancelEvent(this); m_image = newImage; - m_hasPendingBeforeLoadEvent = !m_element->document()->isImageDocument() && newImage; + m_hasPendingBeforeLoadEvent = !document()->isImageDocument() && newImage; m_hasPendingLoadEvent = newImage; m_imageComplete = !newImage; if (newImage) { - if (!m_element->document()->isImageDocument()) { - if (!m_element->document()->hasListenerType(Document::BEFORELOAD_LISTENER)) + if (!document()->isImageDocument()) { + if (!document()->hasListenerType(Document::BEFORELOAD_LISTENER)) dispatchPendingBeforeLoadEvent(); else beforeLoadEventSender().dispatchEventSoon(this); @@ -253,9 +259,9 @@ void ImageLoader::notifyFinished(CachedResource* resource) if (!m_hasPendingLoadEvent) return; - if (m_element->fastHasAttribute(HTMLNames::crossoriginAttr) - && !m_element->document()->securityOrigin()->canRequest(image()->response().url()) - && !resource->passesAccessControlCheck(m_element->document()->securityOrigin())) { + if (client()->sourceElement()->fastHasAttribute(HTMLNames::crossoriginAttr) + && !document()->securityOrigin()->canRequest(image()->response().url()) + && !resource->passesAccessControlCheck(document()->securityOrigin())) { setImage(0); @@ -263,7 +269,7 @@ void ImageLoader::notifyFinished(CachedResource* resource) errorEventSender().dispatchEventSoon(this); DEFINE_STATIC_LOCAL(String, consoleMessage, ("Cross-origin image load denied by Cross-Origin Resource Sharing policy.")); - m_element->document()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage); + document()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage); ASSERT(!m_hasPendingLoadEvent); return; @@ -282,7 +288,7 @@ void ImageLoader::notifyFinished(CachedResource* resource) RenderImageResource* ImageLoader::renderImageResource() { - RenderObject* renderer = m_element->renderer(); + RenderObject* renderer = client()->imageElement()->renderer(); if (!renderer) return 0; @@ -333,9 +339,9 @@ void ImageLoader::updatedHasPendingLoadEvent() m_elementIsProtected = m_hasPendingLoadEvent; if (m_elementIsProtected) - m_element->ref(); + client()->refSourceElement(); else - m_element->deref(); + client()->derefSourceElement(); } void ImageLoader::dispatchPendingEvent(ImageEventSender* eventSender) @@ -356,10 +362,10 @@ void ImageLoader::dispatchPendingBeforeLoadEvent() return; if (!m_image) return; - if (!m_element->document()->attached()) + if (!document()->attached()) return; m_hasPendingBeforeLoadEvent = false; - if (m_element->dispatchBeforeLoadEvent(m_image->url())) { + if (client()->sourceElement()->dispatchBeforeLoadEvent(m_image->url())) { updateRenderer(); return; } @@ -370,9 +376,9 @@ void ImageLoader::dispatchPendingBeforeLoadEvent() loadEventSender().cancelEvent(this); m_hasPendingLoadEvent = false; - - if (m_element->hasTagName(HTMLNames::objectTag)) - static_cast<HTMLObjectElement*>(m_element)->renderFallbackContent(); + + if (client()->sourceElement()->hasTagName(HTMLNames::objectTag)) + static_cast<HTMLObjectElement*>(client()->sourceElement())->renderFallbackContent(); // Only consider updating the protection ref-count of the Element immediately before returning // from this function as doing so might result in the destruction of this ImageLoader. @@ -385,7 +391,7 @@ void ImageLoader::dispatchPendingLoadEvent() return; if (!m_image) return; - if (!m_element->document()->attached()) + if (!document()->attached()) return; m_hasPendingLoadEvent = false; dispatchLoadEvent(); @@ -399,10 +405,10 @@ void ImageLoader::dispatchPendingErrorEvent() { if (!m_hasPendingErrorEvent) return; - if (!m_element->document()->attached()) + if (!document()->attached()) return; m_hasPendingErrorEvent = false; - m_element->dispatchEvent(Event::create(eventNames().errorEvent, false, false)); + client()->imageElement()->dispatchEvent(Event::create(eventNames().errorEvent, false, false)); } void ImageLoader::dispatchPendingBeforeLoadEvents() diff --git a/Source/WebCore/loader/ImageLoader.h b/Source/WebCore/loader/ImageLoader.h index 943549069..269fa67be 100644 --- a/Source/WebCore/loader/ImageLoader.h +++ b/Source/WebCore/loader/ImageLoader.h @@ -25,12 +25,17 @@ #include "CachedImage.h" #include "CachedResourceHandle.h" +#include "Element.h" +#include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> #include <wtf/text/AtomicString.h> namespace WebCore { class Element; class ImageLoader; +class ImageLoaderClient; +class QualifiedName; class RenderImageResource; template<typename T> class EventSender; @@ -38,9 +43,11 @@ typedef EventSender<ImageLoader> ImageEventSender; class ImageLoader : public CachedImageClient { public: - ImageLoader(Element*); + ImageLoader(ImageLoaderClient*); virtual ~ImageLoader(); + ImageLoaderClient* client() const { return m_client; } + // This function should be called when the element is attached to a document; starts // loading if a load hasn't already been started. void updateFromElement(); @@ -51,7 +58,6 @@ public: void elementDidMoveToNewDocument(); - Element* element() const { return m_element; } bool imageComplete() const { return m_imageComplete; } CachedImage* image() const { return m_image.get(); } @@ -72,6 +78,7 @@ protected: virtual void notifyFinished(CachedResource*); private: + Document* document(); virtual void dispatchLoadEvent() = 0; virtual String sourceURI(const AtomicString&) const = 0; @@ -84,7 +91,7 @@ private: RenderImageResource* renderImageResource(); void updateRenderer(); - Element* m_element; + ImageLoaderClient* m_client; CachedResourceHandle<CachedImage> m_image; AtomicString m_failedLoadURL; bool m_hasPendingBeforeLoadEvent : 1; diff --git a/Source/WebCore/loader/ImageLoaderClient.h b/Source/WebCore/loader/ImageLoaderClient.h new file mode 100644 index 000000000..f08344bb6 --- /dev/null +++ b/Source/WebCore/loader/ImageLoaderClient.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef ImageLoaderClient_h +#define ImageLoaderClient_h + +namespace WebCore { + +class Element; + +class ImageLoaderClient { +public: + virtual ~ImageLoaderClient() { } + + virtual Element* sourceElement() = 0; + virtual Element* imageElement() = 0; + + virtual void refSourceElement() = 0; + virtual void derefSourceElement() = 0; +}; + +template<typename T> +class ImageLoaderClientBase : public ImageLoaderClient { +public: + Element* sourceElement() { return static_cast<T*>(this); } + Element* imageElement() { return static_cast<T*>(this); } + + void refSourceElement() { static_cast<T*>(this)->ref(); } + void derefSourceElement() { static_cast<T*>(this)->deref(); } +}; + +} + +#endif diff --git a/Source/WebCore/loader/ResourceLoader.cpp b/Source/WebCore/loader/ResourceLoader.cpp index 3da77bc47..9315108ae 100644 --- a/Source/WebCore/loader/ResourceLoader.cpp +++ b/Source/WebCore/loader/ResourceLoader.cpp @@ -528,4 +528,17 @@ AsyncFileStream* ResourceLoader::createAsyncFileStream(FileStreamClient* client) } #endif +void ResourceLoader::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const +{ + MemoryClassInfo<ResourceLoader> info(memoryObjectInfo, this, MemoryInstrumentation::Loader); + info.addMember(m_handle.get()); + info.addInstrumentedMember(m_frame); + info.addInstrumentedMember(m_documentLoader); + info.addMember(m_request); + info.addMember(m_originalRequest); + info.addInstrumentedMember(m_resourceData); + info.addMember(m_deferredRequest); + info.addMember(m_options); +} + } diff --git a/Source/WebCore/loader/ResourceLoader.h b/Source/WebCore/loader/ResourceLoader.h index f2ddcccf3..dbf1ab11d 100644 --- a/Source/WebCore/loader/ResourceLoader.h +++ b/Source/WebCore/loader/ResourceLoader.h @@ -44,6 +44,7 @@ namespace WebCore { class Frame; class FrameLoader; class KURL; + class MemoryObjectInfo; class ResourceHandle; class SharedBuffer; @@ -144,6 +145,8 @@ namespace WebCore { void setShouldBufferData(DataBufferingPolicy); + virtual void reportMemoryUsage(MemoryObjectInfo*) const; + protected: ResourceLoader(Frame*, ResourceLoaderOptions); diff --git a/Source/WebCore/page/ChromeClient.h b/Source/WebCore/page/ChromeClient.h index 9e7b59696..da09dc831 100644 --- a/Source/WebCore/page/ChromeClient.h +++ b/Source/WebCore/page/ChromeClient.h @@ -146,21 +146,6 @@ namespace WebCore { virtual void* webView() const = 0; -#if ENABLE(REGISTER_PROTOCOL_HANDLER) - virtual void registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title) = 0; -#endif - -#if ENABLE(CUSTOM_SCHEME_HANDLER) - enum CustomHandlersState { - CustomHandlersNew, - CustomHandlersRegistered, - CustomHandlersDeclined - }; - - virtual CustomHandlersState isProtocolHandlerRegistered(const String& scheme, const String& baseURL, const String& url) = 0; - virtual void unregisterProtocolHandler(const String& scheme, const String& baseURL, const String& url) = 0; -#endif - virtual IntRect windowResizerRect() const = 0; // Methods used by HostWindow. diff --git a/Source/WebCore/page/ContentSecurityPolicy.cpp b/Source/WebCore/page/ContentSecurityPolicy.cpp index 13e85219f..dac65c336 100644 --- a/Source/WebCore/page/ContentSecurityPolicy.cpp +++ b/Source/WebCore/page/ContentSecurityPolicy.cpp @@ -722,7 +722,7 @@ bool CSPDirectiveList::checkInlineAndReportViolation(CSPDirective* directive, co bool CSPDirectiveList::checkNonceAndReportViolation(const String& nonce, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const { - if (m_scriptNonce.isEmpty() || nonce.stripWhiteSpace() == m_scriptNonce) + if (m_scriptNonce.isNull() || (!m_scriptNonce.isEmpty() && nonce.stripWhiteSpace() == m_scriptNonce)) return true; reportViolation(m_scriptNonce, consoleMessage + "\"script-nonce " + m_scriptNonce + "\".\n", KURL(), contextURL, contextLine); return denyIfEnforcingPolicy(); @@ -930,7 +930,7 @@ void CSPDirectiveList::parseReportURI(const String& name, const String& value) void CSPDirectiveList::parseScriptNonce(const String& name, const String& value) { - if (!m_scriptNonce.isEmpty()) { + if (!m_scriptNonce.isNull()) { logDuplicateDirective(name); return; } @@ -943,6 +943,7 @@ void CSPDirectiveList::parseScriptNonce(const String& name, const String& value) const UChar* nonceBegin = position; if (position == end) { logInvalidNonce(String()); + m_scriptNonce = ""; return; } skipWhile<isNotASCIISpace>(position, end); @@ -952,9 +953,10 @@ void CSPDirectiveList::parseScriptNonce(const String& name, const String& value) // Trim off trailing whitespace: If we're not at the end of the string, log // an error. skipWhile<isASCIISpace>(position, end); - if (position < end) + if (position < end) { logInvalidNonce(value); - else + m_scriptNonce = ""; + } else m_scriptNonce = nonce; } diff --git a/Source/WebCore/page/Frame.cpp b/Source/WebCore/page/Frame.cpp index 03a779737..fc3ec9e8a 100644 --- a/Source/WebCore/page/Frame.cpp +++ b/Source/WebCore/page/Frame.cpp @@ -685,6 +685,13 @@ void Frame::dispatchVisibilityStateChangeEvent() } #endif +void Frame::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const +{ + MemoryClassInfo<Frame> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + info.addInstrumentedMember(m_doc.get()); + info.addInstrumentedMember(m_loader); +} + DOMWindow* Frame::domWindow() const { if (!m_domWindow) diff --git a/Source/WebCore/page/Frame.h b/Source/WebCore/page/Frame.h index 77a73d807..46bebd11d 100644 --- a/Source/WebCore/page/Frame.h +++ b/Source/WebCore/page/Frame.h @@ -66,6 +66,7 @@ namespace WebCore { class FrameDestructionObserver; class FrameView; class HTMLTableCellElement; + class MemoryObjectInfo; class RegularExpression; class RenderPart; class TiledBackingStore; @@ -117,6 +118,8 @@ namespace WebCore { void dispatchVisibilityStateChangeEvent(); #endif + void reportMemoryUsage(MemoryObjectInfo*) const; + // ======== All public functions below this point are candidates to move out of Frame into another class. ======== bool inScope(TreeScope*) const; diff --git a/Source/WebCore/page/FrameDestructionObserver.h b/Source/WebCore/page/FrameDestructionObserver.h index 8989e4a9f..094b521f3 100644 --- a/Source/WebCore/page/FrameDestructionObserver.h +++ b/Source/WebCore/page/FrameDestructionObserver.h @@ -26,22 +26,24 @@ #ifndef FrameDestructionObserver_h #define FrameDestructionObserver_h +#include "PlatformExportMacros.h" + namespace WebCore { class Frame; class FrameDestructionObserver { public: - explicit FrameDestructionObserver(Frame*); + WEBCORE_TESTING explicit FrameDestructionObserver(Frame*); - virtual void frameDestroyed(); - virtual void willDetachPage(); + WEBCORE_TESTING virtual void frameDestroyed(); + WEBCORE_TESTING virtual void willDetachPage(); Frame* frame() const { return m_frame; } protected: - virtual ~FrameDestructionObserver(); - void observeFrame(Frame*); + WEBCORE_TESTING virtual ~FrameDestructionObserver(); + WEBCORE_TESTING void observeFrame(Frame*); Frame* m_frame; }; diff --git a/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.cpp b/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.cpp index 7cfb86c0f..99726087c 100644 --- a/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.cpp +++ b/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.cpp @@ -125,9 +125,12 @@ static WebLayer createScrollbarLayer(Scrollbar* scrollbar, WebScrollableLayer sc if (!scrollbarGraphicsLayer->contentsOpaque()) scrollbarGraphicsLayer->setContentsOpaque(isOpaqueRootScrollbar); - // FIXME: Mac scrollbar themes are not thread-safe. + // FIXME: Mac scrollbar themes are not thread-safe to paint. + // FIXME: Win scrollbars on XP Classic themes do not paint valid alpha + // values due to GDI. This needs to be fixed in theme code before it + // can be turned on here. bool platformSupported = true; -#if OS(DARWIN) +#if OS(DARWIN) || OS(WINDOWS) platformSupported = false; #endif diff --git a/Source/WebCore/platform/Decimal.cpp b/Source/WebCore/platform/Decimal.cpp index 3bb6570b5..8a5e275be 100644 --- a/Source/WebCore/platform/Decimal.cpp +++ b/Source/WebCore/platform/Decimal.cpp @@ -246,7 +246,7 @@ Decimal::EncodedData::EncodedData(Sign sign, int exponent, uint64_t coefficient) , m_sign(sign) { if (exponent >= ExponentMin && exponent <= ExponentMax) { - while (coefficient >= MaxCoefficient) { + while (coefficient > MaxCoefficient) { coefficient /= 10; ++exponent; } @@ -967,22 +967,24 @@ String Decimal::toString() const builder.append('-'); int originalExponent = exponent(); - - const int maxDigits = DBL_DIG; uint64_t coefficient = m_data.coefficient(); - uint64_t lastDigit = 0; - while (countDigits(coefficient) > maxDigits) { - lastDigit = coefficient % 10; - coefficient /= 10; - ++originalExponent; - } - if (lastDigit >= 5) - ++coefficient; + if (originalExponent < 0) { + const int maxDigits = DBL_DIG; + uint64_t lastDigit = 0; + while (countDigits(coefficient) > maxDigits) { + lastDigit = coefficient % 10; + coefficient /= 10; + ++originalExponent; + } - while (originalExponent < 0 && coefficient && !(coefficient % 10)) { - coefficient /= 10; - ++originalExponent; + if (lastDigit >= 5) + ++coefficient; + + while (originalExponent < 0 && coefficient && !(coefficient % 10)) { + coefficient /= 10; + ++originalExponent; + } } const String digits = String::number(coefficient); diff --git a/Source/WebCore/platform/DragImage.h b/Source/WebCore/platform/DragImage.h index dd970d293..e78a9d3a8 100644 --- a/Source/WebCore/platform/DragImage.h +++ b/Source/WebCore/platform/DragImage.h @@ -36,7 +36,7 @@ OBJC_CLASS NSImage; #elif PLATFORM(QT) QT_BEGIN_NAMESPACE -class QPixmap; +class QImage; QT_END_NAMESPACE #elif PLATFORM(WIN) typedef struct HBITMAP__* HBITMAP; @@ -62,7 +62,7 @@ namespace WebCore { #if PLATFORM(MAC) typedef RetainPtr<NSImage> DragImageRef; #elif PLATFORM(QT) - typedef QPixmap* DragImageRef; + typedef QImage* DragImageRef; #elif PLATFORM(WIN) typedef HBITMAP DragImageRef; #elif PLATFORM(WX) diff --git a/Source/WebCore/platform/PlatformExportMacros.h b/Source/WebCore/platform/PlatformExportMacros.h index ae3e30a3a..9c264c209 100644 --- a/Source/WebCore/platform/PlatformExportMacros.h +++ b/Source/WebCore/platform/PlatformExportMacros.h @@ -32,11 +32,15 @@ #include <wtf/Platform.h> #include <wtf/ExportMacros.h> +#if defined(BUILDING_WebCore) || defined(BUILDING_WebKit) || \ + defined(STATICALLY_LINKED_WITH_WebCore) || defined(STATICALLY_LINKED_WITH_WebKit) +#define WEBCORE_IS_LINKED_IN_SAME_BINARY 1 +#endif + // See note in wtf/Platform.h for more info on EXPORT_MACROS. #if USE(EXPORT_MACROS) -#if defined(BUILDING_WebCore) || defined(BUILDING_WebKit) || \ - defined(STATICALLY_LINKED_WITH_WebCore) || defined(STATICALLY_LINKED_WITH_WebKit) +#if defined(WEBCORE_IS_LINKED_IN_SAME_BINARY) #define WEBKIT_EXPORTDATA WTF_EXPORT #else #define WEBKIT_EXPORTDATA WTF_IMPORT @@ -46,8 +50,7 @@ #if !PLATFORM(CHROMIUM) && OS(WINDOWS) && !defined(BUILDING_WX__) && !COMPILER(GCC) -#if defined(BUILDING_WebCore) || defined(BUILDING_WebKit) || \ - defined(STATICALLY_LINKED_WITH_WebCore) || defined(STATICALLY_LINKED_WITH_WebKit) +#if defined(WEBCORE_IS_LINKED_IN_SAME_BINARY) #define WEBKIT_EXPORTDATA __declspec(dllexport) #else #define WEBKIT_EXPORTDATA __declspec(dllimport) @@ -61,4 +64,18 @@ #endif // USE(EXPORT_MACROS) +#if USE(EXPORT_MACROS_FOR_TESTING) + +#if defined(WEBCORE_IS_LINKED_IN_SAME_BINARY) +#define WEBCORE_TESTING WTF_EXPORT_DECLARATION +#else +#define WEBCORE_TESTING WTF_IMPORT_DECLARATION +#endif + +#else // USE(EXPORT_MACROS_FOR_TESTING) + +#define WEBCORE_TESTING + +#endif // USE(EXPORT_MACROS_FOR_TESTING) + #endif // PlatformExportMacros_h diff --git a/Source/WebCore/platform/SharedBuffer.cpp b/Source/WebCore/platform/SharedBuffer.cpp index 82efab753..9b8d503bf 100644 --- a/Source/WebCore/platform/SharedBuffer.cpp +++ b/Source/WebCore/platform/SharedBuffer.cpp @@ -27,6 +27,7 @@ #include "config.h" #include "SharedBuffer.h" +#include "MemoryInstrumentation.h" #include "PurgeableBuffer.h" #include <wtf/PassOwnPtr.h> @@ -245,6 +246,16 @@ const Vector<char>& SharedBuffer::buffer() const return m_buffer; } +void SharedBuffer::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const +{ + MemoryClassInfo<SharedBuffer> info(memoryObjectInfo, this, MemoryInstrumentation::Other); + info.addVector(m_buffer); + info.addVector(m_segments); + for (unsigned i = 0; i < m_segments.size(); ++i) + info.addRawBuffer(m_segments[i], segmentSize); + info.addMember(m_purgeableBuffer.get()); +} + unsigned SharedBuffer::getSomeData(const char*& someData, unsigned position) const { unsigned totalSize = size(); diff --git a/Source/WebCore/platform/SharedBuffer.h b/Source/WebCore/platform/SharedBuffer.h index b66a033e5..879e4b285 100644 --- a/Source/WebCore/platform/SharedBuffer.h +++ b/Source/WebCore/platform/SharedBuffer.h @@ -43,6 +43,7 @@ OBJC_CLASS NSData; namespace WebCore { +class MemoryObjectInfo; class PurgeableBuffer; class SharedBuffer : public RefCounted<SharedBuffer> { @@ -114,6 +115,8 @@ public: // } unsigned getSomeData(const char*& data, unsigned position = 0) const; + void reportMemoryUsage(MemoryObjectInfo*) const; + private: SharedBuffer(); SharedBuffer(size_t); diff --git a/Source/WebCore/platform/TreeShared.h b/Source/WebCore/platform/TreeShared.h index 6c4154ede..d4d53eaee 100644 --- a/Source/WebCore/platform/TreeShared.h +++ b/Source/WebCore/platform/TreeShared.h @@ -113,8 +113,8 @@ public: void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::DOM); - memoryObjectInfo->reportInstrumentedPointer(m_parent); + MemoryClassInfo<TreeShared<NodeType, ParentNodeType> > info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + info.addInstrumentedMember(m_parent); } private: diff --git a/Source/WebCore/platform/Widget.h b/Source/WebCore/platform/Widget.h index fbb0020c7..345b321cf 100644 --- a/Source/WebCore/platform/Widget.h +++ b/Source/WebCore/platform/Widget.h @@ -221,10 +221,6 @@ public: void setEvasObject(Evas_Object*); Evas_Object* evasObject() const; - - const String edjeTheme() const; - void setEdjeTheme(const String &); - const String edjeThemeRecursive() const; #endif #if PLATFORM(CHROMIUM) diff --git a/Source/WebCore/platform/chromium/DragImageChromiumMac.cpp b/Source/WebCore/platform/chromium/DragImageChromiumMac.cpp deleted file mode 100644 index e12780f7e..000000000 --- a/Source/WebCore/platform/chromium/DragImageChromiumMac.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2010, Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "DragImage.h" - -#include "Image.h" -#include "NotImplemented.h" -#include <wtf/RetainPtr.h> - -#include <CoreGraphics/CGBitmapContext.h> -#include <CoreGraphics/CGImage.h> - -namespace WebCore { - -IntSize dragImageSize(DragImageRef image) -{ - if (!image) - return IntSize(); - return IntSize(CGImageGetWidth(image), CGImageGetHeight(image)); -} - -void deleteDragImage(DragImageRef image) -{ - CGImageRelease(image); -} - -DragImageRef scaleDragImage(DragImageRef image, FloatSize scale) -{ - if (!image) - return 0; - size_t width = roundf(CGImageGetWidth(image) * scale.width()); - size_t height = roundf(CGImageGetHeight(image) * scale.height()); - - RetainPtr<CGColorSpaceRef> deviceRGB(WTF::AdoptCF, CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); - CGContextRef context = CGBitmapContextCreate(0, width, height, 8, width * 4, deviceRGB.get(), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); - - if (!context) - return 0; - CGContextDrawImage(context, CGRectMake(0, 0, width, height), image); - CGImageRelease(image); - - CGImageRef scaledImage = CGBitmapContextCreateImage(context); - CGContextRelease(context); - return scaledImage; -} - -DragImageRef dissolveDragImageToFraction(DragImageRef image, float delta) -{ - if (!image) - return 0; - size_t width = CGImageGetWidth(image); - size_t height = CGImageGetHeight(image); - - RetainPtr<CGColorSpaceRef> deviceRGB(WTF::AdoptCF, CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); - CGContextRef context = CGBitmapContextCreate(0, width, height, 8, width * 4, deviceRGB.get(), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); - - if (!context) - return 0; - // From CGContext.h: - // The Porter-Duff "source over" mode is called `kCGBlendModeNormal': - // R = S + D*(1 - Sa) - // This is the same as NSCompositeSourceOver, which is what -[NSImage dissolveToPoint:fraction:] uses. - CGContextSetAlpha(context, delta); - CGContextSetBlendMode(context, kCGBlendModeNormal); - CGContextDrawImage(context, CGRectMake(0, 0, width, height), image); - CGImageRelease(image); - - CGImageRef dissolvedImage = CGBitmapContextCreateImage(context); - CGContextRelease(context); - return dissolvedImage; -} - -DragImageRef createDragImageFromImage(Image* image, RespectImageOrientationEnum) -{ - if (!image) - return 0; - return CGImageCreateCopy(image->nativeImageForCurrentFrame()); -} - -DragImageRef createDragImageIconForCachedImage(CachedImage*) -{ - notImplemented(); - return 0; -} - -} // namespace WebCore diff --git a/Source/WebCore/platform/efl/EflScreenUtilities.cpp b/Source/WebCore/platform/efl/EflScreenUtilities.cpp index e7cd1e46d..18dcd1bb0 100644 --- a/Source/WebCore/platform/efl/EflScreenUtilities.cpp +++ b/Source/WebCore/platform/efl/EflScreenUtilities.cpp @@ -149,7 +149,8 @@ bool isUsingEcoreX(const Evas* evas) #ifdef HAVE_ECORE_X Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(evas); const char* engine = ecore_evas_engine_name_get(ecoreEvas); - return !strcmp(engine, "software_x11") + return !strcmp(engine, "opengl_x11") + || !strcmp(engine, "software_x11") || !strcmp(engine, "software_xcb") || !strcmp(engine, "software_16_x11") || !strncmp(engine, "xrender", sizeof("xrender") - 1); diff --git a/Source/WebCore/platform/efl/RenderThemeEfl.cpp b/Source/WebCore/platform/efl/RenderThemeEfl.cpp index 462ee946e..902341aaa 100644 --- a/Source/WebCore/platform/efl/RenderThemeEfl.cpp +++ b/Source/WebCore/platform/efl/RenderThemeEfl.cpp @@ -27,9 +27,6 @@ #include "RenderThemeEfl.h" #include "CSSValueKeywords.h" -#include "FileSystem.h" -#include "Frame.h" -#include "FrameView.h" #include "GraphicsContext.h" #include "HTMLInputElement.h" #include "NotImplemented.h" @@ -103,6 +100,7 @@ bool RenderThemeEfl::themePartCacheEntryReset(struct ThemePartCacheEntry* entry, const char *file, *group; ASSERT(entry); + ASSERT(m_edje); edje_object_file_get(m_edje, &file, 0); group = edjeGroupFromFormType(type); @@ -422,6 +420,15 @@ static void renderThemeEflColorClassFocusRing(void* data, Evas_Object* object, c that->setFocusRingColor(fr, fg, fb, fa); } +void RenderThemeEfl::setThemePath(const String& path) +{ + if (path == m_themePath) + return; + + m_themePath = path; + themeChanged(); +} + void RenderThemeEfl::createCanvas() { ASSERT(!m_canvas); @@ -432,20 +439,17 @@ void RenderThemeEfl::createCanvas() void RenderThemeEfl::createEdje() { ASSERT(!m_edje); - Frame* frame = m_page ? m_page->mainFrame() : 0; - FrameView* view = frame ? frame->view() : 0; - String theme = view ? view->edjeThemeRecursive() : ""; - if (theme.isEmpty()) + if (m_themePath.isEmpty()) EINA_LOG_ERR("No theme defined, unable to set RenderThemeEfl."); else { m_edje = edje_object_add(ecore_evas_get(m_canvas)); if (!m_edje) EINA_LOG_ERR("Could not create base edje object."); - else if (!edje_object_file_set(m_edje, theme.utf8().data(), "webkit/base")) { + else if (!edje_object_file_set(m_edje, m_themePath.utf8().data(), "webkit/base")) { Edje_Load_Error err = edje_object_load_error_get(m_edje); const char* errmsg = edje_load_error_str(err); EINA_LOG_ERR("Could not load 'webkit/base' from theme %s: %s", - theme.utf8().data(), errmsg); + m_themePath.utf8().data(), errmsg); evas_object_del(m_edje); m_edje = 0; } else { @@ -461,7 +465,6 @@ void RenderThemeEfl::createEdje() #undef CONNECT } } - ASSERT(m_edje); } void RenderThemeEfl::applyEdjeColors() @@ -660,8 +663,6 @@ RenderThemeEfl::RenderThemeEfl(Page* page) , m_canvas(0) , m_edje(0) { - if (page && page->mainFrame() && page->mainFrame()->view()) - themeChanged(); } RenderThemeEfl::~RenderThemeEfl() diff --git a/Source/WebCore/platform/efl/RenderThemeEfl.h b/Source/WebCore/platform/efl/RenderThemeEfl.h index c2e47d0cc..bbcb4e314 100644 --- a/Source/WebCore/platform/efl/RenderThemeEfl.h +++ b/Source/WebCore/platform/efl/RenderThemeEfl.h @@ -196,6 +196,8 @@ public: virtual bool paintMediaCurrentTime(RenderObject*, const PaintInfo&, const IntRect&); #endif + void setThemePath(const String&); + String themePath() { return m_themePath; } protected: static float defaultFontSize; @@ -225,6 +227,8 @@ private: Color m_mediaPanelColor; Color m_mediaSliderColor; #endif + + String m_themePath; Ecore_Evas* m_canvas; Evas_Object* m_edje; diff --git a/Source/WebCore/platform/efl/ScrollbarEfl.cpp b/Source/WebCore/platform/efl/ScrollbarEfl.cpp index 65dd68d46..ce7f7bf4b 100644 --- a/Source/WebCore/platform/efl/ScrollbarEfl.cpp +++ b/Source/WebCore/platform/efl/ScrollbarEfl.cpp @@ -23,13 +23,13 @@ #include "config.h" #include "ScrollbarEfl.h" -#include "ChromeClient.h" #include "Frame.h" #include "FrameView.h" #include "GraphicsContext.h" #include "HostWindow.h" #include "IntRect.h" #include "Page.h" +#include "RenderThemeEfl.h" #include "ScrollbarTheme.h" #include "Settings.h" @@ -112,9 +112,17 @@ void ScrollbarEfl::setParent(ScrollView* view) return; } + Frame* frame = static_cast<FrameView*>(view)->frame(); + if (!frame) + return; + + Page* page = frame->page(); + if (!page) + return; + const char* group = (orientation() == HorizontalScrollbar) ? "scrollbar.horizontal" : "scrollbar.vertical"; - String theme(edjeThemeRecursive()); + String theme = static_cast<RenderThemeEfl*>(page->theme())->themePath(); if (theme.isEmpty()) { EINA_LOG_ERR("Could not load theme '%s': no theme path set.", group); diff --git a/Source/WebCore/platform/efl/WidgetEfl.cpp b/Source/WebCore/platform/efl/WidgetEfl.cpp index 138bdfa30..8f8f2e7b7 100644 --- a/Source/WebCore/platform/efl/WidgetEfl.cpp +++ b/Source/WebCore/platform/efl/WidgetEfl.cpp @@ -51,7 +51,6 @@ class WidgetPrivate { public: Evas* m_evas; Evas_Object* m_evasObject; - String m_theme; WidgetPrivate() : m_evas(0) @@ -145,29 +144,6 @@ void Widget::setIsSelected(bool) notImplemented(); } -const String Widget::edjeTheme() const -{ - return m_data->m_theme; -} - -void Widget::setEdjeTheme(const String& themePath) -{ - if (m_data->m_theme == themePath) - return; - - m_data->m_theme = themePath; -} - -const String Widget::edjeThemeRecursive() const -{ - if (!m_data->m_theme.isNull()) - return m_data->m_theme; - if (m_parent) - return m_parent->edjeThemeRecursive(); - - return String(); -} - Evas* Widget::evas() const { return m_data->m_evas; diff --git a/Source/WebCore/platform/graphics/FontPlatformData.h b/Source/WebCore/platform/graphics/FontPlatformData.h index 63a91a424..8b0dbed9b 100644 --- a/Source/WebCore/platform/graphics/FontPlatformData.h +++ b/Source/WebCore/platform/graphics/FontPlatformData.h @@ -72,7 +72,7 @@ typedef const struct __CTFont* CTFontRef; #if PLATFORM(CHROMIUM) && OS(DARWIN) #include "CrossProcessFontLoading.h" -#include "HarfBuzzFace.h" +#include "HarfBuzzNGFace.h" #endif #if PLATFORM(WIN) @@ -257,7 +257,7 @@ public: #endif #if PLATFORM(CHROMIUM) && OS(DARWIN) - HarfBuzzFace* harfbuzzFace(); + HarfBuzzNGFace* harfbuzzFace(); #endif unsigned hash() const @@ -363,7 +363,7 @@ private: #if PLATFORM(CHROMIUM) && OS(DARWIN) RefPtr<MemoryActivatedFont> m_inMemoryFont; - RefPtr<HarfBuzzFace> m_harfbuzzFace; + RefPtr<HarfBuzzNGFace> m_harfbuzzFace; #endif bool m_isColorBitmapFont; diff --git a/Source/WebCore/platform/graphics/GeneratorGeneratedImage.cpp b/Source/WebCore/platform/graphics/GeneratorGeneratedImage.cpp index 1caf853b1..e64d16a9c 100644 --- a/Source/WebCore/platform/graphics/GeneratorGeneratedImage.cpp +++ b/Source/WebCore/platform/graphics/GeneratorGeneratedImage.cpp @@ -32,25 +32,16 @@ namespace WebCore { -void GeneratorGeneratedImage::draw(GraphicsContext* destContext, const FloatRect& destRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp) +void GeneratorGeneratedImage::draw(GraphicsContext* destContext, const FloatRect& destRect, const FloatRect& srcRect, ColorSpace, CompositeOperator compositeOp) { - unsigned generatorHash = m_generator->hash(); - if (!m_cachedImageBuffer || m_cachedGeneratorHash != generatorHash || m_cachedAdjustedSize != m_size || !destContext->isCompatibleWithBuffer(m_cachedImageBuffer.get())) { - // Create a BitmapImage and call draw on it. - m_cachedImageBuffer = destContext->createCompatibleBuffer(m_size); - if (!m_cachedImageBuffer) - return; - - // Fill with the generated image. - m_cachedImageBuffer->context()->fillRect(FloatRect(FloatPoint(), m_size), *m_generator); - - m_cachedGeneratorHash = generatorHash; - m_cachedAdjustedSize = m_size; - } - - // Draw the image buffer to the destination - m_cachedImageBuffer->draw(destContext, styleColorSpace, destRect, srcRect, compositeOp); - m_cacheTimer.restart(); + GraphicsContextStateSaver stateSaver(*destContext); + destContext->setCompositeOperation(compositeOp); + destContext->clip(destRect); + destContext->translate(destRect.x(), destRect.y()); + if (destRect.size() != srcRect.size()) + destContext->scale(FloatSize(destRect.width() / srcRect.width(), destRect.height() / srcRect.height())); + destContext->translate(-srcRect.x(), -srcRect.y()); + destContext->fillRect(FloatRect(FloatPoint(), m_size), *m_generator.get()); } void GeneratorGeneratedImage::drawPattern(GraphicsContext* destContext, const FloatRect& srcRect, const AffineTransform& patternTransform, diff --git a/Source/WebCore/platform/graphics/GraphicsContext.h b/Source/WebCore/platform/graphics/GraphicsContext.h index f27bec7cb..a2e083924 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext.h +++ b/Source/WebCore/platform/graphics/GraphicsContext.h @@ -501,7 +501,7 @@ namespace WebCore { #endif #if PLATFORM(QT) - void pushTransparencyLayerInternal(const QRect &rect, qreal opacity, QPixmap& alphaMask); + void pushTransparencyLayerInternal(const QRect&, qreal, QImage&); void takeOwnershipOfPlatformContext(); #endif diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.h b/Source/WebCore/platform/graphics/GraphicsContext3D.h index 1e6184293..c2feec293 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext3D.h +++ b/Source/WebCore/platform/graphics/GraphicsContext3D.h @@ -931,6 +931,11 @@ public: void readPixelsAndConvertToBGRAIfNecessary(int x, int y, int width, int height, unsigned char* pixels); #endif +#if PLATFORM(BLACKBERRY) + void logFrameBufferStatus(int line); + void readPixelsIMG(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data); +#endif + bool reshapeFBOs(const IntSize&); void resolveMultisamplingIfNecessary(const IntRect& = IntRect()); #if PLATFORM(QT) && USE(GRAPHICS_SURFACE) @@ -943,6 +948,11 @@ public: #if PLATFORM(MAC) CGLContextObj m_contextObj; RetainPtr<WebGLLayer> m_webGLLayer; +#elif PLATFORM(BLACKBERRY) +#if USE(ACCELERATED_COMPOSITING) + RefPtr<PlatformLayer> m_compositingLayer; +#endif + void* m_context; #endif #if PLATFORM(MAC) || PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL) || PLATFORM(BLACKBERRY) @@ -996,9 +1006,14 @@ public: // Errors raised by synthesizeGLError(). ListHashSet<GC3Denum> m_syntheticErrors; +#if PLATFORM(BLACKBERRY) + bool m_isImaginationHardware; +#endif + +#if !PLATFORM(BLACKBERRY) friend class GraphicsContext3DPrivate; OwnPtr<GraphicsContext3DPrivate> m_private; - +#endif bool systemAllowsMultisamplingOnATICards() const; }; diff --git a/Source/WebCore/platform/graphics/Image.h b/Source/WebCore/platform/graphics/Image.h index a6b949047..ba953f5e0 100644 --- a/Source/WebCore/platform/graphics/Image.h +++ b/Source/WebCore/platform/graphics/Image.h @@ -52,10 +52,6 @@ typedef SIZE* LPSIZE; typedef struct HBITMAP__ *HBITMAP; #endif -#if PLATFORM(QT) -#include <QPixmap> -#endif - #if PLATFORM(GTK) typedef struct _GdkPixbuf GdkPixbuf; #endif @@ -157,7 +153,7 @@ public: #endif #if PLATFORM(QT) - static void setPlatformResource(const char* name, const QPixmap&); + static void setPlatformResource(const char* name, const QImage&); #endif virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform, diff --git a/Source/WebCore/platform/graphics/ImageSource.h b/Source/WebCore/platform/graphics/ImageSource.h index ed625bc66..913a3e7dc 100644 --- a/Source/WebCore/platform/graphics/ImageSource.h +++ b/Source/WebCore/platform/graphics/ImageSource.h @@ -43,7 +43,7 @@ typedef const struct __CFData* CFDataRef; #elif PLATFORM(QT) #include <qglobal.h> QT_BEGIN_NAMESPACE -class QPixmap; +class QImage; QT_END_NAMESPACE #elif USE(CAIRO) #include "NativeImageCairo.h" @@ -90,7 +90,7 @@ class ImageDecoder; typedef ImageDecoder* NativeImageSourcePtr; typedef void* NativeImagePtr; #elif PLATFORM(QT) -typedef QPixmap* NativeImagePtr; +typedef QImage* NativeImagePtr; #endif #endif diff --git a/Source/WebCore/platform/graphics/blackberry/GraphicsContext3DBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/GraphicsContext3DBlackBerry.cpp index a1f625696..dd4e3f4c8 100644 --- a/Source/WebCore/platform/graphics/blackberry/GraphicsContext3DBlackBerry.cpp +++ b/Source/WebCore/platform/graphics/blackberry/GraphicsContext3DBlackBerry.cpp @@ -31,11 +31,13 @@ #include "GraphicsContext3D.h" #include "BitmapImageSingleFrameSkia.h" -#include "Extensions3DOpenGL.h" +#include "Extensions3DOpenGLES.h" #include "GraphicsContext.h" +#include "OpenGLESShims.h" #include "WebGLLayerWebKitThread.h" #include <BlackBerryPlatformGraphics.h> +#include <BlackBerryPlatformLog.h> namespace WebCore { @@ -48,22 +50,21 @@ PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(Attributes attribs, Host return adoptRef(new GraphicsContext3D(attribs, hostWindow, false)); } -GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, bool renderDirectlyToHostWindow) +GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWindow*, bool renderDirectlyToHostWindow) : m_currentWidth(0) , m_currentHeight(0) - , m_hostWindow(hostWindow) , m_context(BlackBerry::Platform::Graphics::createWebGLContext()) - , m_extensions(adoptPtr(new Extensions3DOpenGL(this))) + , m_extensions(adoptPtr(new Extensions3DOpenGLES(this))) , m_attrs(attrs) , m_texture(0) , m_fbo(0) , m_depthStencilBuffer(0) + , m_layerComposited(false) + , m_internalColorFormat(GL_RGBA) , m_boundFBO(0) , m_activeTexture(GL_TEXTURE0) , m_boundTexture0(0) - , m_multisampleFBO(0) - , m_multisampleDepthStencilBuffer(0) - , m_multisampleColorBuffer(0) + , m_isImaginationHardware(0) { if (!renderDirectlyToHostWindow) { #if USE(ACCELERATED_COMPOSITING) @@ -71,10 +72,6 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWi #endif makeContextCurrent(); - Extensions3D* extensions = getExtensions(); - if (!extensions->supports("GL_IMG_multisampled_render_to_texture")) - m_attrs.antialias = false; - // Create a texture to render into. ::glGenTextures(1, &m_texture); ::glBindTexture(GL_TEXTURE_2D, m_texture); @@ -96,11 +93,28 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWi #endif } - // FIXME: If GraphicsContext3D is created with renderDirectlyToHostWindow == true, - // makeContextCurrent() will make the shared context current. makeContextCurrent(); - // FIXME: Do we need to enable GL_VERTEX_PROGRAM_POINT_SIZE with GL ES2? See PR #120141. + const char* renderer = reinterpret_cast<const char*>(::glGetString(GL_RENDERER)); + m_isImaginationHardware = std::strstr(renderer, "PowerVR SGX"); + + // ANGLE initialization. + ShBuiltInResources ANGLEResources; + ShInitBuiltInResources(&ANGLEResources); + + getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &ANGLEResources.MaxVertexAttribs); + getIntegerv(GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS, &ANGLEResources.MaxVertexUniformVectors); + getIntegerv(GraphicsContext3D::MAX_VARYING_VECTORS, &ANGLEResources.MaxVaryingVectors); + getIntegerv(GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxVertexTextureImageUnits); + getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxCombinedTextureImageUnits); + getIntegerv(GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxTextureImageUnits); + getIntegerv(GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS, &ANGLEResources.MaxFragmentUniformVectors); + + ANGLEResources.MaxDrawBuffers = 1; // Always set to 1 for OpenGL ES. + ANGLEResources.OES_standard_derivatives = m_extensions->supports("GL_OES_standard_derivatives"); + ANGLEResources.OES_EGL_image_external = m_extensions->supports("GL_EGL_image_external"); + ANGLEResources.ARB_texture_rectangle = m_extensions->supports("GL_ARB_texture_rectangle"); + m_compiler.setResources(ANGLEResources); ::glClearColor(0, 0, 0, 0); } @@ -118,9 +132,187 @@ GraphicsContext3D::~GraphicsContext3D() BlackBerry::Platform::Graphics::destroyWebGLContext(m_context); } +bool GraphicsContext3D::reshapeFBOs(const IntSize& size) +{ + // A BlackBerry-specific implementation of reshapeFBOs is necessary because it contains: + // - an Imagination-specific implementation of anti-aliasing + // - an Imagination-specific fix for FBOs of size less than (16,16) + + int fboWidth = size.width(); + int fboHeight = size.height(); + + // Imagination-specific fix + if (m_isImaginationHardware) { + fboWidth = std::max(fboWidth, 16); + fboHeight = std::max(fboHeight, 16); + } + + GLuint internalColorFormat, colorFormat, internalDepthStencilFormat = 0; + if (m_attrs.alpha) { + internalColorFormat = GL_RGBA; + colorFormat = GL_RGBA; + } else { + internalColorFormat = GL_RGB; + colorFormat = GL_RGB; + } + if (m_attrs.stencil || m_attrs.depth) { + // We don't allow the logic where stencil is required and depth is not. + // See GraphicsContext3D constructor. + if (m_attrs.stencil && m_attrs.depth) + internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT; + else + internalDepthStencilFormat = GL_DEPTH_COMPONENT16; + } + + GLint sampleCount = 8; + if (m_attrs.antialias) { + GLint maxSampleCount; + // Hardcode the maximum number of samples due to header issue (PR132183) + // ::glGetIntegerv(GL_MAX_SAMPLES_IMG, &maxSampleCount); + maxSampleCount = 4; + sampleCount = std::min(8, maxSampleCount); + } + + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); + + ::glBindTexture(GL_TEXTURE_2D, m_texture); + ::glTexImage2D(GL_TEXTURE_2D, 0, internalColorFormat, fboWidth, fboHeight, 0, colorFormat, GL_UNSIGNED_BYTE, 0); + + Extensions3D* extensions = getExtensions(); + if (m_attrs.antialias) { + extensions->framebufferTexture2DMultisampleIMG(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0, sampleCount); + + if (m_attrs.stencil || m_attrs.depth) { + ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer); + extensions->renderbufferStorageMultisampleIMG(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, fboWidth, fboHeight); + + if (m_attrs.stencil) + ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); + if (m_attrs.depth) + ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); + ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + } + } else { + ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0); + + if (m_attrs.stencil || m_attrs.depth) { + ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer); + ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, fboWidth, fboHeight); + + if (m_attrs.stencil) + ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); + if (m_attrs.depth) + ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); + ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + } + } + ::glBindTexture(GL_TEXTURE_2D, 0); + + + logFrameBufferStatus(__LINE__); + + return true; +} + +void GraphicsContext3D::logFrameBufferStatus(int line) +{ + BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "Checking FrameBuffer status at line %d: ", line); + switch (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)) { + case GL_FRAMEBUFFER_COMPLETE: + BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "COMPLETE | "); + break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "INCOMPLETE ATTACHMENT | "); + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "MISSING ATTACHMENT | "); + break; + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: + BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "INCOMPLETE DIMENSIONS | "); + break; + case GL_FRAMEBUFFER_UNSUPPORTED: + BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "UNSUPPORTED | "); + break; + case FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: + BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "INCOMPLETE MULTISAMPLE | "); + break; + } + + switch (glGetError()) { + case GL_NO_ERROR: + BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "NO ERROR"); + break; + case GL_INVALID_ENUM: + BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "INVALID ENUM"); + break; + case GL_INVALID_VALUE: + BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "INVALID VALUE"); + break; + case GL_INVALID_OPERATION: + BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "INVALID OPERATION"); + break; + case GL_OUT_OF_MEMORY: + BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "OUT OF MEMORY"); + break; + } + BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "\n"); +} + +void GraphicsContext3D::readPixelsIMG(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data) +{ + // Currently only format=RGBA, type=UNSIGNED_BYTE is supported by the specification: http://www.khronos.org/registry/webgl/specs/latest/ + // If this ever changes, this code will need to be updated. + + // Calculate the strides of our data and canvas + unsigned int formatSize = 4; // RGBA UNSIGNED_BYTE + unsigned int dataStride = width * formatSize; + unsigned int canvasStride = m_currentWidth * formatSize; + + // If we are using a pack alignment of 8, then we need to align our strides to 8 byte boundaries + // See: http://en.wikipedia.org/wiki/Data_structure_alignment (computing padding) + int packAlignment; + glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment); + if (8 == packAlignment) { + dataStride = (dataStride + 7) & ~7; + canvasStride = (canvasStride + 7) & ~7; + } + + unsigned char* canvasData = new unsigned char[canvasStride * m_currentHeight]; + ::glReadPixels(0, 0, m_currentWidth, m_currentHeight, format, type, canvasData); + + // If we failed to read our canvas data due to a GL error, don't continue + int error = glGetError(); + if (GL_NO_ERROR != error) { + synthesizeGLError(error); + return; + } + + // Clear our data in case some of it lies outside the bounds of our canvas + // TODO: don't do this if all of the data lies inside the bounds of the canvas + memset(data, 0, dataStride * height); + + // Calculate the intersection of our canvas and data bounds + IntRect dataRect(x, y, width, height); + IntRect canvasRect(0, 0, m_currentWidth, m_currentHeight); + IntRect nonZeroDataRect = intersection(dataRect, canvasRect); + + unsigned int xDataOffset = x < 0 ? -x * formatSize : 0; + unsigned int yDataOffset = y < 0 ? -y * dataStride : 0; + unsigned int xCanvasOffset = nonZeroDataRect.x() * formatSize; + unsigned int yCanvasOffset = nonZeroDataRect.y() * canvasStride; + unsigned char* dst = static_cast<unsigned char*>(data) + xDataOffset + yDataOffset; + unsigned char* src = canvasData + xCanvasOffset + yCanvasOffset; + for (int row = 0; row < nonZeroDataRect.height(); row++) { + memcpy(dst, src, nonZeroDataRect.width() * formatSize); + dst += dataStride; + src += canvasStride; + } + + delete [] canvasData; +} + bool GraphicsContext3D::paintsIntoCanvasBuffer() const { - // See PR #120141. return true; } @@ -147,7 +339,12 @@ bool GraphicsContext3D::isErrorGeneratedOnOutOfBoundsAccesses() const Platform3DObject GraphicsContext3D::platformTexture() const { - return m_texture; + return m_compositingLayer->getTextureID(); +} + +PlatformGraphicsContext3D GraphicsContext3D::platformGraphicsContext3D() const +{ + return m_context; } #if USE(ACCELERATED_COMPOSITING) @@ -196,7 +393,7 @@ void GraphicsContext3D::paintToCanvas(const unsigned char* imagePixels, int imag FloatRect dst(0, 0, imageWidth, imageHeight); RefPtr<BitmapImageSingleFrameSkia> bitmapImage = BitmapImageSingleFrameSkia::create(canvasBitmap, false); - context->drawImage(bitmapImage.get(), ColorSpaceDeviceRGB, dst, src, CompositeCopy, DoNotRespectImageOrientation, false); + context->drawImage(bitmapImage.get(), ColorSpaceDeviceRGB, dst, src, CompositeCopy, RespectImageOrientation, false); } void GraphicsContext3D::setContextLostCallback(PassOwnPtr<ContextLostCallback>) diff --git a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp index 4ae8db39c..03203bf1c 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp @@ -87,7 +87,7 @@ LayerChromium::LayerChromium() , m_replicaLayer(0) , m_drawOpacity(0) , m_drawOpacityIsAnimating(false) - , m_targetRenderSurface(0) + , m_renderTarget(0) , m_drawTransformIsAnimating(false) , m_screenSpaceTransformIsAnimating(false) , m_contentsScale(1.0) @@ -629,7 +629,7 @@ void LayerChromium::createRenderSurface() { ASSERT(!m_renderSurface); m_renderSurface = adoptPtr(new RenderSurfaceChromium(this)); - setTargetRenderSurface(m_renderSurface.get()); + setRenderTarget(this); } bool LayerChromium::descendantDrawsContent() diff --git a/Source/WebCore/platform/graphics/chromium/LayerChromium.h b/Source/WebCore/platform/graphics/chromium/LayerChromium.h index 40668f556..83058e633 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.h @@ -129,12 +129,12 @@ public: bool opacityIsAnimating() const; void setFilters(const WebKit::WebFilterOperations&); - const WebKit::WebFilterOperations& filters() { return m_filters; } + const WebKit::WebFilterOperations& filters() const { return m_filters; } // Background filters are filters applied to what is behind this layer, when they are viewed through non-opaque // regions in this layer. They are used through the WebLayer interface, and are not exposed to HTML. void setBackgroundFilters(const WebKit::WebFilterOperations&); - const WebKit::WebFilterOperations& backgroundFilters() { return m_backgroundFilters; } + const WebKit::WebFilterOperations& backgroundFilters() const { return m_backgroundFilters; } virtual void setOpaque(bool); bool opaque() const { return m_opaque; } @@ -208,6 +208,10 @@ public: void setReplicaLayer(LayerChromium*); LayerChromium* replicaLayer() const { return m_replicaLayer.get(); } + bool hasMask() const { return m_maskLayer; } + bool hasReplica() const { return m_replicaLayer; } + bool replicaHasMask() const { return m_replicaLayer && (m_maskLayer || m_replicaLayer->m_maskLayer); } + // These methods typically need to be overwritten by derived classes. virtual bool drawsContent() const { return m_isDrawable; } virtual void update(CCTextureUpdater&, const CCOcclusionTracker*) { } @@ -234,8 +238,8 @@ public: const IntRect& clipRect() const { return m_clipRect; } void setClipRect(const IntRect& clipRect) { m_clipRect = clipRect; } - RenderSurfaceChromium* targetRenderSurface() const { return m_targetRenderSurface; } - void setTargetRenderSurface(RenderSurfaceChromium* surface) { m_targetRenderSurface = surface; } + LayerChromium* renderTarget() const { ASSERT(!m_renderTarget || m_renderTarget->renderSurface()); return m_renderTarget; } + void setRenderTarget(LayerChromium* target) { m_renderTarget = target; } bool drawTransformIsAnimating() const { return m_drawTransformIsAnimating; } void setDrawTransformIsAnimating(bool animating) { m_drawTransformIsAnimating = animating; } @@ -348,7 +352,7 @@ private: // During drawing, identifies the region outside of which nothing should be drawn. // Currently this is set to layer's clipRect if usesLayerClipping is true, otherwise - // it's targetRenderSurface's contentRect. + // it's renderTarget's RenderSurface contentRect. // Uses target surface's space. IntRect m_scissorRect; IntPoint m_scrollPosition; @@ -395,7 +399,7 @@ private: // Uses target surface space. IntRect m_clipRect; - RenderSurfaceChromium* m_targetRenderSurface; + LayerChromium* m_renderTarget; WebKit::WebTransformationMatrix m_drawTransform; WebKit::WebTransformationMatrix m_screenSpaceTransform; bool m_drawTransformIsAnimating; diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp index fb2dd8bc6..f7aebeee8 100644 --- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp @@ -40,8 +40,6 @@ namespace WebCore { RenderSurfaceChromium::RenderSurfaceChromium(LayerChromium* owningLayer) : m_owningLayer(owningLayer) - , m_maskLayer(0) - , m_skipsDraw(false) , m_drawOpacity(1) , m_drawOpacityIsAnimating(false) , m_targetSurfaceTransformsAreAnimating(false) @@ -65,29 +63,6 @@ FloatRect RenderSurfaceChromium::drawableContentRect() const return drawableContentRect; } -RenderSurfaceChromium* RenderSurfaceChromium::targetRenderSurface() const -{ - LayerChromium* parent = m_owningLayer->parent(); - if (!parent) - return 0; - return parent->targetRenderSurface(); -} - -bool RenderSurfaceChromium::hasReplica() const -{ - return m_owningLayer->replicaLayer(); -} - -bool RenderSurfaceChromium::hasMask() const -{ - return m_maskLayer; -} - -bool RenderSurfaceChromium::replicaHasMask() const -{ - return hasReplica() && (m_maskLayer || m_owningLayer->replicaLayer()->maskLayer()); -} - FloatRect RenderSurfaceChromium::computeRootScissorRectInCurrentSurface(const FloatRect& rootScissorRect) const { WebTransformationMatrix inverseScreenSpaceTransform = m_screenSpaceTransform.inverse(); diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h index 2b608f4e7..1681c5ba3 100644 --- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h +++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h @@ -31,13 +31,11 @@ #include "FloatRect.h" #include "IntRect.h" -#include <public/WebFilterOperations.h> #include <public/WebTransformationMatrix.h> #include <wtf/Noncopyable.h> namespace WebCore { -class FilterOperations; class LayerChromium; class LayerRendererChromium; @@ -90,38 +88,18 @@ public: const IntRect& scissorRect() const { return m_scissorRect; } void setScissorRect(const IntRect& scissorRect) { m_scissorRect = scissorRect; } - void setFilters(const WebKit::WebFilterOperations& filters) { m_filters = filters; } - const WebKit::WebFilterOperations& filters() const { return m_filters; } - - void setBackgroundFilters(const WebKit::WebFilterOperations& filters) { m_backgroundFilters = filters; } - const WebKit::WebFilterOperations& backgroundFilters() const { return m_backgroundFilters; } - - bool skipsDraw() const { return m_skipsDraw; } - void setSkipsDraw(bool skipsDraw) { m_skipsDraw = skipsDraw; } - void clearLayerList() { m_layerList.clear(); } Vector<RefPtr<LayerChromium> >& layerList() { return m_layerList; } - void setMaskLayer(LayerChromium* maskLayer) { m_maskLayer = maskLayer; } - void setNearestAncestorThatMovesPixels(RenderSurfaceChromium* surface) { m_nearestAncestorThatMovesPixels = surface; } const RenderSurfaceChromium* nearestAncestorThatMovesPixels() const { return m_nearestAncestorThatMovesPixels; } - RenderSurfaceChromium* targetRenderSurface() const; - - bool hasReplica() const; - - bool hasMask() const; - bool replicaHasMask() const; - FloatRect computeRootScissorRectInCurrentSurface(const FloatRect& rootScissorRect) const; private: LayerChromium* m_owningLayer; - LayerChromium* m_maskLayer; // Uses this surface's space. IntRect m_contentRect; - bool m_skipsDraw; float m_drawOpacity; bool m_drawOpacityIsAnimating; @@ -133,8 +111,6 @@ private: WebKit::WebTransformationMatrix m_replicaScreenSpaceTransform; bool m_targetSurfaceTransformsAreAnimating; bool m_screenSpaceTransformsAreAnimating; - WebKit::WebFilterOperations m_filters; - WebKit::WebFilterOperations m_backgroundFilters; // Uses the space of the surface's target surface. IntRect m_clipRect; diff --git a/Source/WebCore/platform/graphics/chromium/ScrollbarLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/ScrollbarLayerChromium.cpp index 56c96a74a..e00a26e39 100644 --- a/Source/WebCore/platform/graphics/chromium/ScrollbarLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/ScrollbarLayerChromium.cpp @@ -258,19 +258,19 @@ void ScrollbarLayerChromium::setTexturePriorities(const CCPriorityCalculator&) createTextureUpdaterIfNeeded(); - bool drawsToRootSurface = !targetRenderSurface()->targetRenderSurface(); + bool drawsToRoot = !renderTarget()->parent(); if (m_backTrack) { m_backTrack->texture()->setDimensions(contentBounds(), m_textureFormat); - m_backTrack->texture()->setRequestPriority(CCPriorityCalculator::uiPriority(drawsToRootSurface)); + m_backTrack->texture()->setRequestPriority(CCPriorityCalculator::uiPriority(drawsToRoot)); } if (m_foreTrack) { m_foreTrack->texture()->setDimensions(contentBounds(), m_textureFormat); - m_foreTrack->texture()->setRequestPriority(CCPriorityCalculator::uiPriority(drawsToRootSurface)); + m_foreTrack->texture()->setRequestPriority(CCPriorityCalculator::uiPriority(drawsToRoot)); } if (m_thumb) { IntSize thumbSize = theme()->thumbRect(m_scrollbar.get()).size(); m_thumb->texture()->setDimensions(thumbSize, m_textureFormat); - m_thumb->texture()->setRequestPriority(CCPriorityCalculator::uiPriority(drawsToRootSurface)); + m_thumb->texture()->setRequestPriority(CCPriorityCalculator::uiPriority(drawsToRoot)); } } diff --git a/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp index d085c9dd1..eed5cfc9a 100644 --- a/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp @@ -525,7 +525,7 @@ void TiledLayerChromium::setTexturePrioritiesInRect(const CCPriorityCalculator& resetUpdateState(); IntRect prepaintRect = idlePaintRect(visibleContentRect); - bool drawsToRootSurface = !targetRenderSurface()->targetRenderSurface(); + bool drawsToRoot = !renderTarget()->parent(); // Minimally create the tiles in the desired pre-paint rect. if (!prepaintRect.isEmpty()) { @@ -561,7 +561,7 @@ void TiledLayerChromium::setTexturePrioritiesInRect(const CCPriorityCalculator& tile->dirtyRect = m_tiler->tileRect(tile); LayerTextureUpdater::Texture* backBuffer = tile->texture(); - backBuffer->texture()->setRequestPriority(priorityCalc.priorityFromVisibility(true, drawsToRootSurface)); + backBuffer->texture()->setRequestPriority(priorityCalc.priorityFromVisibility(true, drawsToRoot)); OwnPtr<CCPrioritizedTexture> frontBuffer = CCPrioritizedTexture::create(backBuffer->texture()->textureManager(), backBuffer->texture()->size(), backBuffer->texture()->format()); @@ -581,9 +581,9 @@ void TiledLayerChromium::setTexturePrioritiesInRect(const CCPriorityCalculator& // 512 pixels of pre-painting. Later we can just pass an animating flag etc. to the // calculator and it can take care of this special case if we still need it. if (visibleContentRect.isEmpty() && !prepaintRect.isEmpty()) - tile->managedTexture()->setRequestPriority(priorityCalc.priorityFromDistance(512, drawsToRootSurface)); + tile->managedTexture()->setRequestPriority(priorityCalc.priorityFromDistance(512, drawsToRoot)); else if (!visibleContentRect.isEmpty()) - tile->managedTexture()->setRequestPriority(priorityCalc.priorityFromDistance(visibleContentRect, tileRect, drawsToRootSurface)); + tile->managedTexture()->setRequestPriority(priorityCalc.priorityFromDistance(visibleContentRect, tileRect, drawsToRoot)); } } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCIOSurfaceLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCIOSurfaceLayerImpl.cpp index ce3b38e96..d1157ed03 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCIOSurfaceLayerImpl.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCIOSurfaceLayerImpl.cpp @@ -98,7 +98,7 @@ void CCIOSurfaceLayerImpl::willDraw(CCRenderer* layerRenderer, CCGraphicsContext void CCIOSurfaceLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState, bool&) { - IntRect quadRect(IntPoint(), bounds()); + IntRect quadRect(IntPoint(), contentBounds()); quadList.append(CCIOSurfaceDrawQuad::create(sharedQuadState, quadRect, m_ioSurfaceSize, m_ioSurfaceTextureId)); } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp index 9a88376c2..9434dc59c 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp @@ -71,7 +71,7 @@ CCLayerImpl::CCLayerImpl(int id) , m_isContainerForFixedPositionLayers(false) , m_fixedToContainerLayer(false) , m_pageScaleDelta(1) - , m_targetRenderSurface(0) + , m_renderTarget(0) , m_drawDepth(0) , m_drawOpacity(0) , m_drawOpacityIsAnimating(false) @@ -133,7 +133,7 @@ void CCLayerImpl::createRenderSurface() { ASSERT(!m_renderSurface); m_renderSurface = adoptPtr(new CCRenderSurface(this)); - setTargetRenderSurface(m_renderSurface.get()); + setRenderTarget(this); } bool CCLayerImpl::descendantDrawsContent() @@ -147,7 +147,14 @@ bool CCLayerImpl::descendantDrawsContent() PassOwnPtr<CCSharedQuadState> CCLayerImpl::createSharedQuadState() const { - return CCSharedQuadState::create(quadTransform(), m_visibleContentRect, m_scissorRect, m_drawOpacity, m_opaque); + WebTransformationMatrix quadTransformation = drawTransform(); + if (!contentBounds().isEmpty() && !bounds().isEmpty()) { + quadTransformation.scaleNonUniform(bounds().width() / static_cast<double>(contentBounds().width()), + bounds().height() / static_cast<double>(contentBounds().height())); + quadTransformation.translate(-contentBounds().width() / 2.0, -contentBounds().height() / 2.0); + } + + return CCSharedQuadState::create(quadTransformation, m_visibleContentRect, m_scissorRect, m_drawOpacity, m_opaque); } void CCLayerImpl::willDraw(CCRenderer*, CCGraphicsContext*) @@ -235,17 +242,6 @@ const IntRect CCLayerImpl::getDrawRect() const return mappedRect; } -WebTransformationMatrix CCLayerImpl::quadTransform() const -{ - WebTransformationMatrix quadTransformation = drawTransform(); - - float offsetX = -0.5 * bounds().width(); - float offsetY = -0.5 * bounds().height(); - quadTransformation.translate(offsetX, offsetY); - - return quadTransformation; -} - void CCLayerImpl::writeIndent(TextStream& ts, int indent) { for (int i = 0; i != indent; ++i) @@ -260,9 +256,9 @@ void CCLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const writeIndent(ts, indent); ts << "bounds: " << bounds().width() << ", " << bounds().height() << "\n"; - if (m_targetRenderSurface) { + if (m_renderTarget) { writeIndent(ts, indent); - ts << "targetRenderSurface: " << m_targetRenderSurface->name() << "\n"; + ts << "renderTarget: " << m_renderTarget->m_layerId << "\n"; } writeIndent(ts, indent); diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h index 2b9a49bd3..a5cacd64b 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h @@ -80,6 +80,10 @@ public: void setReplicaLayer(PassOwnPtr<CCLayerImpl>); CCLayerImpl* replicaLayer() const { return m_replicaLayer.get(); } + bool hasMask() const { return m_maskLayer; } + bool hasReplica() const { return m_replicaLayer; } + bool replicaHasMask() const { return m_replicaLayer && (m_maskLayer || m_replicaLayer->m_maskLayer); } + CCLayerTreeHostImpl* layerTreeHostImpl() const { return m_layerTreeHostImpl; } void setLayerTreeHostImpl(CCLayerTreeHostImpl* hostImpl) { m_layerTreeHostImpl = hostImpl; } @@ -181,8 +185,8 @@ public: const IntRect& scissorRect() const { return m_scissorRect; } void setScissorRect(const IntRect& rect) { m_scissorRect = rect; } - CCRenderSurface* targetRenderSurface() const { return m_targetRenderSurface; } - void setTargetRenderSurface(CCRenderSurface* surface) { m_targetRenderSurface = surface; } + CCLayerImpl* renderTarget() const { ASSERT(!m_renderTarget || m_renderTarget->renderSurface()); return m_renderTarget; } + void setRenderTarget(CCLayerImpl* target) { m_renderTarget = target; } void setBounds(const IntSize&); const IntSize& bounds() const { return m_bounds; } @@ -278,9 +282,6 @@ protected: virtual void dumpLayerProperties(TextStream&, int indent) const; static void writeIndent(TextStream&, int indent); - // Transformation used to transform quads provided in appendQuads. - virtual WebKit::WebTransformationMatrix quadTransform() const; - private: void setParent(CCLayerImpl* parent) { m_parent = parent; } friend class TreeSynchronizer; @@ -358,11 +359,10 @@ private: IntSize m_maxScrollPosition; float m_pageScaleDelta; - // Render surface this layer draws into. This is a surface that can belong - // either to this layer (if m_targetRenderSurface == m_renderSurface) or - // to an ancestor of this layer. The target render surface determines the - // coordinate system the layer's transforms are relative to. - CCRenderSurface* m_targetRenderSurface; + // The layer whose coordinate space this layer draws into. This can be + // either the same layer (m_renderTarget == this) or an ancestor of this + // layer. + CCLayerImpl* m_renderTarget; // The global depth value of the center of the layer. This value is used // to sort layers from back to front. diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp index da2cb32a0..1f51f19d4 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp @@ -555,7 +555,7 @@ size_t CCLayerTreeHost::calculateMemoryForRenderSurfaces(const LayerList& update size_t bytes = CCTexture::memorySizeBytes(renderSurface->contentRect().size(), GraphicsContext3D::RGBA); contentsTextureBytes += bytes; - if (renderSurface->backgroundFilters().isEmpty()) + if (renderSurfaceLayer->backgroundFilters().isEmpty()) continue; if (bytes > maxBackgroundTextureBytes) diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp index 1c677555a..c75d548f8 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp @@ -68,7 +68,8 @@ IntRect CCLayerTreeHostCommon::calculateVisibleRect(const IntRect& targetSurface template<typename LayerType, typename RenderSurfaceType> static IntRect calculateLayerScissorRect(LayerType* layer, const FloatRect& rootScissorRect) { - RenderSurfaceType* targetSurface = layer->targetRenderSurface(); + LayerType* renderTarget = layer->renderTarget(); + RenderSurfaceType* targetSurface = renderTarget->renderSurface(); FloatRect rootScissorRectInTargetSurface = targetSurface->computeRootScissorRectInCurrentSurface(rootScissorRect); FloatRect clipAndDamage; @@ -84,7 +85,9 @@ template<typename LayerType, typename RenderSurfaceType> static IntRect calculateSurfaceScissorRect(LayerType* layer, const FloatRect& rootScissorRect) { LayerType* parentLayer = layer->parent(); - RenderSurfaceType* targetSurface = parentLayer->targetRenderSurface(); + LayerType* renderTarget = parentLayer->renderTarget(); + + RenderSurfaceType* targetSurface = renderTarget->renderSurface(); ASSERT(targetSurface); RenderSurfaceType* currentSurface = layer->renderSurface(); @@ -155,9 +158,9 @@ static bool isSurfaceBackFaceVisible(LayerType* layer, const WebTransformationMa template<typename LayerType> static IntRect calculateVisibleContentRect(LayerType* layer) { - ASSERT(layer->targetRenderSurface()); + ASSERT(layer->renderTarget()); - IntRect targetSurfaceRect = layer->targetRenderSurface()->contentRect(); + IntRect targetSurfaceRect = layer->renderTarget()->renderSurface()->contentRect(); if (layer->usesLayerClipping()) targetSurfaceRect.intersect(layer->clipRect()); @@ -321,7 +324,7 @@ WebTransformationMatrix computeScrollCompensationForThisLayer(CCLayerImpl* scrol // // These steps create a matrix that both start and end in targetSurfaceSpace. So this matrix can // pre-multiply any fixed-position layer's drawTransform to undo the scrollDeltas -- as long as - // that fixed position layer is fixed onto the same targetRenderSurface as this scrollingLayer. + // that fixed position layer is fixed onto the same renderTarget as this scrollingLayer. // WebTransformationMatrix partialLayerOriginTransform = parentMatrix; @@ -610,18 +613,15 @@ static bool calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay layer->setClipRect(IntRect()); if (layer->maskLayer()) - layer->maskLayer()->setTargetRenderSurface(renderSurface); + layer->maskLayer()->setRenderTarget(layer); if (layer->replicaLayer() && layer->replicaLayer()->maskLayer()) - layer->replicaLayer()->maskLayer()->setTargetRenderSurface(renderSurface); + layer->replicaLayer()->maskLayer()->setRenderTarget(layer); - renderSurface->setFilters(layer->filters()); - if (renderSurface->filters().hasFilterThatMovesPixels()) + if (layer->filters().hasFilterThatMovesPixels()) nearestAncestorThatMovesPixels = renderSurface; renderSurface->setNearestAncestorThatMovesPixels(nearestAncestorThatMovesPixels); - renderSurface->setBackgroundFilters(layer->backgroundFilters()); - renderSurfaceLayerList.append(layer); } else { layer->setDrawTransform(combinedTransform); @@ -641,8 +641,8 @@ static bool calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay if (layer->parent()->usesLayerClipping()) layer->setUsesLayerClipping(true); - // Layers without their own renderSurface will render into the nearest ancestor surface. - layer->setTargetRenderSurface(layer->parent()->targetRenderSurface()); + // Layers that are not their own renderTarget will render into the target of their nearest ancestor. + layer->setRenderTarget(layer->parent()->renderTarget()); } } @@ -918,7 +918,8 @@ static bool pointIsClippedBySurfaceOrClipRect(const IntPoint& viewportPoint, CCL // Note that clipRects are actually in targetSurface space, so the transform we // have to provide is the target surface's screenSpaceTransform. - if (currentLayer->usesLayerClipping() && !pointHitsRect(viewportPoint, currentLayer->targetRenderSurface()->screenSpaceTransform(), currentLayer->clipRect())) + CCLayerImpl* renderTarget = currentLayer->renderTarget(); + if (currentLayer->usesLayerClipping() && !pointHitsRect(viewportPoint, renderTarget->renderSurface()->screenSpaceTransform(), currentLayer->clipRect())) return true; currentLayer = currentLayer->parent(); diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp index ada3c8e3b..04bb78671 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp @@ -447,7 +447,10 @@ bool CCLayerTreeHostImpl::CullRenderPassesWithNoQuads::shouldRemoveRenderPass(co { const CCRenderPass* renderPass = findRenderPassById(quad.renderPassId(), frame); size_t passIndex = frame.renderPasses.find(renderPass); - ASSERT(passIndex != notFound); + + bool renderPassAlreadyRemoved = passIndex == notFound; + if (renderPassAlreadyRemoved) + return false; // If any quad or RenderPass draws into this RenderPass, then keep it. const CCQuadList& quadList = frame.renderPasses[passIndex]->quadList(); @@ -758,18 +761,6 @@ static void adjustScrollsForPageScaleChange(CCLayerImpl* layerImpl, float pageSc adjustScrollsForPageScaleChange(layerImpl->children()[i].get(), pageScaleChange); } -static void applyPageScaleDeltaToScrollLayers(CCLayerImpl* layerImpl, float pageScaleDelta) -{ - if (!layerImpl) - return; - - if (layerImpl->scrollable()) - layerImpl->setPageScaleDelta(pageScaleDelta); - - for (size_t i = 0; i < layerImpl->children().size(); ++i) - applyPageScaleDeltaToScrollLayers(layerImpl->children()[i].get(), pageScaleDelta); -} - void CCLayerTreeHostImpl::setDeviceScaleFactor(float deviceScaleFactor) { if (deviceScaleFactor == m_deviceScaleFactor) @@ -804,7 +795,8 @@ void CCLayerTreeHostImpl::setPageScaleFactorAndLimits(float pageScale, float min // Clamp delta to limits and refresh display matrix. setPageScaleDelta(m_pageScaleDelta / m_sentPageScaleDelta); m_sentPageScaleDelta = 1; - applyPageScaleDeltaToScrollLayers(m_rootScrollLayerImpl, m_pageScaleDelta); + if (m_rootScrollLayerImpl) + m_rootScrollLayerImpl->setPageScaleDelta(m_pageScaleDelta); } void CCLayerTreeHostImpl::setPageScaleDelta(float delta) @@ -822,7 +814,8 @@ void CCLayerTreeHostImpl::setPageScaleDelta(float delta) m_pageScaleDelta = delta; updateMaxScrollPosition(); - applyPageScaleDeltaToScrollLayers(m_rootScrollLayerImpl, m_pageScaleDelta); + if (m_rootScrollLayerImpl) + m_rootScrollLayerImpl->setPageScaleDelta(m_pageScaleDelta); } void CCLayerTreeHostImpl::updateMaxScrollPosition() diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp index 6124ddc9c..0d01593cf 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp @@ -52,34 +52,34 @@ CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::CCOcclusionTrackerBase(Int template<typename LayerType, typename RenderSurfaceType> void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::enterLayer(const CCLayerIteratorPosition<LayerType>& layerIterator) { - RenderSurfaceType* renderSurface = layerIterator.targetRenderSurfaceLayer->renderSurface(); + LayerType* renderTarget = layerIterator.targetRenderSurfaceLayer; if (layerIterator.representsItself) - enterTargetRenderSurface(renderSurface); + enterRenderTarget(renderTarget); else if (layerIterator.representsTargetRenderSurface) - finishedTargetRenderSurface(layerIterator.currentLayer, renderSurface); + finishedRenderTarget(renderTarget); } template<typename LayerType, typename RenderSurfaceType> void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveLayer(const CCLayerIteratorPosition<LayerType>& layerIterator) { - RenderSurfaceType* renderSurface = layerIterator.targetRenderSurfaceLayer->renderSurface(); + LayerType* renderTarget = layerIterator.targetRenderSurfaceLayer; if (layerIterator.representsItself) markOccludedBehindLayer(layerIterator.currentLayer); else if (layerIterator.representsContributingRenderSurface) - leaveToTargetRenderSurface(renderSurface); + leaveToRenderTarget(renderTarget); } template<typename LayerType, typename RenderSurfaceType> -void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::enterTargetRenderSurface(const RenderSurfaceType* newTarget) +void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::enterRenderTarget(const LayerType* newTarget) { - if (!m_stack.isEmpty() && m_stack.last().surface == newTarget) + if (!m_stack.isEmpty() && m_stack.last().target == newTarget) return; - const RenderSurfaceType* oldTarget = m_stack.isEmpty() ? 0 : m_stack.last().surface; - const RenderSurfaceType* oldAncestorThatMovesPixels = !oldTarget ? 0 : oldTarget->nearestAncestorThatMovesPixels(); - const RenderSurfaceType* newAncestorThatMovesPixels = newTarget->nearestAncestorThatMovesPixels(); + const LayerType* oldTarget = m_stack.isEmpty() ? 0 : m_stack.last().target; + const RenderSurfaceType* oldAncestorThatMovesPixels = !oldTarget ? 0 : oldTarget->renderSurface()->nearestAncestorThatMovesPixels(); + const RenderSurfaceType* newAncestorThatMovesPixels = newTarget->renderSurface()->nearestAncestorThatMovesPixels(); m_stack.append(StackObject(newTarget)); @@ -116,22 +116,21 @@ static inline bool layerIsInUnsorted3dRenderingContext(const LayerChromium* laye static inline bool layerIsInUnsorted3dRenderingContext(const CCLayerImpl*) { return false; } template<typename LayerType, typename RenderSurfaceType> -void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::finishedTargetRenderSurface(const LayerType* owningLayer, const RenderSurfaceType* finishedTarget) +void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::finishedRenderTarget(const LayerType* finishedTarget) { - // FIXME: Remove the owningLayer parameter when we can get all the info from the surface. - ASSERT(owningLayer->renderSurface() == finishedTarget); - // Make sure we know about the target surface. - enterTargetRenderSurface(finishedTarget); + enterRenderTarget(finishedTarget); + + RenderSurfaceType* surface = finishedTarget->renderSurface(); // If the occlusion within the surface can not be applied to things outside of the surface's subtree, then clear the occlusion here so it won't be used. - if (owningLayer->maskLayer() || !surfaceOpacityKnown(finishedTarget) || finishedTarget->drawOpacity() < 1 || finishedTarget->filters().hasFilterThatAffectsOpacity()) { + if (finishedTarget->maskLayer() || !surfaceOpacityKnown(surface) || surface->drawOpacity() < 1 || finishedTarget->filters().hasFilterThatAffectsOpacity()) { m_stack.last().occlusionInScreen = Region(); m_stack.last().occlusionInTarget = Region(); } else { - if (!surfaceTransformsToTargetKnown(finishedTarget)) + if (!surfaceTransformsToTargetKnown(surface)) m_stack.last().occlusionInTarget = Region(); - if (!surfaceTransformsToScreenKnown(finishedTarget)) + if (!surfaceTransformsToScreenKnown(surface)) m_stack.last().occlusionInScreen = Region(); } } @@ -199,52 +198,53 @@ static inline void reduceOcclusion(const IntRect& affectedArea, const IntRect& e } } -template<typename RenderSurfaceType> -static void reduceOcclusionBelowSurface(RenderSurfaceType* surface, const IntRect& surfaceRect, const WebTransformationMatrix& surfaceTransform, RenderSurfaceType* surfaceTarget, Region& occlusionInTarget, Region& occlusionInScreen) +template<typename LayerType> +static void reduceOcclusionBelowSurface(LayerType* contributingLayer, const IntRect& surfaceRect, const WebTransformationMatrix& surfaceTransform, LayerType* renderTarget, Region& occlusionInTarget, Region& occlusionInScreen) { if (surfaceRect.isEmpty()) return; IntRect boundsInTarget = enclosingIntRect(CCMathUtil::mapClippedRect(surfaceTransform, FloatRect(surfaceRect))); - if (!surface->clipRect().isEmpty()) - boundsInTarget.intersect(surface->clipRect()); + if (!contributingLayer->renderSurface()->clipRect().isEmpty()) + boundsInTarget.intersect(contributingLayer->renderSurface()->clipRect()); int outsetTop, outsetRight, outsetBottom, outsetLeft; - surface->backgroundFilters().getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft); + contributingLayer->backgroundFilters().getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft); // The filter can move pixels from outside of the clip, so allow affectedArea to expand outside the clip. boundsInTarget.move(-outsetLeft, -outsetTop); boundsInTarget.expand(outsetLeft + outsetRight, outsetTop + outsetBottom); - IntRect boundsInScreen = enclosingIntRect(CCMathUtil::mapClippedRect(surfaceTarget->screenSpaceTransform(), FloatRect(boundsInTarget))); + IntRect boundsInScreen = enclosingIntRect(CCMathUtil::mapClippedRect(renderTarget->renderSurface()->screenSpaceTransform(), FloatRect(boundsInTarget))); IntRect filterOutsetsInTarget(-outsetLeft, -outsetTop, outsetLeft + outsetRight, outsetTop + outsetBottom); - IntRect filterOutsetsInScreen = enclosingIntRect(CCMathUtil::mapClippedRect(surfaceTarget->screenSpaceTransform(), FloatRect(filterOutsetsInTarget))); + IntRect filterOutsetsInScreen = enclosingIntRect(CCMathUtil::mapClippedRect(renderTarget->renderSurface()->screenSpaceTransform(), FloatRect(filterOutsetsInTarget))); reduceOcclusion(boundsInTarget, filterOutsetsInTarget, occlusionInTarget); reduceOcclusion(boundsInScreen, filterOutsetsInScreen, occlusionInScreen); } template<typename LayerType, typename RenderSurfaceType> -void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveToTargetRenderSurface(const RenderSurfaceType* newTarget) +void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveToRenderTarget(const LayerType* newTarget) { int lastIndex = m_stack.size() - 1; - bool surfaceWillBeAtTopAfterPop = m_stack.size() > 1 && m_stack[lastIndex - 1].surface == newTarget; + bool surfaceWillBeAtTopAfterPop = m_stack.size() > 1 && m_stack[lastIndex - 1].target == newTarget; // We merge the screen occlusion from the current RenderSurface subtree out to its parent target RenderSurface. // The target occlusion can be merged out as well but needs to be transformed to the new target. - const RenderSurfaceType* oldTarget = m_stack[lastIndex].surface; - Region oldTargetOcclusionInNewTarget = transformSurfaceOpaqueRegion<RenderSurfaceType>(oldTarget, m_stack[lastIndex].occlusionInTarget, oldTarget->originTransform()); + const LayerType* oldTarget = m_stack[lastIndex].target; + const RenderSurfaceType* oldSurface = oldTarget->renderSurface(); + Region oldTargetOcclusionInNewTarget = transformSurfaceOpaqueRegion<RenderSurfaceType>(oldSurface, m_stack[lastIndex].occlusionInTarget, oldSurface->originTransform()); if (oldTarget->hasReplica() && !oldTarget->replicaHasMask()) - oldTargetOcclusionInNewTarget.unite(transformSurfaceOpaqueRegion<RenderSurfaceType>(oldTarget, m_stack[lastIndex].occlusionInTarget, oldTarget->replicaOriginTransform())); + oldTargetOcclusionInNewTarget.unite(transformSurfaceOpaqueRegion<RenderSurfaceType>(oldSurface, m_stack[lastIndex].occlusionInTarget, oldSurface->replicaOriginTransform())); IntRect unoccludedSurfaceRect; IntRect unoccludedReplicaRect; if (oldTarget->backgroundFilters().hasFilterThatMovesPixels()) { - unoccludedSurfaceRect = unoccludedContributingSurfaceContentRect(oldTarget, false, oldTarget->contentRect()); + unoccludedSurfaceRect = unoccludedContributingSurfaceContentRect(oldTarget, false, oldSurface->contentRect()); if (oldTarget->hasReplica()) - unoccludedReplicaRect = unoccludedContributingSurfaceContentRect(oldTarget, true, oldTarget->contentRect()); + unoccludedReplicaRect = unoccludedContributingSurfaceContentRect(oldTarget, true, oldSurface->contentRect()); } if (surfaceWillBeAtTopAfterPop) { @@ -254,14 +254,14 @@ void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::leaveToTargetRenderSu m_stack.removeLast(); } else { // Replace the top of the stack with the new pushed surface. Copy the occluded screen region to the top. - m_stack.last().surface = newTarget; + m_stack.last().target = newTarget; m_stack.last().occlusionInTarget = oldTargetOcclusionInNewTarget; } if (oldTarget->backgroundFilters().hasFilterThatMovesPixels()) { - reduceOcclusionBelowSurface(oldTarget, unoccludedSurfaceRect, oldTarget->originTransform(), newTarget, m_stack.last().occlusionInTarget, m_stack.last().occlusionInScreen); + reduceOcclusionBelowSurface(oldTarget, unoccludedSurfaceRect, oldSurface->originTransform(), newTarget, m_stack.last().occlusionInTarget, m_stack.last().occlusionInScreen); if (oldTarget->hasReplica()) - reduceOcclusionBelowSurface(oldTarget, unoccludedReplicaRect, oldTarget->replicaOriginTransform(), newTarget, m_stack.last().occlusionInTarget, m_stack.last().occlusionInScreen); + reduceOcclusionBelowSurface(oldTarget, unoccludedReplicaRect, oldSurface->replicaOriginTransform(), newTarget, m_stack.last().occlusionInTarget, m_stack.last().occlusionInScreen); } } @@ -335,7 +335,7 @@ template<typename LayerType, typename RenderSurfaceType> void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLayer(const LayerType* layer) { ASSERT(!m_stack.isEmpty()); - ASSERT(layer->targetRenderSurface() == m_stack.last().surface); + ASSERT(layer->renderTarget() == m_stack.last().target); if (m_stack.isEmpty()) return; @@ -357,7 +357,7 @@ void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLay // remain rectilinear, then we don't add any occlusion in screen space. if (layerTransformsToScreenKnown(layer)) { - WebTransformationMatrix targetToScreenTransform = m_stack.last().surface->screenSpaceTransform(); + WebTransformationMatrix targetToScreenTransform = m_stack.last().target->renderSurface()->screenSpaceTransform(); bool clipped; FloatQuad scissorInScreenQuad = CCMathUtil::mapQuad(targetToScreenTransform, FloatQuad(FloatRect(scissorInTarget)), clipped); // FIXME: Find a rect interior to the transformed scissor quad. @@ -385,7 +385,7 @@ bool CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::occluded(const LayerT if (contentRect.isEmpty()) return true; - ASSERT(layer->targetRenderSurface() == m_stack.last().surface); + ASSERT(layer->renderTarget() == m_stack.last().target); if (layerTransformsToScreenKnown(layer) && testContentRectOccluded(contentRect, contentToScreenSpaceTransform<LayerType>(layer), m_scissorRectInScreenSpace, m_stack.last().occlusionInScreen)) return true; @@ -425,7 +425,7 @@ IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContentR if (contentRect.isEmpty()) return contentRect; - ASSERT(layer->targetRenderSurface() == m_stack.last().surface); + ASSERT(layer->renderTarget() == m_stack.last().target); // We want to return a rect that contains all the visible parts of |contentRect| in both screen space and in the target surface. // So we find the visible parts of |contentRect| in each space, and take the intersection. @@ -445,22 +445,27 @@ IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContentR } template<typename LayerType, typename RenderSurfaceType> -IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContributingSurfaceContentRect(const RenderSurfaceType* surface, bool forReplica, const IntRect& contentRect) const +IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContributingSurfaceContentRect(const LayerType* layer, bool forReplica, const IntRect& contentRect) const { ASSERT(!m_stack.isEmpty()); - // This should be called while the contributing render surface is still considered the current target in the occlusion tracker. - ASSERT(surface == m_stack.last().surface); + // The layer is a contributing renderTarget so it should have a surface. + ASSERT(layer->renderSurface()); + // The layer is a contributing renderTarget so its target should be itself. + ASSERT(layer->renderTarget() == layer); + // The layer should not be the root, else what is is contributing to? + ASSERT(layer->parent()); + // This should be called while the layer is still considered the current target in the occlusion tracker. + ASSERT(layer == m_stack.last().target); if (contentRect.isEmpty()) return contentRect; + RenderSurfaceType* surface = layer->renderSurface(); + IntRect surfaceClipRect = surface->clipRect(); if (surfaceClipRect.isEmpty()) { - const RenderSurfaceType* targetSurface = surface->targetRenderSurface(); - if (targetSurface) - surfaceClipRect = intersection(targetSurface->contentRect(), enclosingIntRect(surface->drawableContentRect())); - else - surfaceClipRect = m_scissorRectInScreenSpace; + LayerType* contributingSurfaceRenderTarget = layer->parent()->renderTarget(); + surfaceClipRect = intersection(contributingSurfaceRenderTarget->renderSurface()->contentRect(), enclosingIntRect(surface->drawableContentRect())); } // A contributing surface doesn't get occluded by things inside its own surface, so only things outside the surface can occlude it. That occlusion is @@ -497,8 +502,8 @@ IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::unoccludedContribu template<typename LayerType, typename RenderSurfaceType> IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::layerScissorRectInTargetSurface(const LayerType* layer) const { - const RenderSurfaceType* targetSurface = m_stack.last().surface; - FloatRect totalScissor = targetSurface->contentRect(); + const LayerType* renderTarget = m_stack.last().target; + FloatRect totalScissor = renderTarget->renderSurface()->contentRect(); if (layer->usesLayerClipping()) totalScissor.intersect(layer->clipRect()); return enclosingIntRect(totalScissor); @@ -508,25 +513,25 @@ IntRect CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::layerScissorRectIn template CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::CCOcclusionTrackerBase(IntRect scissorRectInScreenSpace, bool recordMetricsForFrame); template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::enterLayer(const CCLayerIteratorPosition<LayerChromium>&); template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::leaveLayer(const CCLayerIteratorPosition<LayerChromium>&); -template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::enterTargetRenderSurface(const RenderSurfaceChromium* newTarget); -template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::finishedTargetRenderSurface(const LayerChromium* owningLayer, const RenderSurfaceChromium* finishedTarget); -template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::leaveToTargetRenderSurface(const RenderSurfaceChromium* newTarget); +template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::enterRenderTarget(const LayerChromium* newTarget); +template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::finishedRenderTarget(const LayerChromium* finishedTarget); +template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::leaveToRenderTarget(const LayerChromium* newTarget); template void CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::markOccludedBehindLayer(const LayerChromium*); template bool CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::occluded(const LayerChromium*, const IntRect& contentRect) const; template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::unoccludedContentRect(const LayerChromium*, const IntRect& contentRect) const; -template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::unoccludedContributingSurfaceContentRect(const RenderSurfaceChromium*, bool forReplica, const IntRect& contentRect) const; +template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::unoccludedContributingSurfaceContentRect(const LayerChromium*, bool forReplica, const IntRect& contentRect) const; template IntRect CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium>::layerScissorRectInTargetSurface(const LayerChromium*) const; template CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::CCOcclusionTrackerBase(IntRect scissorRectInScreenSpace, bool recordMetricsForFrame); template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::enterLayer(const CCLayerIteratorPosition<CCLayerImpl>&); template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::leaveLayer(const CCLayerIteratorPosition<CCLayerImpl>&); -template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::enterTargetRenderSurface(const CCRenderSurface* newTarget); -template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::finishedTargetRenderSurface(const CCLayerImpl* owningLayer, const CCRenderSurface* finishedTarget); -template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::leaveToTargetRenderSurface(const CCRenderSurface* newTarget); +template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::enterRenderTarget(const CCLayerImpl* newTarget); +template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::finishedRenderTarget(const CCLayerImpl* finishedTarget); +template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::leaveToRenderTarget(const CCLayerImpl* newTarget); template void CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::markOccludedBehindLayer(const CCLayerImpl*); template bool CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::occluded(const CCLayerImpl*, const IntRect& contentRect) const; template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::unoccludedContentRect(const CCLayerImpl*, const IntRect& contentRect) const; -template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::unoccludedContributingSurfaceContentRect(const CCRenderSurface*, bool forReplica, const IntRect& contentRect) const; +template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::unoccludedContributingSurfaceContentRect(const CCLayerImpl*, bool forReplica, const IntRect& contentRect) const; template IntRect CCOcclusionTrackerBase<CCLayerImpl, CCRenderSurface>::layerScissorRectInTargetSurface(const CCLayerImpl*) const; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h index 0ca966d96..ae85751ea 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.h @@ -58,9 +58,9 @@ public: // Gives an unoccluded sub-rect of |contentRect| in the content space of the layer. Used when considering occlusion for a layer that paints/draws something. IntRect unoccludedContentRect(const LayerType*, const IntRect& contentRect) const; - // Gives an unoccluded sub-rect of |contentRect| in the content space of the surface. Used when considering occlusion for a contributing surface - // that is rendering into another target surface. - IntRect unoccludedContributingSurfaceContentRect(const RenderSurfaceType*, bool forReplica, const IntRect& contentRect) const; + // Gives an unoccluded sub-rect of |contentRect| in the content space of the renderTarget owned by the layer. + // Used when considering occlusion for a contributing surface that is rendering into another target. + IntRect unoccludedContributingSurfaceContentRect(const LayerType*, bool forReplica, const IntRect& contentRect) const; // Report operations for recording overdraw metrics. CCOverdrawMetrics& overdrawMetrics() const { return *m_overdrawMetrics.get(); } @@ -75,9 +75,9 @@ public: protected: struct StackObject { - StackObject() : surface(0) { } - StackObject(const RenderSurfaceType* surface) : surface(surface) { } - const RenderSurfaceType* surface; + StackObject() : target(0) { } + StackObject(const LayerType* target) : target(target) { } + const LayerType* target; Region occlusionInScreen; Region occlusionInTarget; }; @@ -96,15 +96,15 @@ protected: private: // Called when visiting a layer representing itself. If the target was not already current, then this indicates we have entered a new surface subtree. - void enterTargetRenderSurface(const RenderSurfaceType* newTarget); + void enterRenderTarget(const LayerType* newTarget); // Called when visiting a layer representing a target surface. This indicates we have visited all the layers within the surface, and we may // perform any surface-wide operations. - void finishedTargetRenderSurface(const LayerType*, const RenderSurfaceType* finishedTarget); + void finishedRenderTarget(const LayerType* finishedTarget); // Called when visiting a layer representing a contributing surface. This indicates that we are leaving our current surface, and // entering the new one. We then perform any operations required for merging results from the child subtree into its parent. - void leaveToTargetRenderSurface(const RenderSurfaceType* newTarget); + void leaveToRenderTarget(const LayerType* newTarget); // Add the layer's occlusion to the tracked state. void markOccludedBehindLayer(const LayerType*); diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp index da8980295..65f78788e 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp @@ -84,7 +84,7 @@ bool CCQuadCuller::append(PassOwnPtr<CCDrawQuad> passDrawQuad) bool CCQuadCuller::appendSurface(PassOwnPtr<CCDrawQuad> passDrawQuad) { - IntRect culledRect = m_occlusionTracker->unoccludedContributingSurfaceContentRect(m_layer->renderSurface(), false, passDrawQuad->quadRect()); + IntRect culledRect = m_occlusionTracker->unoccludedContributingSurfaceContentRect(m_layer, false, passDrawQuad->quadRect()); return appendQuadInternal(passDrawQuad, culledRect, m_quadList, *m_occlusionTracker, m_showCullingWithDebugBorderQuads); } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp index b11100af3..532665fbe 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp @@ -75,7 +75,7 @@ void CCRenderPass::appendQuadsForRenderSurfaceLayer(CCLayerImpl* layer, const CC surface->appendQuads(quadCuller, sharedQuadState.get(), isReplica, contributingRenderPass->id()); m_sharedQuadStateList.append(sharedQuadState.release()); - if (!surface->hasReplica()) + if (!layer->hasReplica()) return; // Add replica after the surface so that it appears below the surface. @@ -94,6 +94,8 @@ void CCRenderPass::appendQuadsToFillScreen(CCLayerImpl* rootLayer, SkColor scree if (fillRegion.isEmpty()) return; + // Manually create the quad state for the gutter quads, as the root layer + // doesn't have any bounds and so can't generate this itself. OwnPtr<CCSharedQuadState> sharedQuadState = rootLayer->createSharedQuadState(); WebTransformationMatrix transformToLayerSpace = rootLayer->screenSpaceTransform().inverse(); Vector<IntRect> fillRects = fillRegion.rects(); diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp index 8bd46bf00..e7260966a 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp @@ -78,7 +78,7 @@ FloatRect CCRenderSurface::drawableContentRect() const FloatRect localContentRect(-0.5 * m_contentRect.width(), -0.5 * m_contentRect.height(), m_contentRect.width(), m_contentRect.height()); FloatRect drawableContentRect = CCMathUtil::mapClippedRect(m_drawTransform, localContentRect); - if (hasReplica()) + if (m_owningLayer->hasReplica()) drawableContentRect.unite(CCMathUtil::mapClippedRect(m_replicaDrawTransform, localContentRect)); return drawableContentRect; @@ -120,28 +120,6 @@ int CCRenderSurface::owningLayerId() const return m_owningLayer ? m_owningLayer->id() : 0; } -CCRenderSurface* CCRenderSurface::targetRenderSurface() const -{ - CCLayerImpl* parent = m_owningLayer->parent(); - if (!parent) - return 0; - return parent->targetRenderSurface(); -} - -bool CCRenderSurface::hasReplica() const -{ - return m_owningLayer->replicaLayer(); -} - -bool CCRenderSurface::hasMask() const -{ - return m_owningLayer->maskLayer(); -} - -bool CCRenderSurface::replicaHasMask() const -{ - return hasReplica() && (m_owningLayer->maskLayer() || m_owningLayer->replicaLayer()->maskLayer()); -} void CCRenderSurface::setClipRect(const IntRect& clipRect) { @@ -205,7 +183,7 @@ FloatRect CCRenderSurface::computeRootScissorRectInCurrentSurface(const FloatRec void CCRenderSurface::appendQuads(CCQuadCuller& quadList, CCSharedQuadState* sharedQuadState, bool forReplica, int renderPassId) { - ASSERT(!forReplica || hasReplica()); + ASSERT(!forReplica || m_owningLayer->hasReplica()); if (m_owningLayer->hasDebugBorders()) { int red = forReplica ? debugReplicaBorderColorRed : debugSurfaceBorderColorRed; @@ -235,7 +213,10 @@ void CCRenderSurface::appendQuads(CCQuadCuller& quadList, CCSharedQuadState* sha WebTransformationMatrix drawTransform = forReplica ? m_replicaDrawTransform : m_drawTransform; IntRect contentsChangedSinceLastFrame = contentsChanged() ? m_contentRect : IntRect(); - quadList.appendSurface(CCRenderPassDrawQuad::create(sharedQuadState, contentRect(), renderPassId, forReplica, drawTransform, filters(), backgroundFilters(), maskTextureId, contentsChangedSinceLastFrame)); + const WebKit::WebFilterOperations& filters = m_owningLayer->filters(); + const WebKit::WebFilterOperations& backgroundFilters = m_owningLayer->backgroundFilters(); + + quadList.appendSurface(CCRenderPassDrawQuad::create(sharedQuadState, contentRect(), renderPassId, forReplica, drawTransform, filters, backgroundFilters, maskTextureId, contentsChangedSinceLastFrame)); } } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h index 5410befed..9f7d876ee 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h @@ -32,7 +32,6 @@ #include "FloatRect.h" #include "IntRect.h" #include "cc/CCSharedQuadState.h" -#include <public/WebFilterOperations.h> #include <public/WebTransformationMatrix.h> #include <wtf/Noncopyable.h> #include <wtf/text/WTFString.h> @@ -63,12 +62,6 @@ public: float drawOpacity() const { return m_drawOpacity; } void setDrawOpacity(float opacity) { m_drawOpacity = opacity; } - void setFilters(const WebKit::WebFilterOperations& filters) { m_filters = filters; } - const WebKit::WebFilterOperations& filters() const { return m_filters; } - - void setBackgroundFilters(const WebKit::WebFilterOperations& filters) { m_backgroundFilters = filters; } - const WebKit::WebFilterOperations& backgroundFilters() const { return m_backgroundFilters; } - void setNearestAncestorThatMovesPixels(CCRenderSurface* surface) { m_nearestAncestorThatMovesPixels = surface; } const CCRenderSurface* nearestAncestorThatMovesPixels() const { return m_nearestAncestorThatMovesPixels; } @@ -114,12 +107,6 @@ public: Vector<CCLayerImpl*>& layerList() { return m_layerList; } int owningLayerId() const; - CCRenderSurface* targetRenderSurface() const; - - bool hasReplica() const; - - bool hasMask() const; - bool replicaHasMask() const; void resetPropertyChangedFlag() { m_surfacePropertyChanged = false; } bool surfacePropertyChanged() const; @@ -151,8 +138,6 @@ private: WebKit::WebTransformationMatrix m_replicaScreenSpaceTransform; bool m_targetSurfaceTransformsAreAnimating; bool m_screenSpaceTransformsAreAnimating; - WebKit::WebFilterOperations m_filters; - WebKit::WebFilterOperations m_backgroundFilters; // Uses the space of the surface's target surface. IntRect m_clipRect; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.cpp index 95564b635..4d52c15dd 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.cpp @@ -49,20 +49,12 @@ CCSolidColorLayerImpl::~CCSolidColorLayerImpl() { } -WebTransformationMatrix CCSolidColorLayerImpl::quadTransform() const -{ - WebTransformationMatrix solidColorTransform = drawTransform(); - solidColorTransform.translate(-bounds().width() / 2.0, -bounds().height() / 2.0); - - return solidColorTransform; -} - void CCSolidColorLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState, bool&) { // We create a series of smaller quads instead of just one large one so that the // culler can reduce the total pixels drawn. - int width = bounds().width(); - int height = bounds().height(); + int width = contentBounds().width(); + int height = contentBounds().height(); for (int x = 0; x < width; x += m_tileSize) { for (int y = 0; y < height; y += m_tileSize) { IntRect solidTileRect(x, y, min(width - x, m_tileSize), min(height - y, m_tileSize)); diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.h index 64291255f..e3005845e 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCSolidColorLayerImpl.h @@ -41,7 +41,6 @@ public: } virtual ~CCSolidColorLayerImpl(); - virtual WebKit::WebTransformationMatrix quadTransform() const OVERRIDE; virtual void appendQuads(CCQuadCuller&, const CCSharedQuadState*, bool& hadMissingTiles) OVERRIDE; protected: diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCTextureLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCTextureLayerImpl.cpp index cad376076..6df2fb6bd 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCTextureLayerImpl.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCTextureLayerImpl.cpp @@ -50,7 +50,7 @@ CCTextureLayerImpl::~CCTextureLayerImpl() void CCTextureLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState, bool&) { - IntRect quadRect(IntPoint(), bounds()); + IntRect quadRect(IntPoint(), contentBounds()); quadList.append(CCTextureDrawQuad::create(sharedQuadState, quadRect, m_textureId, m_premultipliedAlpha, m_uvRect, m_flipped)); } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp index 1b2108912..da9a10a99 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp @@ -123,21 +123,6 @@ DrawableTile* CCTiledLayerImpl::createTile(int i, int j) return addedTile; } -WebTransformationMatrix CCTiledLayerImpl::quadTransform() const -{ - WebTransformationMatrix transform = drawTransform(); - - if (contentBounds().isEmpty()) - return transform; - - transform.scaleNonUniform(bounds().width() / static_cast<double>(contentBounds().width()), - bounds().height() / static_cast<double>(contentBounds().height())); - - // Tiler draws with a different origin from other layers. - transform.translate(-contentBounds().width() / 2.0, -contentBounds().height() / 2.0); - return transform; -} - void CCTiledLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState, bool& hadMissingTiles) { const IntRect& contentRect = visibleContentRect(); diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.h index 4c82cdc8c..4052fe97c 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.h @@ -64,8 +64,6 @@ protected: bool hasTileAt(int, int) const; bool hasTextureIdForTileAt(int, int) const; - virtual WebKit::WebTransformationMatrix quadTransform() const OVERRIDE; - private: virtual const char* layerTypeAsString() const OVERRIDE { return "ContentLayer"; } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp index cc349c8e5..b524596f0 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp @@ -183,7 +183,7 @@ void CCVideoLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadSta // FIXME: When we pass quads out of process, we need to double-buffer, or // otherwise synchonize use of all textures in the quad. - IntRect quadRect(IntPoint(), bounds()); + IntRect quadRect(IntPoint(), contentBounds()); switch (m_format) { case GraphicsContext3D::LUMINANCE: { diff --git a/Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm b/Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm index fbfe6379f..4bb0951da 100644 --- a/Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm +++ b/Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm @@ -315,7 +315,7 @@ static bool isAATFont(CTFontRef ctFont) return false; } -HarfBuzzFace* FontPlatformData::harfbuzzFace() +HarfBuzzNGFace* FontPlatformData::harfbuzzFace() { CTFontRef font = ctFont(); // HarfBuzz can't handle AAT font @@ -324,7 +324,7 @@ HarfBuzzFace* FontPlatformData::harfbuzzFace() if (!m_harfbuzzFace) { uint64_t uniqueID = reinterpret_cast<uintptr_t>(font); - m_harfbuzzFace = HarfBuzzFace::create(const_cast<FontPlatformData*>(this), uniqueID); + m_harfbuzzFace = HarfBuzzNGFace::create(const_cast<FontPlatformData*>(this), uniqueID); } return m_harfbuzzFace.get(); } diff --git a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h index 83bdfe2b7..7a0e5ee56 100644 --- a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h +++ b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h @@ -29,6 +29,10 @@ #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> +#if PLATFORM(QT) +#include <QImage> +#endif + namespace WebCore { class IntSize; diff --git a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp index 503c13dd3..d6e6e2afc 100644 --- a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp @@ -36,7 +36,6 @@ using namespace WebCore; ImageGStreamer::ImageGStreamer(GstBuffer* buffer, GstCaps* caps) : m_image(0) { - QPixmap* surface = new QPixmap; GstVideoFormat format; IntSize size; int pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride; @@ -69,8 +68,7 @@ ImageGStreamer::ImageGStreamer(GstBuffer* buffer, GstCaps* caps) image.invertPixels(invertMode); #endif - surface->convertFromImage(image); - m_image = BitmapImage::create(surface); + m_image = BitmapImage::create(new QImage(image)); #ifdef GST_API_VERSION_1 if (GstVideoCropMeta* cropMeta = gst_buffer_get_video_crop_meta(buffer)) diff --git a/Source/WebCore/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.cpp b/Source/WebCore/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.cpp index 48b162474..e6ff322b4 100644 --- a/Source/WebCore/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.cpp +++ b/Source/WebCore/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.cpp @@ -240,10 +240,10 @@ bool FontPlatformData::isFixedPitch() const } #if USE(HARFBUZZ_NG) -HarfBuzzFace* FontPlatformData::harfbuzzFace() const +HarfBuzzNGFace* FontPlatformData::harfbuzzFace() const { if (!m_harfbuzzFace) - m_harfbuzzFace = HarfBuzzFace::create(const_cast<FontPlatformData*>(this), uniqueID()); + m_harfbuzzFace = HarfBuzzNGFace::create(const_cast<FontPlatformData*>(this), uniqueID()); return m_harfbuzzFace.get(); } diff --git a/Source/WebCore/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.h b/Source/WebCore/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.h index 6f4eca331..5c6faa64a 100644 --- a/Source/WebCore/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.h +++ b/Source/WebCore/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.h @@ -34,7 +34,7 @@ #include "FontOrientation.h" #include "FontRenderStyle.h" #if USE(HARFBUZZ_NG) -#include "HarfBuzzFace.h" +#include "HarfBuzzNGFace.h" #else #include "HarfBuzzSkia.h" #endif @@ -133,8 +133,7 @@ public: #endif #if USE(HARFBUZZ_NG) - // FIXME: Rename this like "harfbuzzNGFace()" because difference is too subtle. - HarfBuzzFace* harfbuzzFace() const; + HarfBuzzNGFace* harfbuzzFace() const; #else HarfbuzzFace* harfbuzzFace() const; #endif @@ -166,7 +165,7 @@ private: TextOrientation m_textOrientation; FontRenderStyle m_style; #if USE(HARFBUZZ_NG) - mutable RefPtr<HarfBuzzFace> m_harfbuzzFace; + mutable RefPtr<HarfBuzzNGFace> m_harfbuzzFace; #else mutable RefPtr<HarfbuzzFace> m_harfbuzzFace; #endif diff --git a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzFace.cpp b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFace.cpp index 49ddbabb2..7dd048b3b 100644 --- a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzFace.cpp +++ b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFace.cpp @@ -29,7 +29,7 @@ */ #include "config.h" -#include "HarfBuzzFace.h" +#include "HarfBuzzNGFace.h" #include "FontPlatformData.h" #include "hb.h" @@ -42,19 +42,19 @@ namespace WebCore { // to reduce the memory consumption because hb_face_t should be associated with // underling font data (e.g. CTFontRef, FTFace). typedef pair<hb_face_t*, unsigned> FaceCacheEntry; -typedef HashMap<uint64_t, FaceCacheEntry, WTF::IntHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t> > HarfBuzzFaceCache; +typedef HashMap<uint64_t, FaceCacheEntry, WTF::IntHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t> > HarfBuzzNGFaceCache; -static HarfBuzzFaceCache* harfbuzzFaceCache() +static HarfBuzzNGFaceCache* harfbuzzFaceCache() { - DEFINE_STATIC_LOCAL(HarfBuzzFaceCache, s_harfbuzzFaceCache, ()); + DEFINE_STATIC_LOCAL(HarfBuzzNGFaceCache, s_harfbuzzFaceCache, ()); return &s_harfbuzzFaceCache; } -HarfBuzzFace::HarfBuzzFace(FontPlatformData* platformData, uint64_t uniqueID) +HarfBuzzNGFace::HarfBuzzNGFace(FontPlatformData* platformData, uint64_t uniqueID) : m_platformData(platformData) , m_uniqueID(uniqueID) { - HarfBuzzFaceCache::iterator result = harfbuzzFaceCache()->find(m_uniqueID); + HarfBuzzNGFaceCache::iterator result = harfbuzzFaceCache()->find(m_uniqueID); if (result == harfbuzzFaceCache()->end()) { m_face = createFace(); ASSERT(m_face); @@ -65,9 +65,9 @@ HarfBuzzFace::HarfBuzzFace(FontPlatformData* platformData, uint64_t uniqueID) } } -HarfBuzzFace::~HarfBuzzFace() +HarfBuzzNGFace::~HarfBuzzNGFace() { - HarfBuzzFaceCache::iterator result = harfbuzzFaceCache()->find(m_uniqueID); + HarfBuzzNGFaceCache::iterator result = harfbuzzFaceCache()->find(m_uniqueID); ASSERT(result != harfbuzzFaceCache()->end()); ASSERT(result.get()->second.second > 0); --(result.get()->second.second); diff --git a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzFace.h b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFace.h index afc26b1b1..f3c635af0 100644 --- a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzFace.h +++ b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFace.h @@ -28,8 +28,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef HarfBuzzFace_h -#define HarfBuzzFace_h +#ifndef HarfBuzzNGFace_h +#define HarfBuzzNGFace_h #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> @@ -44,18 +44,18 @@ namespace WebCore { class FontPlatformData; -class HarfBuzzFace : public RefCounted<HarfBuzzFace> { +class HarfBuzzNGFace : public RefCounted<HarfBuzzNGFace> { public: - static PassRefPtr<HarfBuzzFace> create(FontPlatformData* platformData, uint64_t uniqueID) + static PassRefPtr<HarfBuzzNGFace> create(FontPlatformData* platformData, uint64_t uniqueID) { - return adoptRef(new HarfBuzzFace(platformData, uniqueID)); + return adoptRef(new HarfBuzzNGFace(platformData, uniqueID)); } - ~HarfBuzzFace(); + ~HarfBuzzNGFace(); hb_font_t* createFont(); private: - HarfBuzzFace(FontPlatformData*, uint64_t); + HarfBuzzNGFace(FontPlatformData*, uint64_t); hb_face_t* createFace(); @@ -66,4 +66,4 @@ private: } -#endif // HarfBuzzFace_h +#endif // HarfBuzzNGFace_h diff --git a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzFaceCoreText.cpp b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceCoreText.cpp index 966589db9..f2baba73f 100644 --- a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzFaceCoreText.cpp +++ b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceCoreText.cpp @@ -29,7 +29,7 @@ */ #include "config.h" -#include "HarfBuzzFace.h" +#include "HarfBuzzNGFace.h" #include "FontPlatformData.h" #include "HarfBuzzShaper.h" @@ -123,14 +123,14 @@ static hb_blob_t* harfbuzzCoreTextGetTable(hb_face_t* face, hb_tag_t tag, void* return hb_blob_create(data, length, HB_MEMORY_MODE_READONLY, reinterpret_cast<void*>(const_cast<__CFData*>(cfData)), releaseTableData); } -hb_face_t* HarfBuzzFace::createFace() +hb_face_t* HarfBuzzNGFace::createFace() { hb_face_t* face = hb_face_create_for_tables(harfbuzzCoreTextGetTable, m_platformData, 0); ASSERT(face); return face; } -hb_font_t* HarfBuzzFace::createFont() +hb_font_t* HarfBuzzNGFace::createFont() { hb_font_t* font = hb_font_create(m_face); hb_font_set_funcs(font, harfbuzzCoreTextGetFontFuncs(), m_platformData, 0); diff --git a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzFaceSkia.cpp b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceSkia.cpp index f29bdb91d..b9ba7d362 100644 --- a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzFaceSkia.cpp +++ b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceSkia.cpp @@ -29,7 +29,7 @@ */ #include "config.h" -#include "HarfBuzzFace.h" +#include "HarfBuzzNGFace.h" #include "FontPlatformData.h" #include "GlyphBuffer.h" @@ -157,14 +157,14 @@ static void destroyPaint(void* userData) delete paint; } -hb_face_t* HarfBuzzFace::createFace() +hb_face_t* HarfBuzzNGFace::createFace() { hb_face_t* face = hb_face_create_for_tables(harfbuzzSkiaGetTable, m_platformData, 0); ASSERT(face); return face; } -hb_font_t* HarfBuzzFace::createFont() +hb_font_t* HarfBuzzNGFace::createFont() { hb_font_t* font = hb_font_create(m_face); SkPaint* paint = new SkPaint; diff --git a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp index 68d196df1..eaf3099fd 100644 --- a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp +++ b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp @@ -32,7 +32,7 @@ #include "HarfBuzzShaper.h" #include "Font.h" -#include "HarfBuzzFace.h" +#include "HarfBuzzNGFace.h" #include "SurrogatePairAwareTextIterator.h" #include "TextRun.h" #include "hb-icu.h" @@ -272,7 +272,7 @@ bool HarfBuzzShaper::shapeHarfBuzzRuns(GlyphBuffer* glyphBuffer) hb_buffer_add_utf16(harfbuzzBuffer.get(), m_normalizedBuffer.get() + currentRun->startIndex(), currentRun->numCharacters(), 0, currentRun->numCharacters()); FontPlatformData* platformData = const_cast<FontPlatformData*>(¤tFontData->platformData()); - HarfBuzzFace* face = platformData->harfbuzzFace(); + HarfBuzzNGFace* face = platformData->harfbuzzFace(); if (!face) return false; HarfBuzzScopedPtr<hb_font_t> harfbuzzFont(face->createFont(), hb_font_destroy); diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h index 72eff9218..786303c59 100644 --- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h +++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h @@ -41,7 +41,7 @@ public: // Extensions3D methods. virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter); virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height); - + virtual Platform3DObject createVertexArrayOES(); virtual void deleteVertexArrayOES(Platform3DObject); virtual GC3Dboolean isVertexArrayOES(Platform3DObject); diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp index 5a628810d..58fc7f7de 100644 --- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp +++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp @@ -130,6 +130,16 @@ String Extensions3DOpenGLCommon::getTranslatedShaderSourceANGLE(Platform3DObject if (!isValid) return ""; +#if PLATFORM(BLACKBERRY) + // Our hardware really likes being told what precision to have (i.e., with "precision * float") + // ANGLE strips this information. + if (entry.source.contains("precision lowp float")) + translatedShaderSource = "precision lowp float;\n" + translatedShaderSource; + else if (entry.source.contains("precision mediump float")) + translatedShaderSource = "precision mediump float;\n" + translatedShaderSource; + else + translatedShaderSource = "precision highp float;\n" + translatedShaderSource; +#endif return translatedShaderSource; } diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.h b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.h index 2796d6fc9..6a61e4632 100644 --- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.h +++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.h @@ -53,13 +53,13 @@ public: virtual String getTranslatedShaderSourceANGLE(Platform3DObject); protected: + friend class Extensions3DOpenGLES; Extensions3DOpenGLCommon(GraphicsContext3D*); virtual bool supportsExtension(const String&) = 0; virtual String getExtensions() = 0; virtual void initializeAvailableExtensions(); - bool m_initializedAvailableExtensions; HashSet<String> m_availableExtensions; diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.cpp b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.cpp index fed5492c6..b3a930001 100644 --- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.cpp +++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.cpp @@ -76,7 +76,10 @@ void Extensions3DOpenGLES::blitFramebuffer(long srcX0, long srcY0, long srcX1, l void Extensions3DOpenGLES::renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height) { - notImplemented(); + if (m_glRenderbufferStorageMultisampleIMG) + renderbufferStorageMultisampleIMG(target, samples, internalformat, width, height); + else + notImplemented(); } void Extensions3DOpenGLES::copyTextureCHROMIUM(GC3Denum, Platform3DObject, Platform3DObject, GC3Dint, GC3Denum) diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.h b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.h index c3cc59571..fcf72d6b5 100644 --- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.h +++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.h @@ -32,6 +32,12 @@ #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> +#if PLATFORM(BLACKBERRY) +// See https://bugs.webkit.org/show_bug.cgi?id=91030. +#define PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC +#define PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMG PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC +#endif + namespace WebCore { class Extensions3DOpenGLES : public Extensions3DOpenGLCommon { diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp index 9a7f4250d..a4d1eb4cd 100644 --- a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp +++ b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp @@ -120,8 +120,13 @@ void GraphicsContext3D::paintRenderingResultsToCanvas(ImageBuffer* imageBuffer, } } +#if PLATFORM(BLACKBERRY) + paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight, + imageBuffer->internalSize().width(), imageBuffer->internalSize().height(), imageBuffer->context(), true); +#else paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight, imageBuffer->internalSize().width(), imageBuffer->internalSize().height(), imageBuffer->context()->platformContext()); +#endif } bool GraphicsContext3D::paintCompositedResultsToCanvas(ImageBuffer*) @@ -161,11 +166,27 @@ void GraphicsContext3D::prepareTexture() ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo); ::glActiveTexture(GL_TEXTURE0); +#if PLATFORM(BLACKBERRY) + if (!platformTexture()) { + GLuint tex = 0; + ::glGenTextures(1, &tex); + ::glBindTexture(GL_TEXTURE_2D, tex); + ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_currentWidth, m_currentHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + m_compositingLayer->setTextureID(tex); + } + ::glBindTexture(GL_TEXTURE_2D, platformTexture()); +#else ::glBindTexture(GL_TEXTURE_2D, m_compositorTexture); +#endif ::glCopyTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, 0, 0, m_currentWidth, m_currentHeight, 0); ::glBindTexture(GL_TEXTURE_2D, m_boundTexture0); ::glActiveTexture(m_activeTexture); - ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_boundFBO); + if (m_boundFBO != m_fbo) + ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_boundFBO); ::glFinish(); m_layerComposited = true; } @@ -325,7 +346,11 @@ void GraphicsContext3D::bindFramebuffer(GC3Denum target, Platform3DObject buffer if (buffer) fbo = buffer; else +#if PLATFORM(BLACKBERRY) + fbo = m_fbo; +#else fbo = (m_attrs.antialias ? m_multisampleFBO : m_fbo); +#endif if (fbo != m_boundFBO) { ::glBindFramebufferEXT(target, fbo); m_boundFBO = fbo; @@ -448,33 +473,60 @@ void GraphicsContext3D::compileShader(Platform3DObject shader) int GLCompileSuccess; ::glGetShaderiv(shader, COMPILE_STATUS, &GLCompileSuccess); + + // Populate the shader log + GLint length = 0; + ::glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); + + if (length) { + HashMap<Platform3DObject, GraphicsContext3D::ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader); + GraphicsContext3D::ShaderSourceEntry& entry = result->second; + + GLsizei size = 0; + OwnArrayPtr<GLchar> info = adoptArrayPtr(new GLchar[length]); + ::glGetShaderInfoLog(shader, length, &size, info.get()); + + entry.log = info.get(); + } // ASSERT that ANGLE generated GLSL will be accepted by OpenGL. ASSERT(GLCompileSuccess == GL_TRUE); +#if PLATFORM(BLACKBERRY) + if (GLCompileSuccess != GL_TRUE) + BlackBerry::Platform::log(BlackBerry::Platform::LogLevelWarn, "The shader validated, but didn't compile.\n"); +#endif } void GraphicsContext3D::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) { makeContextCurrent(); +#if !PLATFORM(BLACKBERRY) if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) { resolveMultisamplingIfNecessary(IntRect(x, y, width, height)); ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo); } +#endif ::glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); +#if !PLATFORM(BLACKBERRY) if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO); +#endif } void GraphicsContext3D::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height) { makeContextCurrent(); +#if !PLATFORM(BLACKBERRY) if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) { resolveMultisamplingIfNecessary(IntRect(x, y, width, height)); ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo); } +#endif ::glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); +#if !PLATFORM(BLACKBERRY) if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO); +#endif } void GraphicsContext3D::cullFace(GC3Denum mode) diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp index 26281909b..79ddcbbfd 100644 --- a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp +++ b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp @@ -99,10 +99,20 @@ void GraphicsContext3D::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsi } delete [] canvasData; +#if PLATFORM(BLACKBERRY) + // Imagination specific fix + if (m_isImaginationHardware) + readPixelsIMG(x, y, width, height, format, type, data); + else + ::glReadPixels(x, y, width, height, format, type, data); + + // Note: BlackBerries have a different anti-aliasing pipeline. +#else ::glReadPixels(x, y, width, height, format, type, data); if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO); +#endif } void GraphicsContext3D::readPixelsAndConvertToBGRAIfNecessary(int x, int y, int width, int height, unsigned char* pixels) @@ -115,6 +125,8 @@ void GraphicsContext3D::readPixelsAndConvertToBGRAIfNecessary(int x, int y, int } } +#if !PLATFORM(BLACKBERRY) +// The BlackBerry port uses a special implementation of reshapeFBOs. See GraphicsContext3DBlackBerry.cpp bool GraphicsContext3D::reshapeFBOs(const IntSize& size) { const int width = size.width(); @@ -183,6 +195,7 @@ bool GraphicsContext3D::reshapeFBOs(const IntSize& size) return mustRestoreFBO; } +#endif void GraphicsContext3D::resolveMultisamplingIfNecessary(const IntRect& rect) { diff --git a/Source/WebCore/platform/graphics/opentype/OpenTypeTypes.h b/Source/WebCore/platform/graphics/opentype/OpenTypeTypes.h index 9fc765979..2f2d51c62 100644 --- a/Source/WebCore/platform/graphics/opentype/OpenTypeTypes.h +++ b/Source/WebCore/platform/graphics/opentype/OpenTypeTypes.h @@ -25,6 +25,8 @@ #ifndef OpenTypeTypes_h #define OpenTypeTypes_h +#include "SharedBuffer.h" + namespace WebCore { namespace OpenType { @@ -67,6 +69,37 @@ typedef UInt16 GlyphID; typedef uint32_t Tag; #define OT_MAKE_TAG(ch1, ch2, ch3, ch4) ((((uint32_t)(ch4)) << 24) | (((uint32_t)(ch3)) << 16) | (((uint32_t)(ch2)) << 8) | ((uint32_t)(ch1))) +template <typename T> static const T* validateTable(const RefPtr<SharedBuffer>& buffer, size_t count = 1) +{ + if (!buffer || buffer->size() < sizeof(T) * count) + return 0; + return reinterpret_cast<const T*>(buffer->data()); +} + +struct TableBase { +protected: + static bool isValidEnd(const SharedBuffer& buffer, const void* position) + { + if (position < buffer.data()) + return false; + size_t offset = reinterpret_cast<const char*>(position) - buffer.data(); + return offset <= buffer.size(); // "<=" because end is included as valid + } + + template <typename T> static const T* validatePtr(const SharedBuffer& buffer, const void* position) + { + const T* casted = reinterpret_cast<const T*>(position); + if (!isValidEnd(buffer, &casted[1])) + return 0; + return casted; + } + + template <typename T> const T* validateOffset(const SharedBuffer& buffer, uint16_t offset) const + { + return validatePtr<T>(buffer, reinterpret_cast<const int8_t*>(this) + offset); + } +}; + } // namespace OpenType } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/opentype/OpenTypeVerticalData.cpp b/Source/WebCore/platform/graphics/opentype/OpenTypeVerticalData.cpp index 78ebcf8cb..c6d13f26b 100644 --- a/Source/WebCore/platform/graphics/opentype/OpenTypeVerticalData.cpp +++ b/Source/WebCore/platform/graphics/opentype/OpenTypeVerticalData.cpp @@ -23,6 +23,7 @@ */ #include "config.h" +#if ENABLE(OPENTYPE_VERTICAL) #include "OpenTypeVerticalData.h" #include "FloatRect.h" @@ -37,13 +38,16 @@ using namespace std; namespace WebCore { namespace OpenType { -enum { - HheaTag = OT_MAKE_TAG('h', 'h', 'e', 'a'), - HmtxTag = OT_MAKE_TAG('h', 'm', 't', 'x'), - VheaTag = OT_MAKE_TAG('v', 'h', 'e', 'a'), - VmtxTag = OT_MAKE_TAG('v', 'm', 't', 'x'), - VORGTag = OT_MAKE_TAG('V', 'O', 'R', 'G'), -}; +const uint32_t GSUBTag = OT_MAKE_TAG('G', 'S', 'U', 'B'); +const uint32_t HheaTag = OT_MAKE_TAG('h', 'h', 'e', 'a'); +const uint32_t HmtxTag = OT_MAKE_TAG('h', 'm', 't', 'x'); +const uint32_t VheaTag = OT_MAKE_TAG('v', 'h', 'e', 'a'); +const uint32_t VmtxTag = OT_MAKE_TAG('v', 'm', 't', 'x'); +const uint32_t VORGTag = OT_MAKE_TAG('V', 'O', 'R', 'G'); + +const uint32_t DefaultScriptTag = OT_MAKE_TAG('D', 'F', 'L', 'T'); + +const uint32_t VertFeatureTag = OT_MAKE_TAG('v', 'e', 'r', 't'); #pragma pack(1) @@ -108,24 +112,287 @@ struct VORGTable { size_t requiredSize() const { return sizeof(*this) + sizeof(VertOriginYMetrics) * (numVertOriginYMetrics - 1); } }; +struct CoverageTable : TableBase { + OpenType::UInt16 coverageFormat; +}; + +struct Coverage1Table : CoverageTable { + OpenType::UInt16 glyphCount; + OpenType::GlyphID glyphArray[1]; +}; + +struct Coverage2Table : CoverageTable { + OpenType::UInt16 rangeCount; + struct RangeRecord { + OpenType::GlyphID start; + OpenType::GlyphID end; + OpenType::UInt16 startCoverageIndex; + } ranges[1]; +}; + +struct SubstitutionSubTable : TableBase { + OpenType::UInt16 substFormat; + OpenType::Offset coverageOffset; + + const CoverageTable* coverage(const SharedBuffer& buffer) const { return validateOffset<CoverageTable>(buffer, coverageOffset); } +}; + +struct SingleSubstitution2SubTable : SubstitutionSubTable { + OpenType::UInt16 glyphCount; + OpenType::GlyphID substitute[1]; +}; + +struct LookupTable : TableBase { + OpenType::UInt16 lookupType; + OpenType::UInt16 lookupFlag; + OpenType::UInt16 subTableCount; + OpenType::Offset subTableOffsets[1]; + // OpenType::UInt16 markFilteringSet; this field comes after variable length, so offset is determined dynamically. + + bool getSubstitutions(HashMap<Glyph, Glyph>* map, const SharedBuffer& buffer) const + { + uint16_t countSubTable = subTableCount; + if (!isValidEnd(buffer, &subTableOffsets[countSubTable])) + return false; + if (lookupType != 1) // "Single Substitution Subtable" is all what we support + return false; + for (uint16_t i = 0; i < countSubTable; ++i) { + const SubstitutionSubTable* substitution = validateOffset<SubstitutionSubTable>(buffer, subTableOffsets[i]); + if (!substitution) + return false; + const CoverageTable* coverage = substitution->coverage(buffer); + if (!coverage) + return false; + if (substitution->substFormat != 2) // "Single Substitution Format 2" is all what we support + return false; + const SingleSubstitution2SubTable* singleSubstitution2 = validatePtr<SingleSubstitution2SubTable>(buffer, substitution); + if (!singleSubstitution2) + return false; + uint16_t countTo = singleSubstitution2->glyphCount; + if (!isValidEnd(buffer, &singleSubstitution2->substitute[countTo])) + return false; + switch (coverage->coverageFormat) { + case 1: { // Coverage Format 1 (e.g., MS Gothic) + const Coverage1Table* coverage1 = validatePtr<Coverage1Table>(buffer, coverage); + if (!coverage1) + return false; + uint16_t countFrom = coverage1->glyphCount; + if (!isValidEnd(buffer, &coverage1->glyphArray[countFrom]) || countTo != countFrom) + return false; + for (uint16_t i = 0; i < countTo; ++i) + map->set(coverage1->glyphArray[i], singleSubstitution2->substitute[i]); + break; + } + case 2: { // Coverage Format 2 (e.g., Adobe Kozuka Gothic) + const Coverage2Table* coverage2 = validatePtr<Coverage2Table>(buffer, coverage); + if (!coverage2) + return false; + uint16_t countRange = coverage2->rangeCount; + if (!isValidEnd(buffer, &coverage2->ranges[countRange])) + return false; + for (uint16_t i = 0, indexTo = 0; i < countRange; ++i) { + uint16_t from = coverage2->ranges[i].start; + uint16_t fromEnd = coverage2->ranges[i].end + 1; // OpenType "end" is inclusive + if (indexTo + (fromEnd - from) > countTo) + return false; + for (; from != fromEnd; ++from, ++indexTo) + map->set(from, singleSubstitution2->substitute[indexTo]); + } + break; + } + default: + return false; + } + } + return true; + } +}; + +struct LookupList : TableBase { + OpenType::UInt16 lookupCount; + OpenType::Offset lookupOffsets[1]; + + const LookupTable* lookup(uint16_t index, const SharedBuffer& buffer) const + { + uint16_t count = lookupCount; + if (index >= count || !isValidEnd(buffer, &lookupOffsets[count])) + return 0; + return validateOffset<LookupTable>(buffer, lookupOffsets[index]); + } +}; + +struct FeatureTable : TableBase { + OpenType::Offset featureParams; + OpenType::UInt16 lookupCount; + OpenType::UInt16 lookupListIndex[1]; + + bool getGlyphSubstitutions(const LookupList* lookups, HashMap<Glyph, Glyph>* map, const SharedBuffer& buffer) const + { + uint16_t count = lookupCount; + if (!isValidEnd(buffer, &lookupListIndex[count])) + return false; + for (uint16_t i = 0; i < count; ++i) { + const LookupTable* lookup = lookups->lookup(lookupListIndex[i], buffer); + if (!lookup || !lookup->getSubstitutions(map, buffer)) + return false; + } + return true; + } +}; + +struct FeatureList : TableBase { + OpenType::UInt16 featureCount; + struct FeatureRecord { + OpenType::Tag featureTag; + OpenType::Offset featureOffset; + } features[1]; + + const FeatureTable* feature(uint16_t index, OpenType::Tag tag, const SharedBuffer& buffer) const + { + uint16_t count = featureCount; + if (index >= count || !isValidEnd(buffer, &features[count])) + return 0; + if (features[index].featureTag == tag) + return validateOffset<FeatureTable>(buffer, features[index].featureOffset); + return 0; + } +}; + +struct LangSysTable : TableBase { + OpenType::Offset lookupOrder; + OpenType::UInt16 reqFeatureIndex; + OpenType::UInt16 featureCount; + OpenType::UInt16 featureIndex[1]; + + const FeatureTable* feature(OpenType::Tag featureTag, const FeatureList* features, const SharedBuffer& buffer) const + { + uint16_t count = featureCount; + if (!isValidEnd(buffer, &featureIndex[count])) + return 0; + for (uint16_t i = 0; i < count; ++i) { + const FeatureTable* featureTable = features->feature(featureIndex[i], featureTag, buffer); + if (featureTable) + return featureTable; + } + return 0; + } +}; + +struct ScriptTable : TableBase { + OpenType::Offset defaultLangSysOffset; + OpenType::UInt16 langSysCount; + struct LangSysRecord { + OpenType::Tag langSysTag; + OpenType::Offset langSysOffset; + } langSysRecords[1]; + + const LangSysTable* defaultLangSys(const SharedBuffer& buffer) const + { + uint16_t count = langSysCount; + if (!isValidEnd(buffer, &langSysRecords[count])) + return 0; + uint16_t offset = defaultLangSysOffset; + if (offset) + return validateOffset<LangSysTable>(buffer, offset); + if (count) + return validateOffset<LangSysTable>(buffer, langSysRecords[0].langSysOffset); + return 0; + } +}; + +struct ScriptList : TableBase { + OpenType::UInt16 scriptCount; + struct ScriptRecord { + OpenType::Tag scriptTag; + OpenType::Offset scriptOffset; + } scripts[1]; + + const ScriptTable* script(OpenType::Tag tag, const SharedBuffer& buffer) const + { + uint16_t count = scriptCount; + if (!isValidEnd(buffer, &scripts[count])) + return 0; + for (uint16_t i = 0; i < count; ++i) { + if (scripts[i].scriptTag == tag) + return validateOffset<ScriptTable>(buffer, scripts[i].scriptOffset); + } + return 0; + } + + const ScriptTable* defaultScript(const SharedBuffer& buffer) const + { + uint16_t count = scriptCount; + if (!count || !isValidEnd(buffer, &scripts[count])) + return 0; + const ScriptTable* scriptOfDefaultTag = script(OpenType::DefaultScriptTag, buffer); + if (scriptOfDefaultTag) + return scriptOfDefaultTag; + return validateOffset<ScriptTable>(buffer, scripts[0].scriptOffset); + } + + const LangSysTable* defaultLangSys(const SharedBuffer& buffer) const + { + const ScriptTable* scriptTable = defaultScript(buffer); + if (!scriptTable) + return 0; + return scriptTable->defaultLangSys(buffer); + } +}; + +struct GSUBTable : TableBase { + OpenType::Fixed version; + OpenType::Offset scriptListOffset; + OpenType::Offset featureListOffset; + OpenType::Offset lookupListOffset; + + const ScriptList* scriptList(const SharedBuffer& buffer) const { return validateOffset<ScriptList>(buffer, scriptListOffset); } + const FeatureList* featureList(const SharedBuffer& buffer) const { return validateOffset<FeatureList>(buffer, featureListOffset); } + const LookupList* lookupList(const SharedBuffer& buffer) const { return validateOffset<LookupList>(buffer, lookupListOffset); } + + const LangSysTable* defaultLangSys(const SharedBuffer& buffer) const + { + const ScriptList* scripts = scriptList(buffer); + if (!scripts) + return 0; + return scripts->defaultLangSys(buffer); + } + + const FeatureTable* feature(OpenType::Tag featureTag, const SharedBuffer& buffer) const + { + const LangSysTable* langSys = defaultLangSys(buffer); + const FeatureList* features = featureList(buffer); + if (!langSys || !features) + return 0; + return langSys->feature(featureTag, features, buffer); + } + + bool getVerticalGlyphSubstitutions(HashMap<Glyph, Glyph>* map, const SharedBuffer& buffer) const + { + const FeatureTable* verticalFeatureTable = feature(OpenType::VertFeatureTag, buffer); + if (!verticalFeatureTable) + return false; + const LookupList* lookups = lookupList(buffer); + return lookups && verticalFeatureTable->getGlyphSubstitutions(lookups, map, buffer); + } +}; + #pragma pack() } // namespace OpenType -template <typename T> const T* validatedPtr(const RefPtr<SharedBuffer>& buffer, size_t count = 1) +OpenTypeVerticalData::OpenTypeVerticalData(const FontPlatformData& platformData) + : m_defaultVertOriginY(0) { - if (!buffer || buffer->size() < sizeof(T) * count) - return 0; - return reinterpret_cast<const T*>(buffer->data()); + loadMetrics(platformData); + loadVerticalGlyphSubstitutions(platformData); } -OpenTypeVerticalData::OpenTypeVerticalData(const FontPlatformData& platformData) - : m_defaultVertOriginY(0) +void OpenTypeVerticalData::loadMetrics(const FontPlatformData& platformData) { // Load hhea and hmtx to get x-component of vertical origins. // If these tables are missing, it's not an OpenType font. RefPtr<SharedBuffer> buffer = platformData.openTypeTable(OpenType::HheaTag); - const OpenType::HheaTable* hhea = validatedPtr<OpenType::HheaTable>(buffer); + const OpenType::HheaTable* hhea = OpenType::validateTable<OpenType::HheaTable>(buffer); if (!hhea) return; uint16_t countHmtxEntries = hhea->numberOfHMetrics; @@ -135,7 +402,7 @@ OpenTypeVerticalData::OpenTypeVerticalData(const FontPlatformData& platformData) } buffer = platformData.openTypeTable(OpenType::HmtxTag); - const OpenType::HmtxTable* hmtx = validatedPtr<OpenType::HmtxTable>(buffer, countHmtxEntries); + const OpenType::HmtxTable* hmtx = OpenType::validateTable<OpenType::HmtxTable>(buffer, countHmtxEntries); if (!hmtx) { LOG_ERROR("hhea exists but hmtx does not (or broken)"); return; @@ -146,7 +413,7 @@ OpenTypeVerticalData::OpenTypeVerticalData(const FontPlatformData& platformData) // Load vhea first. This table is required for fonts that support vertical flow. buffer = platformData.openTypeTable(OpenType::VheaTag); - const OpenType::VheaTable* vhea = validatedPtr<OpenType::VheaTable>(buffer); + const OpenType::VheaTable* vhea = OpenType::validateTable<OpenType::VheaTable>(buffer); if (!vhea) return; uint16_t countVmtxEntries = vhea->numOfLongVerMetrics; @@ -157,7 +424,7 @@ OpenTypeVerticalData::OpenTypeVerticalData(const FontPlatformData& platformData) // Load VORG. This table is optional. buffer = platformData.openTypeTable(OpenType::VORGTag); - const OpenType::VORGTable* vorg = validatedPtr<OpenType::VORGTable>(buffer); + const OpenType::VORGTable* vorg = OpenType::validateTable<OpenType::VORGTable>(buffer); if (vorg && buffer->size() >= vorg->requiredSize()) { m_defaultVertOriginY = vorg->defaultVertOriginY; uint16_t countVertOriginYMetrics = vorg->numVertOriginYMetrics; @@ -174,7 +441,7 @@ OpenTypeVerticalData::OpenTypeVerticalData(const FontPlatformData& platformData) // Load vmtx then. This table is required for fonts that support vertical flow. buffer = platformData.openTypeTable(OpenType::VmtxTag); - const OpenType::VmtxTable* vmtx = validatedPtr<OpenType::VmtxTable>(buffer, countVmtxEntries); + const OpenType::VmtxTable* vmtx = OpenType::validateTable<OpenType::VmtxTable>(buffer, countVmtxEntries); if (!vmtx) { LOG_ERROR("vhea exists but vmtx does not (or broken)"); return; @@ -205,6 +472,14 @@ OpenTypeVerticalData::OpenTypeVerticalData(const FontPlatformData& platformData) } } +void OpenTypeVerticalData::loadVerticalGlyphSubstitutions(const FontPlatformData& platformData) +{ + RefPtr<SharedBuffer> buffer = platformData.openTypeTable(OpenType::GSUBTag); + const OpenType::GSUBTable* gsub = OpenType::validateTable<OpenType::GSUBTable>(buffer); + if (gsub) + gsub->getVerticalGlyphSubstitutions(&m_verticalGlyphMap, *buffer.get()); +} + float OpenTypeVerticalData::advanceHeight(const SimpleFontData* font, Glyph glyph) const { size_t countHeights = m_advanceHeights.size(); @@ -261,4 +536,23 @@ void OpenTypeVerticalData::getVerticalTranslationsForGlyphs(const SimpleFontData } } +void OpenTypeVerticalData::substituteWithVerticalGlyphs(const SimpleFontData* font, GlyphPage* glyphPage, unsigned offset, unsigned length) const +{ + const HashMap<Glyph, Glyph>& map = m_verticalGlyphMap; + if (map.isEmpty()) + return; + + for (unsigned index = offset, end = offset + length; index < end; ++index) { + Glyph glyph = glyphPage->glyphAt(index); + if (glyph) { + ASSERT(glyphPage->glyphDataForIndex(index).fontData == font); + Glyph to = map.get(glyph); + if (to) + glyphPage->setGlyphDataForIndex(index, to, font); + } + } +} + } // namespace WebCore + +#endif // ENABLE(OPENTYPE_VERTICAL) diff --git a/Source/WebCore/platform/graphics/opentype/OpenTypeVerticalData.h b/Source/WebCore/platform/graphics/opentype/OpenTypeVerticalData.h index 85e4ee7a1..f0739575a 100644 --- a/Source/WebCore/platform/graphics/opentype/OpenTypeVerticalData.h +++ b/Source/WebCore/platform/graphics/opentype/OpenTypeVerticalData.h @@ -43,10 +43,14 @@ public: bool hasVerticalMetrics() const { return !m_advanceHeights.isEmpty(); } float advanceHeight(const SimpleFontData*, Glyph) const; void getVerticalTranslationsForGlyphs(const SimpleFontData*, const Glyph*, size_t, float* outXYArray) const; + void substituteWithVerticalGlyphs(const SimpleFontData*, GlyphPage*, unsigned offset, unsigned length) const; private: + void loadMetrics(const FontPlatformData&); + void loadVerticalGlyphSubstitutions(const FontPlatformData&); bool hasVORG() const { return !m_vertOriginY.isEmpty(); } + HashMap<Glyph, Glyph> m_verticalGlyphMap; Vector<uint16_t> m_advanceWidths; Vector<uint16_t> m_advanceHeights; Vector<int16_t> m_topSideBearings; diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp index 84729d992..1136fb8d1 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp +++ b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp @@ -495,23 +495,16 @@ bool GraphicsContext3D::getImageData(Image* image, if (!image) return false; - QImage qtImage; + QImage nativeImage; // Is image already loaded? If not, load it. if (image->data()) - qtImage = QImage::fromData(reinterpret_cast<const uchar*>(image->data()->data()), image->data()->size()); - else { - QPixmap* nativePixmap = image->nativeImageForCurrentFrame(); -#if HAVE(QT5) - // With QPA, we can avoid a deep copy. - qtImage = *nativePixmap->handle()->buffer(); -#else - // This might be a deep copy, depending on other references to the pixmap. - qtImage = nativePixmap->toImage(); -#endif - } + nativeImage = QImage::fromData(reinterpret_cast<const uchar*>(image->data()->data()), image->data()->size()); + else + nativeImage = *image->nativeImageForCurrentFrame(); + AlphaOp alphaOp = AlphaDoNothing; - switch (qtImage.format()) { + switch (nativeImage.format()) { case QImage::Format_RGB32: // For opaque images, we should not premultiply or unmultiply alpha. break; @@ -525,7 +518,7 @@ bool GraphicsContext3D::getImageData(Image* image, break; default: // The image has a format that is not supported in packPixels. We have to convert it here. - qtImage = qtImage.convertToFormat(premultiplyAlpha ? QImage::Format_ARGB32_Premultiplied : QImage::Format_ARGB32); + nativeImage = nativeImage.convertToFormat(premultiplyAlpha ? QImage::Format_ARGB32_Premultiplied : QImage::Format_ARGB32); break; } @@ -536,7 +529,7 @@ bool GraphicsContext3D::getImageData(Image* image, outputVector.resize(packedSize); - return packPixels(qtImage.constBits(), SourceFormatBGRA8, image->width(), image->height(), 0, format, type, alphaOp, outputVector.data()); + return packPixels(nativeImage.constBits(), SourceFormatBGRA8, image->width(), image->height(), 0, format, type, alphaOp, outputVector.data()); } void GraphicsContext3D::setContextLostCallback(PassOwnPtr<ContextLostCallback>) diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index c034f64b3..611efc6a2 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -1022,7 +1022,7 @@ void GraphicsContext::clearPlatformShadow() m_data->shadow->clear(); } -void GraphicsContext::pushTransparencyLayerInternal(const QRect &rect, qreal opacity, QPixmap& alphaMask) +void GraphicsContext::pushTransparencyLayerInternal(const QRect &rect, qreal opacity, QImage& alphaMask) { QPainter* p = m_data->p(); @@ -1057,7 +1057,7 @@ void GraphicsContext::beginPlatformTransparencyLayer(float opacity) h = int(qBound(qreal(0), deviceClip.height(), (qreal)h) + 2); } - QPixmap emptyAlphaMask; + QImage emptyAlphaMask; m_data->layers.push(new TransparencyLayer(p, QRect(x, y, w, h), opacity, emptyAlphaMask)); ++m_data->layerCount; } @@ -1071,7 +1071,7 @@ void GraphicsContext::endPlatformTransparencyLayer() if (!layer->alphaMask.isNull()) { layer->painter.resetTransform(); layer->painter.setCompositionMode(QPainter::CompositionMode_DestinationIn); - layer->painter.drawPixmap(QPoint(), layer->alphaMask); + layer->painter.drawImage(QPoint(), layer->alphaMask); } else --m_data->layerCount; // see the comment for layerCount layer->painter.end(); @@ -1080,7 +1080,7 @@ void GraphicsContext::endPlatformTransparencyLayer() p->save(); p->resetTransform(); p->setOpacity(layer->opacity); - p->drawPixmap(layer->offset, layer->pixmap); + p->drawImage(layer->offset, layer->image); p->restore(); delete layer; diff --git a/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.h b/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.h index 9cf782bea..94065d3a6 100644 --- a/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.h +++ b/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.h @@ -25,8 +25,8 @@ #include "Image.h" +#include <QImage> #include <QPainter> -#include <QPixmap> #include <wtf/OwnPtr.h> #include <wtf/RefPtr.h> @@ -39,9 +39,7 @@ class ImageBufferData { public: ImageBufferData(const IntSize&); - QImage toQImage() const; - - QPixmap m_pixmap; + QImage m_nativeImage; OwnPtr<QPainter> m_painter; RefPtr<Image> m_image; }; diff --git a/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp index b9b9ebf6c..32dd39a5f 100644 --- a/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp +++ b/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp @@ -32,6 +32,7 @@ #include "GraphicsContext.h" #include "ImageData.h" #include "MIMETypeRegistry.h" +#include "NativeImageQt.h" #include "StillImageQt.h" #include "TransparencyLayer.h" #include <wtf/text/CString.h> @@ -42,23 +43,22 @@ #include <QImage> #include <QImageWriter> #include <QPainter> -#include <QPixmap> #include <math.h> namespace WebCore { ImageBufferData::ImageBufferData(const IntSize& size) - : m_pixmap(size) + : m_nativeImage(size, NativeImageQt::defaultFormatForAlphaEnabledImages()) { - if (m_pixmap.isNull()) + if (m_nativeImage.isNull()) return; - m_pixmap.fill(QColor(Qt::transparent)); + m_nativeImage.fill(QColor(Qt::transparent)); QPainter* painter = new QPainter; m_painter = adoptPtr(painter); - if (!painter->begin(&m_pixmap)) + if (!painter->begin(&m_nativeImage)) return; // Since ImageBuffer is used mainly for Canvas, explicitly initialize @@ -76,22 +76,7 @@ ImageBufferData::ImageBufferData(const IntSize& size) painter->setBrush(brush); painter->setCompositionMode(QPainter::CompositionMode_SourceOver); - m_image = StillImage::createForRendering(&m_pixmap); -} - -QImage ImageBufferData::toQImage() const -{ - QPaintEngine* paintEngine = m_pixmap.paintEngine(); - if (!paintEngine || paintEngine->type() != QPaintEngine::Raster) - return m_pixmap.toImage(); - - // QRasterPixmapData::toImage() will deep-copy the backing QImage if there's an active QPainter on it. - // For performance reasons, we don't want that here, so we temporarily redirect the paint engine. - QPaintDevice* currentPaintDevice = paintEngine->paintDevice(); - paintEngine->setPaintDevice(0); - QImage image = m_pixmap.toImage(); - paintEngine->setPaintDevice(currentPaintDevice); - return image; + m_image = StillImage::createForRendering(&m_nativeImage); } ImageBuffer::ImageBuffer(const IntSize& size, float /* resolutionScale */, ColorSpace, RenderingMode, DeferralMode, bool& success) @@ -120,9 +105,9 @@ GraphicsContext* ImageBuffer::context() const PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior) const { if (copyBehavior == CopyBackingStore) - return StillImage::create(m_data.m_pixmap); + return StillImage::create(m_data.m_nativeImage); - return StillImage::createForRendering(&m_data.m_pixmap); + return StillImage::createForRendering(&m_data.m_nativeImage); } void ImageBuffer::draw(GraphicsContext* destContext, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, @@ -149,12 +134,12 @@ void ImageBuffer::drawPattern(GraphicsContext* destContext, const FloatRect& src void ImageBuffer::clip(GraphicsContext* context, const FloatRect& floatRect) const { - QPixmap* nativeImage = m_data.m_image->nativeImageForCurrentFrame(); + QImage* nativeImage = m_data.m_image->nativeImageForCurrentFrame(); if (!nativeImage) return; IntRect rect = enclosingIntRect(floatRect); - QPixmap alphaMask = *nativeImage; + QImage alphaMask = *nativeImage; context->pushTransparencyLayerInternal(rect, 1.0, alphaMask); } @@ -165,7 +150,7 @@ void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable) if (isPainting) m_data.m_painter->end(); - QImage image = m_data.toQImage().convertToFormat(QImage::Format_ARGB32); + QImage image = m_data.m_nativeImage.convertToFormat(QImage::Format_ARGB32); ASSERT(!image.isNull()); uchar* bits = image.bits(); @@ -182,10 +167,10 @@ void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable) } } - m_data.m_pixmap = QPixmap::fromImage(image); + m_data.m_nativeImage = image; if (isPainting) - m_data.m_painter->begin(&m_data.m_pixmap); + m_data.m_painter->begin(&m_data.m_nativeImage); } template <Multiply multiplied> @@ -224,7 +209,7 @@ PassRefPtr<Uint8ClampedArray> getImageData(const IntRect& rect, const ImageBuffe int numRows = endy - originy; // NOTE: For unmultiplied data, we undo the premultiplication below. - QImage image = imageData.toQImage().convertToFormat(QImage::Format_ARGB32_Premultiplied); + QImage image = imageData.m_nativeImage.convertToFormat(NativeImageQt::defaultFormatForAlphaEnabledImages()); ASSERT(!image.isNull()); @@ -358,7 +343,7 @@ void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, c bool isPainting = m_data.m_painter->isActive(); if (!isPainting) - m_data.m_painter->begin(&m_data.m_pixmap); + m_data.m_painter->begin(&m_data.m_nativeImage); else { m_data.m_painter->save(); @@ -377,7 +362,7 @@ void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, c m_data.m_painter->restore(); } -static bool encodeImage(const QPixmap& pixmap, const String& format, const double* quality, QByteArray& data) +static bool encodeImage(const QImage& image, const String& format, const double* quality, QByteArray& data) { int compressionQuality = 100; if (quality && *quality >= 0.0 && *quality <= 1.0) @@ -385,7 +370,7 @@ static bool encodeImage(const QPixmap& pixmap, const String& format, const doubl QBuffer buffer(&data); buffer.open(QBuffer::WriteOnly); - bool success = pixmap.save(&buffer, format.utf8().data(), compressionQuality); + bool success = image.save(&buffer, format.utf8().data(), compressionQuality); buffer.close(); return success; @@ -397,10 +382,10 @@ String ImageBuffer::toDataURL(const String& mimeType, const double* quality, Coo // QImageWriter does not support mimetypes. It does support Qt image formats (png, // gif, jpeg..., xpm) so skip the image/ to get the Qt image format used to encode - // the m_pixmap image. + // the m_nativeImage image. QByteArray data; - if (!encodeImage(m_data.m_pixmap, mimeType.substring(sizeof "image"), quality, data)) + if (!encodeImage(m_data.m_nativeImage, mimeType.substring(sizeof "image"), quality, data)) return "data:,"; return "data:" + mimeType + ";base64," + data.toBase64().data(); diff --git a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp index e03636f20..f039e4300 100644 --- a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp +++ b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp @@ -272,9 +272,7 @@ NativeImagePtr ImageFrame::asNewNativeImage() const else format = QImage::Format_RGB32; - QImage img(reinterpret_cast<uchar*>(m_bytes), m_size.width(), m_size.height(), sizeof(PixelData) * m_size.width(), format); - - return new QPixmap(QPixmap::fromImage(img)); + return new QImage(reinterpret_cast<uchar*>(m_bytes), m_size.width(), m_size.height(), sizeof(PixelData) * m_size.width(), format); } } diff --git a/Source/WebCore/platform/graphics/qt/ImageQt.cpp b/Source/WebCore/platform/graphics/qt/ImageQt.cpp index e098e09f5..10fe1feb6 100644 --- a/Source/WebCore/platform/graphics/qt/ImageQt.cpp +++ b/Source/WebCore/platform/graphics/qt/ImageQt.cpp @@ -37,6 +37,7 @@ #include "FloatRect.h" #include "GraphicsContext.h" #include "ImageObserver.h" +#include "NativeImageQt.h" #include "PlatformString.h" #include "ShadowBlur.h" #include "StillImageQt.h" @@ -55,7 +56,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP, int hbitmapFormat = 0); #endif -typedef QHash<QByteArray, QPixmap> WebGraphicHash; +typedef QHash<QByteArray, QImage> WebGraphicHash; Q_GLOBAL_STATIC(WebGraphicHash, _graphics) static void earlyClearGraphics() @@ -69,28 +70,28 @@ static WebGraphicHash* graphics() if (hash->isEmpty()) { - // prevent ~QPixmap running after ~QApplication (leaks native pixmaps) + // prevent ~QImage running after ~QApplication (leaks native images) qAddPostRoutine(earlyClearGraphics); // QWebSettings::MissingImageGraphic - hash->insert("missingImage", QPixmap(QLatin1String(":webkit/resources/missingImage.png"))); + hash->insert("missingImage", QImage(QLatin1String(":webkit/resources/missingImage.png"))); // QWebSettings::MissingPluginGraphic - hash->insert("nullPlugin", QPixmap(QLatin1String(":webkit/resources/nullPlugin.png"))); + hash->insert("nullPlugin", QImage(QLatin1String(":webkit/resources/nullPlugin.png"))); // QWebSettings::DefaultFrameIconGraphic - hash->insert("urlIcon", QPixmap(QLatin1String(":webkit/resources/urlIcon.png"))); + hash->insert("urlIcon", QImage(QLatin1String(":webkit/resources/urlIcon.png"))); // QWebSettings::TextAreaSizeGripCornerGraphic - hash->insert("textAreaResizeCorner", QPixmap(QLatin1String(":webkit/resources/textAreaResizeCorner.png"))); + hash->insert("textAreaResizeCorner", QImage(QLatin1String(":webkit/resources/textAreaResizeCorner.png"))); // QWebSettings::DeleteButtonGraphic - hash->insert("deleteButton", QPixmap(QLatin1String(":webkit/resources/deleteButton.png"))); + hash->insert("deleteButton", QImage(QLatin1String(":webkit/resources/deleteButton.png"))); // QWebSettings::InputSpeechButtonGraphic - hash->insert("inputSpeech", QPixmap(QLatin1String(":webkit/resources/inputSpeech.png"))); + hash->insert("inputSpeech", QImage(QLatin1String(":webkit/resources/inputSpeech.png"))); } return hash; } // This function loads resources into WebKit -static QPixmap loadResourcePixmap(const char *name) +static QImage loadResourceImage(const char *name) { return graphics()->value(name); } @@ -117,23 +118,23 @@ bool FrameData::clear(bool clearMetadata) PassRefPtr<Image> Image::loadPlatformResource(const char* name) { - return StillImage::create(loadResourcePixmap(name)); + return StillImage::create(loadResourceImage(name)); } -void Image::setPlatformResource(const char* name, const QPixmap& pixmap) +void Image::setPlatformResource(const char* name, const QImage& image) { WebGraphicHash* h = graphics(); - if (pixmap.isNull()) + if (image.isNull()) h->remove(name); else - h->insert(name, pixmap); + h->insert(name, image); } void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace, CompositeOperator op, const FloatRect& destRect) { - QPixmap* framePixmap = nativeImageForCurrentFrame(); - if (!framePixmap) // If it's too early we won't have an image yet. + QImage* frameImage = nativeImageForCurrentFrame(); + if (!frameImage) // If it's too early we won't have an image yet. return; #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) @@ -148,34 +149,38 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const if (!dr.width() || !dr.height() || !tr.width() || !tr.height()) return; - QPixmap pixmap = *framePixmap; - if (tr.x() || tr.y() || tr.width() != pixmap.width() || tr.height() != pixmap.height()) - pixmap = pixmap.copy(tr); + QImage image = *frameImage; + if (tr.x() || tr.y() || tr.width() != image.width() || tr.height() != image.height()) + image = image.copy(tr); CompositeOperator previousOperator = ctxt->compositeOperation(); - ctxt->setCompositeOperation(!pixmap.hasAlpha() && op == CompositeSourceOver ? CompositeCopy : op); + ctxt->setCompositeOperation(!image.hasAlphaChannel() && op == CompositeSourceOver ? CompositeCopy : op); QPainter* p = ctxt->platformContext(); QTransform transform(patternTransform); - // If this would draw more than one scaled tile, we scale the pixmap first and then use the result to draw. + // If this would draw more than one scaled tile, we scale the image first and then use the result to draw. if (transform.type() == QTransform::TxScale) { QRectF tileRectInTargetCoords = (transform * QTransform().translate(phase.x(), phase.y())).mapRect(tr); bool tileWillBePaintedOnlyOnce = tileRectInTargetCoords.contains(dr); if (!tileWillBePaintedOnlyOnce) { - QSizeF scaledSize(float(pixmap.width()) * transform.m11(), float(pixmap.height()) * transform.m22()); - QPixmap scaledPixmap(scaledSize.toSize()); - if (pixmap.hasAlpha()) - scaledPixmap.fill(Qt::transparent); + QSizeF scaledSize(float(image.width()) * transform.m11(), float(image.height()) * transform.m22()); + QImage scaledImage; + if (image.hasAlphaChannel()) { + scaledImage = QImage(scaledSize.toSize(), NativeImageQt::defaultFormatForAlphaEnabledImages()); + scaledImage.fill(Qt::transparent); + } else + scaledImage = QImage(scaledSize.toSize(), NativeImageQt::defaultFormatForOpaqueImages()); + { - QPainter painter(&scaledPixmap); + QPainter painter(&scaledImage); painter.setCompositionMode(QPainter::CompositionMode_Source); painter.setRenderHints(p->renderHints()); - painter.drawPixmap(QRect(0, 0, scaledPixmap.width(), scaledPixmap.height()), pixmap); + painter.drawImage(QRect(0, 0, scaledImage.width(), scaledImage.height()), image); } - pixmap = scaledPixmap; + image = scaledImage; transform = QTransform::fromTranslate(transform.dx(), transform.dy()); } } @@ -184,7 +189,7 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const transform *= QTransform().translate(phase.x(), phase.y()); transform.translate(tr.x(), tr.y()); - QBrush b(pixmap); + QBrush b(image); b.setTransform(transform); p->fillRect(dr, b); @@ -194,7 +199,7 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const imageObserver()->didDraw(this); } -BitmapImage::BitmapImage(QPixmap* pixmap, ImageObserver* observer) +BitmapImage::BitmapImage(QImage* image, ImageObserver* observer) : Image(observer) , m_currentFrame(0) , m_frames(0) @@ -212,14 +217,14 @@ BitmapImage::BitmapImage(QPixmap* pixmap, ImageObserver* observer) , m_sizeAvailable(true) , m_haveFrameCount(true) { - int width = pixmap->width(); - int height = pixmap->height(); + int width = image->width(); + int height = image->height(); m_decodedSize = width * height * 4; m_size = IntSize(width, height); m_frames.grow(1); - m_frames[0].m_frame = pixmap; - m_frames[0].m_hasAlpha = pixmap->hasAlpha(); + m_frames[0].m_frame = image; + m_frames[0].m_hasAlpha = image->hasAlphaChannel(); m_frames[0].m_haveMetadata = true; checkForSolidColor(); } @@ -240,7 +245,8 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, if (normalizedSrc.isEmpty() || normalizedDst.isEmpty()) return; - QPixmap* image = nativeImageForCurrentFrame(); + QImage* image = nativeImageForCurrentFrame(); + if (!image) return; @@ -254,19 +260,19 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, #endif CompositeOperator previousOperator = ctxt->compositeOperation(); - ctxt->setCompositeOperation(!image->hasAlpha() && op == CompositeSourceOver ? CompositeCopy : op); + ctxt->setCompositeOperation(!image->hasAlphaChannel() && op == CompositeSourceOver ? CompositeCopy : op); if (ctxt->hasShadow()) { ShadowBlur* shadow = ctxt->shadowBlur(); GraphicsContext* shadowContext = shadow->beginShadowLayer(ctxt, normalizedDst); if (shadowContext) { QPainter* shadowPainter = shadowContext->platformContext(); - shadowPainter->drawPixmap(normalizedDst, *image, normalizedSrc); + shadowPainter->drawImage(normalizedDst, *image, normalizedSrc); shadow->endShadowLayer(ctxt); } } - ctxt->platformContext()->drawPixmap(normalizedDst, *image, normalizedSrc); + ctxt->platformContext()->drawImage(normalizedDst, *image, normalizedSrc); ctxt->setCompositeOperation(previousOperator); @@ -282,24 +288,24 @@ void BitmapImage::checkForSolidColor() if (frameCount() > 1) return; - QPixmap* framePixmap = frameAtIndex(0); - if (!framePixmap || framePixmap->width() != 1 || framePixmap->height() != 1) + QImage* frameImage = frameAtIndex(0); + if (!frameImage || frameImage->width() != 1 || frameImage->height() != 1) return; m_isSolidColor = true; - m_solidColor = QColor::fromRgba(framePixmap->toImage().pixel(0, 0)); + m_solidColor = QColor::fromRgba(frameImage->pixel(0, 0)); } #if OS(WINDOWS) PassRefPtr<BitmapImage> BitmapImage::create(HBITMAP hBitmap) { #if HAVE(QT5) - QPixmap* qPixmap = new QPixmap(qt_pixmapFromWinHBITMAP(hBitmap)); + QImage* nativeImage = new QImage(qt_pixmapFromWinHBITMAP(hBitmap).toImage()); #else - QPixmap* qPixmap = new QPixmap(QPixmap::fromWinHBITMAP(hBitmap)); + QImage* nativeImage = new QImage(QPixmap::fromWinHBITMAP(hBitmap).toImage()); #endif - return BitmapImage::create(qPixmap); + return BitmapImage::create(nativeImage); } #endif diff --git a/Source/WebCore/bindings/v8/ScriptControllerQt.cpp b/Source/WebCore/platform/graphics/qt/NativeImageQt.h index 1d7f79476..0fd1d2cb2 100644 --- a/Source/WebCore/bindings/v8/ScriptControllerQt.cpp +++ b/Source/WebCore/platform/graphics/qt/NativeImageQt.h @@ -1,7 +1,5 @@ /* - * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) - * - * All rights reserved. + * Copyright (C) 2012 Zoltan Horvath (zoltan@webkit.org) 2012 University of Szeged. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -12,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -25,25 +23,26 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "config.h" -#include "ScriptController.h" +#ifndef NativeImageQt_h +#define NativeImageQt_h -#include <QtQml/QJSEngine> +#include <QImage> namespace WebCore { -QJSEngine* ScriptController::qtScriptEngine() -{ - if (!m_qtScriptEngine) { - v8::HandleScope handleScope; - v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(m_frame); - v8::Context::Scope scope(v8Context); - if (v8Context.IsEmpty()) - return 0; - m_qtScriptEngine = adoptPtr(new QJSEngine(QJSEngine::AdoptCurrentContext)); - } - return m_qtScriptEngine.get(); -} +class NativeImageQt { +public: + static QImage::Format defaultFormatForAlphaEnabledImages() + { + return QImage::Format_ARGB32_Premultiplied; + } + + static QImage::Format defaultFormatForOpaqueImages() + { + return QImage::Format_RGB32; + } +}; } -// vim: ts=4 sw=4 et + +#endif // NativeImageQt_h diff --git a/Source/WebCore/platform/graphics/qt/PatternQt.cpp b/Source/WebCore/platform/graphics/qt/PatternQt.cpp index 7aae62599..5c9412215 100644 --- a/Source/WebCore/platform/graphics/qt/PatternQt.cpp +++ b/Source/WebCore/platform/graphics/qt/PatternQt.cpp @@ -33,12 +33,12 @@ namespace WebCore { QBrush Pattern::createPlatformPattern() const { - QPixmap* pixmap = tileImage()->nativeImageForCurrentFrame(); - if (!pixmap) + QImage* image = tileImage()->nativeImageForCurrentFrame(); + if (!image) return QBrush(); // Qt merges patter space and user space itself - QBrush brush(*pixmap); + QBrush brush(*image); brush.setTransform(m_patternSpaceTransformation); return brush; diff --git a/Source/WebCore/platform/graphics/qt/StillImageQt.cpp b/Source/WebCore/platform/graphics/qt/StillImageQt.cpp index 80666ba46..041252019 100644 --- a/Source/WebCore/platform/graphics/qt/StillImageQt.cpp +++ b/Source/WebCore/platform/graphics/qt/StillImageQt.cpp @@ -36,41 +36,41 @@ namespace WebCore { -StillImage::StillImage(const QPixmap& pixmap) - : m_pixmap(new QPixmap(pixmap)) - , m_ownsPixmap(true) +StillImage::StillImage(const QImage& image) + : m_image(new QImage(image)) + , m_ownsImage(true) {} -StillImage::StillImage(const QPixmap* pixmap) - : m_pixmap(pixmap) - , m_ownsPixmap(false) +StillImage::StillImage(const QImage* image) + : m_image(image) + , m_ownsImage(false) {} StillImage::~StillImage() { - if (m_ownsPixmap) - delete m_pixmap; + if (m_ownsImage) + delete m_image; } bool StillImage::currentFrameHasAlpha() { - return m_pixmap->hasAlpha(); + return m_image->hasAlphaChannel(); } IntSize StillImage::size() const { - return IntSize(m_pixmap->width(), m_pixmap->height()); + return IntSize(m_image->width(), m_image->height()); } NativeImagePtr StillImage::nativeImageForCurrentFrame() { - return const_cast<NativeImagePtr>(m_pixmap); + return const_cast<NativeImagePtr>(m_image); } void StillImage::draw(GraphicsContext* ctxt, const FloatRect& dst, const FloatRect& src, ColorSpace, CompositeOperator op) { - if (m_pixmap->isNull()) + if (m_image->isNull()) return; FloatRect normalizedSrc = src.normalized(); @@ -84,12 +84,12 @@ void StillImage::draw(GraphicsContext* ctxt, const FloatRect& dst, GraphicsContext* shadowContext = shadow->beginShadowLayer(ctxt, normalizedDst); if (shadowContext) { QPainter* shadowPainter = shadowContext->platformContext(); - shadowPainter->drawPixmap(normalizedDst, *m_pixmap, normalizedSrc); + shadowPainter->drawImage(normalizedDst, *m_image, normalizedSrc); shadow->endShadowLayer(ctxt); } } - ctxt->platformContext()->drawPixmap(normalizedDst, *m_pixmap, normalizedSrc); + ctxt->platformContext()->drawImage(normalizedDst, *m_image, normalizedSrc); ctxt->setCompositeOperation(previousOperator); } diff --git a/Source/WebCore/platform/graphics/qt/StillImageQt.h b/Source/WebCore/platform/graphics/qt/StillImageQt.h index 26df4714e..8c9ec0d88 100644 --- a/Source/WebCore/platform/graphics/qt/StillImageQt.h +++ b/Source/WebCore/platform/graphics/qt/StillImageQt.h @@ -34,14 +34,14 @@ namespace WebCore { class StillImage : public Image { public: - static PassRefPtr<StillImage> create(const QPixmap& pixmap) + static PassRefPtr<StillImage> create(const QImage& image) { - return adoptRef(new StillImage(pixmap)); + return adoptRef(new StillImage(image)); } - static PassRefPtr<StillImage> createForRendering(const QPixmap* pixmap) + static PassRefPtr<StillImage> createForRendering(const QImage* image) { - return adoptRef(new StillImage(pixmap)); + return adoptRef(new StillImage(image)); } virtual bool currentFrameHasAlpha(); @@ -56,12 +56,12 @@ namespace WebCore { virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator); private: - StillImage(const QPixmap& pixmap); - StillImage(const QPixmap* pixmap); + StillImage(const QImage&); + StillImage(const QImage*); virtual ~StillImage(); - const QPixmap* m_pixmap; - bool m_ownsPixmap; + const QImage* m_image; + bool m_ownsImage; }; } diff --git a/Source/WebCore/platform/graphics/qt/TransparencyLayer.h b/Source/WebCore/platform/graphics/qt/TransparencyLayer.h index f13deb03b..5974017be 100644 --- a/Source/WebCore/platform/graphics/qt/TransparencyLayer.h +++ b/Source/WebCore/platform/graphics/qt/TransparencyLayer.h @@ -36,24 +36,24 @@ #ifndef TransparencyLayer_h #define TransparencyLayer_h +#include <NativeImageQt.h> #include <QPaintEngine> #include <QPainter> -#include <QPixmap> namespace WebCore { struct TransparencyLayer { WTF_MAKE_FAST_ALLOCATED; public: - TransparencyLayer(const QPainter* p, const QRect &rect, qreal opacity, QPixmap& alphaMask) - : pixmap(rect.width(), rect.height()) + TransparencyLayer(const QPainter* p, const QRect &rect, qreal opacity, QImage& alphaMask) + : image(rect.width(), rect.height(), NativeImageQt::defaultFormatForAlphaEnabledImages()) , opacity(opacity) , alphaMask(alphaMask) , saveCounter(1) // see the comment for saveCounter { offset = rect.topLeft(); - pixmap.fill(Qt::transparent); - painter.begin(&pixmap); + image.fill(Qt::transparent); + painter.begin(&image); painter.setRenderHints(p->renderHints()); painter.translate(-offset); painter.setPen(p->pen()); @@ -67,12 +67,12 @@ public: { } - QPixmap pixmap; + QImage image; QPoint offset; QPainter painter; qreal opacity; // for clipToImageBuffer - QPixmap alphaMask; + QImage alphaMask; // saveCounter is only used in combination with alphaMask // otherwise, its value is unspecified int saveCounter; diff --git a/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceQt.cpp b/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceQt.cpp index 734a093ae..e1b275893 100644 --- a/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceQt.cpp +++ b/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceQt.cpp @@ -52,8 +52,7 @@ PassRefPtr<Image> GraphicsSurface::createReadOnlyImage(const IntRect& rect) int stride; QImage::Format format = (flags() & SupportsAlpha) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; char* data = platformLock(rect, &stride, RetainPixels | ReadOnly); - QImage image(reinterpret_cast<uchar*>(data), rect.width(), rect.height(), stride, format, didReleaseImage, this); - return BitmapImage::create(new QPixmap(QPixmap::fromImage(image))); + return BitmapImage::create(new QImage(reinterpret_cast<uchar*>(data), rect.width(), rect.height(), stride, format, didReleaseImage, this)); } } diff --git a/Source/WebCore/platform/network/blackberry/NetworkJob.cpp b/Source/WebCore/platform/network/blackberry/NetworkJob.cpp index a48324763..56b8760ba 100644 --- a/Source/WebCore/platform/network/blackberry/NetworkJob.cpp +++ b/Source/WebCore/platform/network/blackberry/NetworkJob.cpp @@ -83,6 +83,7 @@ NetworkJob::NetworkJob() , m_callingClient(false) , m_needsRetryAsFTPDirectory(false) , m_isOverrideContentType(false) + , m_newJobWithCredentialsStarted(false) , m_extendedStatusCode(0) , m_redirectCount(0) , m_deferredData(*this) @@ -282,7 +283,7 @@ void NetworkJob::notifyAuthReceived(BlackBerry::Platform::NetworkRequest::AuthTy return; } - sendRequestWithCredentials(serverType, scheme, realm); + m_newJobWithCredentialsStarted = sendRequestWithCredentials(serverType, scheme, realm); } void NetworkJob::notifyStringHeaderReceived(const String& key, const String& value) @@ -505,15 +506,8 @@ void NetworkJob::handleNotifyClose(int status) bool NetworkJob::shouldReleaseClientResource() { - if (m_redirectCount >= s_redirectMaximum) - return true; - - if (m_needsRetryAsFTPDirectory && retryAsFTPDirectory()) - return false; - - if (isRedirect(m_extendedStatusCode) && handleRedirect()) + if ((m_needsRetryAsFTPDirectory && retryAsFTPDirectory()) || (isRedirect(m_extendedStatusCode) && handleRedirect()) || m_newJobWithCredentialsStarted) return false; - return true; } @@ -576,7 +570,7 @@ bool NetworkJob::startNewJobWithRequest(ResourceRequest& newRequest, bool increa bool NetworkJob::handleRedirect() { ASSERT(m_handle); - if (!m_handle) + if (!m_handle || m_redirectCount >= s_redirectMaximum) return false; String location = m_response.httpHeaderField("Location"); diff --git a/Source/WebCore/platform/network/blackberry/NetworkJob.h b/Source/WebCore/platform/network/blackberry/NetworkJob.h index acc07dcbf..8fceffc1a 100644 --- a/Source/WebCore/platform/network/blackberry/NetworkJob.h +++ b/Source/WebCore/platform/network/blackberry/NetworkJob.h @@ -165,6 +165,7 @@ private: bool m_callingClient; bool m_needsRetryAsFTPDirectory; bool m_isOverrideContentType; + bool m_newJobWithCredentialsStarted; // If an HTTP status code is received, m_extendedStatusCode and m_response.httpStatusCode will both be set to it. // If a platform error code is received, m_extendedStatusCode will be set to it and m_response.httpStatusCode will be set to 404. diff --git a/Source/WebCore/platform/qt/ClipboardQt.cpp b/Source/WebCore/platform/qt/ClipboardQt.cpp index 6d2ab7229..8e4c5800d 100644 --- a/Source/WebCore/platform/qt/ClipboardQt.cpp +++ b/Source/WebCore/platform/qt/ClipboardQt.cpp @@ -50,6 +50,7 @@ #include <QGuiApplication> #include <QClipboard> +#include <QImage> #include <QList> #include <QMimeData> #include <QStringList> @@ -243,7 +244,7 @@ DragImageRef ClipboardQt::createDragImage(IntPoint& dragLoc) const if (!m_dragImage) return 0; dragLoc = m_dragLoc; - return m_dragImage->image()->nativeImageForCurrentFrame(); + return new QImage(*m_dragImage->image()->nativeImageForCurrentFrame()); } @@ -273,9 +274,9 @@ void ClipboardQt::declareAndWriteDragImage(Element* element, const KURL& url, co CachedImage* cachedImage = getCachedImage(element); if (!cachedImage || !cachedImage->imageForRenderer(element->renderer()) || !cachedImage->isLoaded()) return; - QPixmap* pixmap = cachedImage->imageForRenderer(element->renderer())->nativeImageForCurrentFrame(); - if (pixmap) - m_writableData->setImageData(*pixmap); + QImage* image = cachedImage->imageForRenderer(element->renderer())->nativeImageForCurrentFrame(); + if (image) + m_writableData->setImageData(*image); QList<QUrl> urls; urls.append(url); diff --git a/Source/WebCore/platform/qt/CursorQt.cpp b/Source/WebCore/platform/qt/CursorQt.cpp index e7854dde5..168a2f56b 100644 --- a/Source/WebCore/platform/qt/CursorQt.cpp +++ b/Source/WebCore/platform/qt/CursorQt.cpp @@ -37,6 +37,8 @@ #include "NotImplemented.h" +#include <QImage> +#include <QPixmap> #include <stdio.h> #include <stdlib.h> @@ -75,10 +77,11 @@ Cursor& Cursor::operator=(const Cursor& other) #ifndef QT_NO_CURSOR static QCursor* createCustomCursor(Image* image, const IntPoint& hotSpot) { - if (!image->nativeImageForCurrentFrame()) + QImage* nativeImage = image->nativeImageForCurrentFrame(); + if (!nativeImage) return 0; IntPoint effectiveHotSpot = determineHotSpot(image, hotSpot); - return new QCursor(*(image->nativeImageForCurrentFrame()), effectiveHotSpot.x(), effectiveHotSpot.y()); + return new QCursor(QPixmap::fromImage(*nativeImage), effectiveHotSpot.x(), effectiveHotSpot.y()); } #endif diff --git a/Source/WebCore/platform/qt/DragImageQt.cpp b/Source/WebCore/platform/qt/DragImageQt.cpp index 0e7ce0465..e93ac7089 100644 --- a/Source/WebCore/platform/qt/DragImageQt.cpp +++ b/Source/WebCore/platform/qt/DragImageQt.cpp @@ -29,6 +29,8 @@ #include "CachedImage.h" #include "Image.h" +#include <QImage> + namespace WebCore { IntSize dragImageSize(DragImageRef image) @@ -66,7 +68,7 @@ DragImageRef createDragImageFromImage(Image* image, RespectImageOrientationEnum) if (!image || !image->nativeImageForCurrentFrame()) return 0; - return new QPixmap(*image->nativeImageForCurrentFrame()); + return new QImage(*image->nativeImageForCurrentFrame()); } DragImageRef createDragImageIconForCachedImage(CachedImage*) diff --git a/Source/WebCore/platform/qt/PasteboardQt.cpp b/Source/WebCore/platform/qt/PasteboardQt.cpp index d6f4e1d52..c6e3d0153 100644 --- a/Source/WebCore/platform/qt/PasteboardQt.cpp +++ b/Source/WebCore/platform/qt/PasteboardQt.cpp @@ -166,10 +166,10 @@ void Pasteboard::writeImage(Node* node, const KURL&, const String&) Image* image = cachedImage->imageForRenderer(node->renderer()); ASSERT(image); - QPixmap* pixmap = image->nativeImageForCurrentFrame(); - if (!pixmap) + QImage* nativeImage = image->nativeImageForCurrentFrame(); + if (!image) return; - QGuiApplication::clipboard()->setPixmap(*pixmap, QClipboard::Clipboard); + QGuiApplication::clipboard()->setImage(*nativeImage, QClipboard::Clipboard); #endif } diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp index 2f2ab2421..131ebcaf6 100644 --- a/Source/WebCore/rendering/RenderBox.cpp +++ b/Source/WebCore/rendering/RenderBox.cpp @@ -385,7 +385,7 @@ int RenderBox::scrollWidth() const // For objects with visible overflow, this matches IE. // FIXME: Need to work right with writing modes. if (style()->isLeftToRightDirection()) - return snapSizeToPixel(max(clientWidth(), layoutOverflowRect().maxX() - borderLeft()), clientLeft()); + return snapSizeToPixel(max(clientWidth(), layoutOverflowRect().maxX() - borderLeft()), x() + clientLeft()); return clientWidth() - min(ZERO_LAYOUT_UNIT, layoutOverflowRect().x() - borderLeft()); } @@ -395,7 +395,7 @@ int RenderBox::scrollHeight() const return layer()->scrollHeight(); // For objects with visible overflow, this matches IE. // FIXME: Need to work right with writing modes. - return snapSizeToPixel(max(clientHeight(), layoutOverflowRect().maxY() - borderTop()), clientTop()); + return snapSizeToPixel(max(clientHeight(), layoutOverflowRect().maxY() - borderTop()), y() + clientTop()); } int RenderBox::scrollLeft() const diff --git a/Source/WebCore/rendering/RenderBox.h b/Source/WebCore/rendering/RenderBox.h index 064ed9191..488c58405 100644 --- a/Source/WebCore/rendering/RenderBox.h +++ b/Source/WebCore/rendering/RenderBox.h @@ -353,9 +353,9 @@ public: LayoutUnit computePercentageLogicalHeight(const Length& height); - // Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.) + // Block flows subclass availableWidth/Height to handle multi column layout (shrinking the width/height available to children when laying out.) virtual LayoutUnit availableLogicalWidth() const { return contentLogicalWidth(); } - LayoutUnit availableLogicalHeight() const; + virtual LayoutUnit availableLogicalHeight() const; LayoutUnit availableLogicalHeightUsing(const Length&) const; // There are a few cases where we need to refer specifically to the available physical width and available physical height. diff --git a/Source/WebCore/rendering/RenderGeometryMap.h b/Source/WebCore/rendering/RenderGeometryMap.h index 8e63c5084..98f44c633 100644 --- a/Source/WebCore/rendering/RenderGeometryMap.h +++ b/Source/WebCore/rendering/RenderGeometryMap.h @@ -41,6 +41,7 @@ class RenderLayer; struct RenderGeometryMapStep { RenderGeometryMapStep(const RenderGeometryMapStep& o) : m_renderer(o.m_renderer) + , m_offset(o.m_offset) , m_accumulatingTransform(o.m_accumulatingTransform) , m_isNonUniform(o.m_isNonUniform) , m_isFixedPosition(o.m_isFixedPosition) @@ -67,6 +68,7 @@ struct RenderGeometryMapStep { // Can be used while walking the Renderer tree to cache data about offsets and transforms. class RenderGeometryMap { + WTF_MAKE_NONCOPYABLE(RenderGeometryMap); public: RenderGeometryMap(); ~RenderGeometryMap(); diff --git a/Source/WebCore/rendering/RenderGrid.cpp b/Source/WebCore/rendering/RenderGrid.cpp index 883e1710b..b4d2a0c08 100644 --- a/Source/WebCore/rendering/RenderGrid.cpp +++ b/Source/WebCore/rendering/RenderGrid.cpp @@ -24,11 +24,25 @@ */ #include "config.h" - #include "RenderGrid.h" +#include "LayoutRepainter.h" +#include "NotImplemented.h" +#include "RenderLayer.h" +#include "RenderView.h" + namespace WebCore { +class RenderGrid::GridTrack { +public: + GridTrack() + : m_usedBreadth(0) + { + } + + LayoutUnit m_usedBreadth; +}; + RenderGrid::RenderGrid(Node* node) : RenderBlock(node) { @@ -40,10 +54,129 @@ RenderGrid::~RenderGrid() { } -void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight) +void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit) { - // For now just call the base class. - RenderBlock::layoutBlock(relayoutChildren, pageLogicalHeight); + ASSERT(needsLayout()); + + if (!relayoutChildren && simplifiedLayout()) + return; + + // FIXME: Much of this method is boiler plate that matches RenderBox::layoutBlock and Render*FlexibleBox::layoutBlock. + // It would be nice to refactor some of the duplicate code. + LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); + LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode()); + + if (inRenderFlowThread()) { + // Regions changing widths can force us to relayout our children. + if (logicalWidthChangedInRegions()) + relayoutChildren = true; + } + computeInitialRegionRangeForBlock(); + + LayoutSize previousSize = size(); + + setLogicalHeight(0); + computeLogicalWidth(); + + m_overflow.clear(); + + if (scrollsOverflow()) { + if (style()->overflowX() == OSCROLL) + layer()->setHasHorizontalScrollbar(true); + if (style()->overflowY() == OSCROLL) + layer()->setHasVerticalScrollbar(true); + } + + layoutGridItems(); + + LayoutUnit oldClientAfterEdge = clientLogicalBottom(); + computeLogicalHeight(); + + if (size() != previousSize) + relayoutChildren = true; + + layoutPositionedObjects(relayoutChildren || isRoot()); + + computeRegionRangeForBlock(); + + computeOverflow(oldClientAfterEdge); + statePusher.pop(); + + updateLayerTransform(); + + // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if + // we overflow or not. + if (hasOverflowClip()) + layer()->updateScrollInfoAfterLayout(); + + repainter.repaintAfterLayout(); + + setNeedsLayout(false); +} + +void RenderGrid::computedUsedBreadthOfGridTracks(TrackSizingDirection direction, Vector<GridTrack>& tracks) +{ + const Vector<Length>& trackStyles = (direction == ForColumns) ? style()->gridColumns() : style()->gridRows(); + for (size_t i = 0; i < trackStyles.size(); ++i) { + GridTrack track; + if (trackStyles[i].isFixed()) + track.m_usedBreadth = trackStyles[i].getFloatValue(); + else + notImplemented(); + + tracks.append(track); + } +} + +void RenderGrid::layoutGridItems() +{ + Vector<GridTrack> columnTracks, rowTracks; + computedUsedBreadthOfGridTracks(ForColumns, columnTracks); + // FIXME: The logical width of Grid Columns from the prior step is used in + // the formatting of Grid items in content-sized Grid Rows to determine + // their required height. We will probably need to pass columns through. + computedUsedBreadthOfGridTracks(ForRows, rowTracks); + + for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { + LayoutPoint childPosition = findChildLogicalPosition(child, columnTracks, rowTracks); + // FIXME: Grid items should stretch to fill their cells. Once we + // implement grid-{column,row}-align, we can also shrink to fit. For + // now, just size as if we were a regular child. + child->layoutIfNeeded(); + + // FIXME: Handle border & padding on the grid element. + child->setLogicalLocation(childPosition); + } + + // FIXME: Handle border & padding on the grid element. + for (size_t i = 0; i < rowTracks.size(); ++i) + setLogicalHeight(logicalHeight() + rowTracks[i].m_usedBreadth); +} + +LayoutPoint RenderGrid::findChildLogicalPosition(RenderBox* child, const Vector<GridTrack>& columnTracks, const Vector<GridTrack>& rowTracks) +{ + Length column = child->style()->gridItemColumn(); + Length row = child->style()->gridItemRow(); + + // FIXME: What does a non-positive integer mean for a column/row? + if (!column.isPositive() || !row.isPositive()) + return LayoutPoint(); + + // FIXME: Handle other values for grid-{row,column} like ranges or line names. + if (!column.isFixed() || !row.isFixed()) + return LayoutPoint(); + + size_t columnTrack = static_cast<size_t>(column.intValue()) - 1; + size_t rowTrack = static_cast<size_t>(row.intValue()) - 1; + + LayoutPoint offset; + for (size_t i = 0; i < columnTrack && i < columnTracks.size(); ++i) + offset.setX(offset.x() + columnTracks[i].m_usedBreadth); + for (size_t i = 0; i < rowTrack && i < rowTracks.size(); ++i) + offset.setY(offset.y() + rowTracks[i].m_usedBreadth); + + // FIXME: Handle margins on the grid item. + return offset; } const char* RenderGrid::renderName() const diff --git a/Source/WebCore/rendering/RenderGrid.h b/Source/WebCore/rendering/RenderGrid.h index 28498fe43..829bf8862 100644 --- a/Source/WebCore/rendering/RenderGrid.h +++ b/Source/WebCore/rendering/RenderGrid.h @@ -40,6 +40,14 @@ public: virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) OVERRIDE; virtual bool avoidsFloats() const OVERRIDE { return true; } + +private: + class GridTrack; + enum TrackSizingDirection { ForColumns, ForRows }; + void computedUsedBreadthOfGridTracks(TrackSizingDirection, Vector<GridTrack>&); + void layoutGridItems(); + + LayoutPoint findChildLogicalPosition(RenderBox*, const Vector<GridTrack>& columnTracks, const Vector<GridTrack>& rowTracks); }; } // namespace WebCore diff --git a/Source/WebCore/rendering/RenderImage.cpp b/Source/WebCore/rendering/RenderImage.cpp index 776e2787b..3feb57c54 100644 --- a/Source/WebCore/rendering/RenderImage.cpp +++ b/Source/WebCore/rendering/RenderImage.cpp @@ -446,7 +446,7 @@ void RenderImage::paintIntoRect(GraphicsContext* context, const LayoutRect& rect if (!img || img->isNull()) return; - HTMLImageElement* imageElt = (node() && node()->hasTagName(imgTag)) ? static_cast<HTMLImageElement*>(node()) : 0; + HTMLImageElement* imageElt = hostImageElement(); CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver; Image* image = m_imageResource->image().get(); bool useLowQualityScaling = shouldPaintAtLowQuality(context, image, image, alignedRect.size()); @@ -494,7 +494,7 @@ int RenderImage::minimumReplacedHeight() const HTMLMapElement* RenderImage::imageMap() const { - HTMLImageElement* i = node() && node()->hasTagName(imgTag) ? static_cast<HTMLImageElement*>(node()) : 0; + HTMLImageElement* i = hostImageElement(); return i ? i->treeScope()->getImageMap(i->fastGetAttribute(usemapAttr)) : 0; } @@ -529,8 +529,8 @@ void RenderImage::updateAltText() if (node()->hasTagName(inputTag)) m_altText = static_cast<HTMLInputElement*>(node())->altText(); - else if (node()->hasTagName(imgTag)) - m_altText = static_cast<HTMLImageElement*>(node())->altText(); + else if (HTMLImageElement* image = hostImageElement()) + m_altText = image->altText(); } void RenderImage::layout() @@ -563,6 +563,24 @@ void RenderImage::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, dou } } +HTMLImageElement* RenderImage::hostImageElement() const +{ + if (!node()) + return 0; + + if (isHTMLImageElement(node())) + return toHTMLImageElement(node()); + + if (node()->hasTagName(webkitInnerImageTag)) { + if (Node* ancestor = node()->shadowAncestorNode()) { + if (ancestor->hasTagName(imgTag)) + return toHTMLImageElement(ancestor); + } + } + + return 0; +} + bool RenderImage::needsPreferredWidthsRecalculation() const { if (RenderReplaced::needsPreferredWidthsRecalculation()) diff --git a/Source/WebCore/rendering/RenderImage.h b/Source/WebCore/rendering/RenderImage.h index b6725f005..6bddb0a58 100644 --- a/Source/WebCore/rendering/RenderImage.h +++ b/Source/WebCore/rendering/RenderImage.h @@ -31,6 +31,7 @@ namespace WebCore { class HTMLAreaElement; +class HTMLImageElement; class HTMLMapElement; class RenderImage : public RenderReplaced { @@ -58,6 +59,8 @@ public: bool isGeneratedContent() const { return m_isGeneratedContent; } protected: + HTMLImageElement* hostImageElement() const; + virtual bool needsPreferredWidthsRecalculation() const; virtual RenderBox* embeddedContentBox() const; virtual void computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const; diff --git a/Source/WebCore/rendering/RenderInline.cpp b/Source/WebCore/rendering/RenderInline.cpp index c4e142392..104c56f5d 100644 --- a/Source/WebCore/rendering/RenderInline.cpp +++ b/Source/WebCore/rendering/RenderInline.cpp @@ -533,7 +533,7 @@ void RenderInline::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) } template<typename GeneratorContext> -void RenderInline::generateLineBoxRects(GeneratorContext yield) const +void RenderInline::generateLineBoxRects(GeneratorContext& yield) const { if (!alwaysCreateLineBoxes()) generateCulledLineBoxRects(yield, this); @@ -545,7 +545,7 @@ void RenderInline::generateLineBoxRects(GeneratorContext yield) const } template<typename GeneratorContext> -void RenderInline::generateCulledLineBoxRects(GeneratorContext yield, const RenderInline* container) const +void RenderInline::generateCulledLineBoxRects(GeneratorContext& yield, const RenderInline* container) const { if (!culledInlineFirstLineBox()) { yield(FloatRect()); @@ -631,7 +631,8 @@ private: void RenderInline::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const { - generateLineBoxRects(AbsoluteRectsGeneratorContext(rects, accumulatedOffset)); + AbsoluteRectsGeneratorContext context(rects, accumulatedOffset); + generateLineBoxRects(context); if (continuation()) { if (continuation()->isBox()) { @@ -647,9 +648,8 @@ namespace { class AbsoluteQuadsGeneratorContext { public: - AbsoluteQuadsGeneratorContext(const RenderInline* renderer, Vector<FloatQuad>& quads, bool* wasFixed) + AbsoluteQuadsGeneratorContext(const RenderInline* renderer, Vector<FloatQuad>& quads) : m_quads(quads) - , m_wasFixed(wasFixed) , m_geometryMap() { m_geometryMap.pushMappingsToAncestor(renderer, 0); @@ -661,7 +661,6 @@ public: } private: Vector<FloatQuad>& m_quads; - bool* m_wasFixed; RenderGeometryMap m_geometryMap; }; @@ -669,7 +668,8 @@ private: void RenderInline::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const { - generateLineBoxRects(AbsoluteQuadsGeneratorContext(this, quads, wasFixed)); + AbsoluteQuadsGeneratorContext context(this, quads); + generateLineBoxRects(context); if (continuation()) continuation()->absoluteQuads(quads, wasFixed); @@ -804,7 +804,8 @@ IntRect RenderInline::linesBoundingBox() const if (!alwaysCreateLineBoxes()) { ASSERT(!firstLineBox()); FloatRect floatResult; - generateCulledLineBoxRects(LinesBoundingBoxGeneratorContext(floatResult), this); + LinesBoundingBoxGeneratorContext context(floatResult); + generateCulledLineBoxRects(context, this); return enclosingIntRect(floatResult); } @@ -888,7 +889,8 @@ InlineBox* RenderInline::culledInlineLastLineBox() const LayoutRect RenderInline::culledInlineVisualOverflowBoundingBox() const { FloatRect floatResult; - generateCulledLineBoxRects(LinesBoundingBoxGeneratorContext(floatResult), this); + LinesBoundingBoxGeneratorContext context(floatResult); + generateCulledLineBoxRects(context, this); LayoutRect result(enclosingLayoutRect(floatResult)); bool isHorizontal = style()->isHorizontalWritingMode(); for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) { @@ -1354,7 +1356,8 @@ void RenderInline::imageChanged(WrappedImagePtr, const IntRect*) void RenderInline::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset) { - generateLineBoxRects(AbsoluteRectsGeneratorContext(rects, additionalOffset)); + AbsoluteRectsGeneratorContext context(rects, additionalOffset); + generateLineBoxRects(context); for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) { if (!curr->isText() && !curr->isListMarker()) { diff --git a/Source/WebCore/rendering/RenderInline.h b/Source/WebCore/rendering/RenderInline.h index 722300ab8..a8cc2f1be 100644 --- a/Source/WebCore/rendering/RenderInline.h +++ b/Source/WebCore/rendering/RenderInline.h @@ -106,9 +106,9 @@ private: InlineBox* culledInlineLastLineBox() const; template<typename GeneratorContext> - void generateLineBoxRects(GeneratorContext yield) const; + void generateLineBoxRects(GeneratorContext& yield) const; template<typename GeneratorContext> - void generateCulledLineBoxRects(GeneratorContext yield, const RenderInline* container) const; + void generateCulledLineBoxRects(GeneratorContext& yield, const RenderInline* container) const; void addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild); virtual void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild = 0); diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp index 31be2e8a3..441c0beaa 100644 --- a/Source/WebCore/rendering/RenderLayer.cpp +++ b/Source/WebCore/rendering/RenderLayer.cpp @@ -842,7 +842,11 @@ void RenderLayer::updateLayerPosition() // FIXME: Composited layers ignore pagination, so about the best we can do is make sure they're offset into the appropriate column. // They won't split across columns properly. LayoutSize columnOffset; - parent()->renderer()->adjustForColumns(columnOffset, localPoint); + if (!parent()->renderer()->hasColumns() && parent()->renderer()->isRoot() && renderer()->view()->hasColumns()) + renderer()->view()->adjustForColumns(columnOffset, localPoint); + else + parent()->renderer()->adjustForColumns(columnOffset, localPoint); + localPoint += columnOffset; } @@ -1615,8 +1619,8 @@ IntSize RenderLayer::clampScrollOffset(const IntSize& scrollOffset) const RenderBox* box = renderBox(); ASSERT(box); - int maxX = scrollWidth() - box->clientWidth(); - int maxY = scrollHeight() - box->clientHeight(); + int maxX = scrollWidth() - box->pixelSnappedClientWidth(); + int maxY = scrollHeight() - box->pixelSnappedClientHeight(); int x = min(max(scrollOffset.width(), 0), maxX); int y = min(max(scrollOffset.height(), 0), maxY); @@ -2438,7 +2442,7 @@ int RenderLayer::scrollWidth() const ASSERT(renderBox()); if (m_scrollDimensionsDirty) const_cast<RenderLayer*>(this)->computeScrollDimensions(); - return snapSizeToPixel(m_scrollSize.width(), renderBox()->clientLeft()); + return snapSizeToPixel(m_scrollSize.width(), renderBox()->clientLeft() + renderBox()->x()); } int RenderLayer::scrollHeight() const @@ -2446,7 +2450,7 @@ int RenderLayer::scrollHeight() const ASSERT(renderBox()); if (m_scrollDimensionsDirty) const_cast<RenderLayer*>(this)->computeScrollDimensions(); - return snapSizeToPixel(m_scrollSize.height(), renderBox()->clientTop()); + return snapSizeToPixel(m_scrollSize.height(), renderBox()->clientTop() + renderBox()->y()); } LayoutUnit RenderLayer::overflowTop() const diff --git a/Source/WebCore/rendering/RenderObject.cpp b/Source/WebCore/rendering/RenderObject.cpp index 04f27e652..6cdb4b2f9 100755 --- a/Source/WebCore/rendering/RenderObject.cpp +++ b/Source/WebCore/rendering/RenderObject.cpp @@ -2180,7 +2180,7 @@ RespectImageOrientationEnum RenderObject::shouldRespectImageOrientation() const { // Respect the image's orientation if it's being used as a full-page image or it's // an <img> and the setting to respect it everywhere is set. - return document()->isImageDocument() || (document()->settings() && document()->settings()->shouldRespectImageOrientation() && node() && node()->hasTagName(HTMLNames::imgTag)) ? RespectImageOrientation : DoNotRespectImageOrientation; + return document()->isImageDocument() || (document()->settings() && document()->settings()->shouldRespectImageOrientation() && node() && (node()->hasTagName(HTMLNames::imgTag) || node()->hasTagName(HTMLNames::webkitInnerImageTag))) ? RespectImageOrientation : DoNotRespectImageOrientation; } bool RenderObject::hasOutlineAnnotation() const @@ -2692,6 +2692,11 @@ bool RenderObject::willRenderImage(CachedImage*) if (document()->inPageCache() || document()->view()->isOffscreen()) return false; + // If the document is being destroyed or has not been attached, then this + // RenderObject will not be rendered. + if (!view()) + return false; + // If a renderer is outside the viewport, we won't render. return viewRect().intersects(absoluteClippedOverflowRect()); } diff --git a/Source/WebCore/rendering/RenderTable.cpp b/Source/WebCore/rendering/RenderTable.cpp index 7730828a4..3eac69200 100644 --- a/Source/WebCore/rendering/RenderTable.cpp +++ b/Source/WebCore/rendering/RenderTable.cpp @@ -575,9 +575,11 @@ void RenderTable::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffs info.phase = paintPhase; info.updatePaintingRootForChildren(this); + IntPoint alignedOffset = roundedIntPoint(paintOffset); + for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child->isTableCaption())) { - LayoutPoint childPoint = flipForWritingModeForChild(toRenderBox(child), paintOffset); + LayoutPoint childPoint = flipForWritingModeForChild(toRenderBox(child), alignedOffset); child->paint(info, childPoint); } } diff --git a/Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp b/Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp index 97f587455..5404e47f8 100644 --- a/Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp +++ b/Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp @@ -87,18 +87,6 @@ void RenderThemeChromiumAndroid::adjustInnerSpinButtonStyle(StyleResolver*, Rend } } -bool RenderThemeChromiumAndroid::paintMediaFullscreenButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) -{ -#if ENABLE(VIDEO) - return RenderMediaControlsChromium::paintMediaControlsPart(MediaEnterFullscreenButton, object, paintInfo, rect); -#else - UNUSED_PARAM(object); - UNUSED_PARAM(paintInfo); - UNUSED_PARAM(rect); - return false; -#endif -} - int RenderThemeChromiumAndroid::menuListArrowPadding() const { // We cannot use the scrollbar thickness here, as it's width is 0 on Android. diff --git a/Source/WebCore/rendering/RenderThemeChromiumAndroid.h b/Source/WebCore/rendering/RenderThemeChromiumAndroid.h index f7aafaa18..c3e4b8bed 100644 --- a/Source/WebCore/rendering/RenderThemeChromiumAndroid.h +++ b/Source/WebCore/rendering/RenderThemeChromiumAndroid.h @@ -41,8 +41,6 @@ public: virtual bool delegatesMenuListRendering() const OVERRIDE { return true; } - virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE; - #if ENABLE(VIDEO) virtual String extraMediaControlsStyleSheet() OVERRIDE; #endif diff --git a/Source/WebCore/rendering/RenderView.cpp b/Source/WebCore/rendering/RenderView.cpp index a895bc99e..a3486f61c 100644 --- a/Source/WebCore/rendering/RenderView.cpp +++ b/Source/WebCore/rendering/RenderView.cpp @@ -108,6 +108,14 @@ void RenderView::computePreferredLogicalWidths() RenderBlock::computePreferredLogicalWidths(); } +LayoutUnit RenderView::availableLogicalHeight() const +{ + // If we have columns, then the available logical height is reduced to the column height. + if (hasColumns()) + return columnInfo()->columnHeight(); + return RenderBlock::availableLogicalHeight(); +} + bool RenderView::isChildAllowed(RenderObject* child, RenderStyle*) const { return child->isBox(); diff --git a/Source/WebCore/rendering/RenderView.h b/Source/WebCore/rendering/RenderView.h index a768f79d6..04a806e9b 100644 --- a/Source/WebCore/rendering/RenderView.h +++ b/Source/WebCore/rendering/RenderView.h @@ -63,6 +63,8 @@ public: // it only exists to make computePreferredLogicalWidths public. virtual void computePreferredLogicalWidths() OVERRIDE; + virtual LayoutUnit availableLogicalHeight() const OVERRIDE; + // The same as the FrameView's layoutHeight/layoutWidth but with null check guards. int viewHeight() const; int viewWidth() const; diff --git a/Source/WebCore/rendering/RootInlineBox.cpp b/Source/WebCore/rendering/RootInlineBox.cpp index 675b0718a..3d30cc0b0 100644 --- a/Source/WebCore/rendering/RootInlineBox.cpp +++ b/Source/WebCore/rendering/RootInlineBox.cpp @@ -875,7 +875,7 @@ LayoutUnit RootInlineBox::verticalPositionForBox(InlineBox* box, VerticalPositio else if (verticalAlign == TEXT_TOP) verticalPosition += renderer->baselinePosition(baselineType(), firstLine, lineDirection) - fontMetrics.ascent(baselineType()); else if (verticalAlign == MIDDLE) - verticalPosition += -static_cast<int>(fontMetrics.xHeight() / 2) - renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType(), firstLine, lineDirection); + verticalPosition = (verticalPosition - static_cast<LayoutUnit>(fontMetrics.xHeight() / 2) - renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType(), firstLine, lineDirection)).round(); else if (verticalAlign == TEXT_BOTTOM) { verticalPosition += fontMetrics.descent(baselineType()); // lineHeight - baselinePosition is always 0 for replaced elements (except inline blocks), so don't bother wasting time in that case. diff --git a/Source/WebCore/rendering/style/RenderStyle.h b/Source/WebCore/rendering/style/RenderStyle.h index a984ff6c0..5e8a12c95 100644 --- a/Source/WebCore/rendering/style/RenderStyle.h +++ b/Source/WebCore/rendering/style/RenderStyle.h @@ -814,8 +814,8 @@ public: const Vector<Length>& gridColumns() const { return rareNonInheritedData->m_grid->m_gridColumns; } const Vector<Length>& gridRows() const { return rareNonInheritedData->m_grid->m_gridRows; } - const Length& gridItemColumn() const { return rareNonInheritedData->m_gridItem->m_gridColumn; } - const Length& gridItemRow() const { return rareNonInheritedData->m_gridItem->m_gridRow; } + Length gridItemColumn() const { return rareNonInheritedData->m_gridItem->m_gridColumn; } + Length gridItemRow() const { return rareNonInheritedData->m_gridItem->m_gridRow; } const ShadowData* boxShadow() const { return rareNonInheritedData->m_boxShadow.get(); } void getBoxShadowExtent(LayoutUnit& top, LayoutUnit& right, LayoutUnit& bottom, LayoutUnit& left) const { getShadowExtent(boxShadow(), top, right, bottom, left); } @@ -963,6 +963,10 @@ public: bool isFlippedLinesWritingMode() const { return writingMode() == LeftToRightWritingMode || writingMode() == BottomToTopWritingMode; } bool isFlippedBlocksWritingMode() const { return writingMode() == RightToLeftWritingMode || writingMode() == BottomToTopWritingMode; } +#if ENABLE(CSS_IMAGE_ORIENTATION) + ImageOrientationEnum imageOrientation() const { return static_cast<ImageOrientationEnum>(rareInheritedData->m_imageOrientation); } +#endif + EImageRendering imageRendering() const { return static_cast<EImageRendering>(rareInheritedData->m_imageRendering); } #if ENABLE(CSS_IMAGE_RESOLUTION) @@ -1135,6 +1139,11 @@ public: bool setZoom(float); void setZoomWithoutReturnValue(float f) { setZoom(f); } bool setEffectiveZoom(float); + +#if ENABLE(CSS_IMAGE_ORIENTATION) + void setImageOrientation(ImageOrientationEnum v) { SET_VAR(rareInheritedData, m_imageOrientation, static_cast<int>(v)) } +#endif + void setImageRendering(EImageRendering v) { SET_VAR(rareInheritedData, m_imageRendering, v) } #if ENABLE(CSS_IMAGE_RESOLUTION) @@ -1427,22 +1436,22 @@ public: void setKerning(SVGLength k) { accessSVGStyle()->setKerning(k); } #endif - void setWrapShapeInside(PassRefPtr<CSSWrapShape> shape) + void setWrapShapeInside(PassRefPtr<WrapShape> shape) { if (rareNonInheritedData->m_wrapShapeInside != shape) rareNonInheritedData.access()->m_wrapShapeInside = shape; } - CSSWrapShape* wrapShapeInside() const { return rareNonInheritedData->m_wrapShapeInside.get(); } + WrapShape* wrapShapeInside() const { return rareNonInheritedData->m_wrapShapeInside.get(); } - void setWrapShapeOutside(PassRefPtr<CSSWrapShape> shape) + void setWrapShapeOutside(PassRefPtr<WrapShape> shape) { if (rareNonInheritedData->m_wrapShapeOutside != shape) rareNonInheritedData.access()->m_wrapShapeOutside = shape; } - CSSWrapShape* wrapShapeOutside() const { return rareNonInheritedData->m_wrapShapeOutside.get(); } + WrapShape* wrapShapeOutside() const { return rareNonInheritedData->m_wrapShapeOutside.get(); } - static CSSWrapShape* initialWrapShapeInside() { return 0; } - static CSSWrapShape* initialWrapShapeOutside() { return 0; } + static WrapShape* initialWrapShapeInside() { return 0; } + static WrapShape* initialWrapShapeOutside() { return 0; } Length wrapPadding() const { return rareNonInheritedData->m_wrapPadding; } void setWrapPadding(Length wrapPadding) { SET_VAR(rareNonInheritedData, m_wrapPadding, wrapPadding); } @@ -1658,6 +1667,7 @@ public: static const AtomicString& initialTextEmphasisCustomMark() { return nullAtom; } static TextEmphasisPosition initialTextEmphasisPosition() { return TextEmphasisPositionOver; } static LineBoxContain initialLineBoxContain() { return LineBoxContainBlock | LineBoxContainInline | LineBoxContainReplaced; } + static ImageOrientationEnum initialImageOrientation() { return OriginTopLeft; } static EImageRendering initialImageRendering() { return ImageRenderingAuto; } static ImageResolutionSource initialImageResolutionSource() { return ImageResolutionSpecified; } static ImageResolutionSnap initialImageResolutionSnap() { return ImageResolutionNoSnap; } diff --git a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp index e8a54334f..97de42d3c 100644 --- a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp +++ b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp @@ -81,6 +81,9 @@ StyleRareInheritedData::StyleRareInheritedData() , textEmphasisMark(TextEmphasisMarkNone) , textEmphasisPosition(TextEmphasisPositionOver) , m_lineBoxContain(RenderStyle::initialLineBoxContain()) +#if ENABLE(CSS_IMAGE_ORIENTATION) + , m_imageOrientation(RenderStyle::initialImageOrientation()) +#endif , m_imageRendering(RenderStyle::initialImageRendering()) , m_lineSnap(RenderStyle::initialLineSnap()) , m_lineAlign(RenderStyle::initialLineAlign()) @@ -140,6 +143,9 @@ StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o) , textEmphasisMark(o.textEmphasisMark) , textEmphasisPosition(o.textEmphasisPosition) , m_lineBoxContain(o.m_lineBoxContain) +#if ENABLE(CSS_IMAGE_ORIENTATION) + , m_imageOrientation(o.m_imageOrientation) +#endif , m_imageRendering(o.m_imageRendering) , m_lineSnap(o.m_lineSnap) , m_lineAlign(o.m_lineAlign) @@ -230,6 +236,9 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const && QuotesData::equal(quotes.get(), o.quotes.get()) && m_tabSize == o.m_tabSize && m_lineGrid == o.m_lineGrid +#if ENABLE(CSS_IMAGE_ORIENTATION) + && m_imageOrientation == o.m_imageOrientation +#endif && m_imageRendering == o.m_imageRendering #if ENABLE(CSS_IMAGE_RESOLUTION) && m_imageResolutionSource == o.m_imageResolutionSource diff --git a/Source/WebCore/rendering/style/StyleRareInheritedData.h b/Source/WebCore/rendering/style/StyleRareInheritedData.h index 93908e446..b30982df9 100644 --- a/Source/WebCore/rendering/style/StyleRareInheritedData.h +++ b/Source/WebCore/rendering/style/StyleRareInheritedData.h @@ -95,6 +95,9 @@ public: unsigned textEmphasisPosition : 1; // TextEmphasisPosition unsigned m_lineBoxContain: 7; // LineBoxContain // CSS Image Values Level 3 +#if ENABLE(CSS_IMAGE_ORIENTATION) + unsigned m_imageOrientation : 4; // ImageOrientationEnum +#endif unsigned m_imageRendering : 2; // EImageRendering unsigned m_lineSnap : 2; // LineSnap unsigned m_lineAlign : 1; // LineAlign diff --git a/Source/WebCore/rendering/style/StyleRareNonInheritedData.h b/Source/WebCore/rendering/style/StyleRareNonInheritedData.h index 94c4c8dfb..5e6fde2a6 100644 --- a/Source/WebCore/rendering/style/StyleRareNonInheritedData.h +++ b/Source/WebCore/rendering/style/StyleRareNonInheritedData.h @@ -25,13 +25,13 @@ #ifndef StyleRareNonInheritedData_h #define StyleRareNonInheritedData_h -#include "CSSWrapShapes.h" #include "CounterDirectives.h" #include "CursorData.h" #include "DataRef.h" #include "FillLayer.h" #include "LineClampValue.h" #include "NinePieceImage.h" +#include "WrapShapes.h" #include <wtf/OwnPtr.h> #include <wtf/PassRefPtr.h> #include <wtf/Vector.h> @@ -134,8 +134,8 @@ public: LengthSize m_pageSize; - RefPtr<CSSWrapShape> m_wrapShapeInside; - RefPtr<CSSWrapShape> m_wrapShapeOutside; + RefPtr<WrapShape> m_wrapShapeInside; + RefPtr<WrapShape> m_wrapShapeOutside; Length m_wrapMargin; Length m_wrapPadding; diff --git a/Source/WebCore/rendering/style/WrapShapes.h b/Source/WebCore/rendering/style/WrapShapes.h new file mode 100644 index 000000000..61052cb0d --- /dev/null +++ b/Source/WebCore/rendering/style/WrapShapes.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef WrapShapes_h +#define WrapShapes_h + +#include "Length.h" +#include "WindRule.h" + +namespace WebCore { + +class WrapShape : public RefCounted<WrapShape> { +public: + enum Type { + WRAP_SHAPE_RECTANGLE = 1, + WRAP_SHAPE_CIRCLE = 2, + WRAP_SHAPE_ELLIPSE = 3, + WRAP_SHAPE_POLYGON = 4 + }; + + virtual Type type() const = 0; + virtual ~WrapShape() { } + +protected: + WrapShape() { } +}; + +class WrapShapeRectangle : public WrapShape { +public: + static PassRefPtr<WrapShapeRectangle> create() { return adoptRef(new WrapShapeRectangle); } + + Length x() const { return m_x; } + Length y() const { return m_y; } + Length width() const { return m_width; } + Length height() const { return m_height; } + Length cornerRadiusX() const { return m_cornerRadiusX; } + Length cornerRadiusY() const { return m_cornerRadiusY; } + + void setX(Length x) { m_x = x; } + void setY(Length y) { m_y = y; } + void setWidth(Length width) { m_width = width; } + void setHeight(Length height) { m_height = height; } + void setCornerRadiusX(Length radiusX) { m_cornerRadiusX = radiusX; } + void setCornerRadiusY(Length radiusY) { m_cornerRadiusY = radiusY; } + + virtual Type type() const { return WRAP_SHAPE_RECTANGLE; } + +private: + WrapShapeRectangle() + : m_cornerRadiusX(Undefined) + , m_cornerRadiusY(Undefined) + { } + + Length m_y; + Length m_x; + Length m_width; + Length m_height; + Length m_cornerRadiusX; + Length m_cornerRadiusY; +}; + +class WrapShapeCircle : public WrapShape { +public: + static PassRefPtr<WrapShapeCircle> create() { return adoptRef(new WrapShapeCircle); } + + Length centerX() const { return m_centerX; } + Length centerY() const { return m_centerY; } + Length radius() const { return m_radius; } + + void setCenterX(Length centerX) { m_centerX = centerX; } + void setCenterY(Length centerY) { m_centerY = centerY; } + void setRadius(Length radius) { m_radius = radius; } + + virtual Type type() const { return WRAP_SHAPE_CIRCLE; } +private: + WrapShapeCircle() { } + + Length m_centerX; + Length m_centerY; + Length m_radius; +}; + +class WrapShapeEllipse : public WrapShape { +public: + static PassRefPtr<WrapShapeEllipse> create() { return adoptRef(new WrapShapeEllipse); } + + Length centerX() const { return m_centerX; } + Length centerY() const { return m_centerY; } + Length radiusX() const { return m_radiusX; } + Length radiusY() const { return m_radiusY; } + + void setCenterX(Length centerX) { m_centerX = centerX; } + void setCenterY(Length centerY) { m_centerY = centerY; } + void setRadiusX(Length radiusX) { m_radiusX = radiusX; } + void setRadiusY(Length radiusY) { m_radiusY = radiusY; } + + virtual Type type() const { return WRAP_SHAPE_ELLIPSE; } +private: + WrapShapeEllipse() { } + + Length m_centerX; + Length m_centerY; + Length m_radiusX; + Length m_radiusY; +}; + +class WrapShapePolygon : public WrapShape { +public: + static PassRefPtr<WrapShapePolygon> create() { return adoptRef(new WrapShapePolygon); } + + WindRule windRule() const { return m_windRule; } + const Vector<Length>& values() const { return m_values; } + Length getXAt(unsigned i) const { return m_values.at(2 * i); } + Length getYAt(unsigned i) const { return m_values.at(2 * i + 1); } + + void setWindRule(WindRule windRule) { m_windRule = windRule; } + void appendPoint(Length x, Length y) { m_values.append(x); m_values.append(y); } + + virtual Type type() const { return WRAP_SHAPE_POLYGON; } +private: + WrapShapePolygon() + : m_windRule(RULE_NONZERO) + { } + + WindRule m_windRule; + Vector<Length> m_values; +}; +} +#endif diff --git a/Source/WebCore/rendering/svg/RenderSVGPath.cpp b/Source/WebCore/rendering/svg/RenderSVGPath.cpp index edad43945..cf658359d 100755 --- a/Source/WebCore/rendering/svg/RenderSVGPath.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGPath.cpp @@ -32,6 +32,7 @@ #include "SVGPathElement.h" #include "SVGStyledTransformableElement.h" +#include "SVGSubpathData.h" namespace WebCore { @@ -44,6 +45,123 @@ RenderSVGPath::~RenderSVGPath() { } +void RenderSVGPath::updateShapeFromElement() +{ + RenderSVGShape::updateShapeFromElement(); + updateZeroLengthSubpaths(); + + m_strokeBoundingBox = calculateUpdatedStrokeBoundingBox(); +} + +FloatRect RenderSVGPath::calculateUpdatedStrokeBoundingBox() const +{ + FloatRect strokeBoundingBox = m_strokeBoundingBox; + + if (style()->svgStyle()->hasStroke()) { + // FIXME: zero-length subpaths do not respect vector-effect = non-scaling-stroke. + float strokeWidth = this->strokeWidth(); + for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) + strokeBoundingBox.unite(zeroLengthSubpathRect(m_zeroLengthLinecapLocations[i], strokeWidth)); + } + + return strokeBoundingBox; +} + +static void useStrokeStyleToFill(GraphicsContext* context) +{ + if (Gradient* gradient = context->strokeGradient()) + context->setFillGradient(gradient); + else if (Pattern* pattern = context->strokePattern()) + context->setFillPattern(pattern); + else + context->setFillColor(context->strokeColor(), context->strokeColorSpace()); +} + +void RenderSVGPath::strokeShape(GraphicsContext* context) const +{ + if (!style()->svgStyle()->hasVisibleStroke()) + return; + + RenderSVGShape::strokeShape(context); + + if (m_zeroLengthLinecapLocations.isEmpty()) + return; + + Path* usePath; + AffineTransform nonScalingTransform; + + if (hasNonScalingStroke()) + nonScalingTransform = nonScalingStrokeTransform(); + + GraphicsContextStateSaver stateSaver(*context, true); + useStrokeStyleToFill(context); + for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) { + usePath = zeroLengthLinecapPath(m_zeroLengthLinecapLocations[i]); + if (hasNonScalingStroke()) + usePath = nonScalingStrokePath(usePath, nonScalingTransform); + context->fillPath(*usePath); + } +} + +bool RenderSVGPath::shapeDependentStrokeContains(const FloatPoint& point) +{ + if (RenderSVGShape::shapeDependentStrokeContains(point)) + return true; + + const SVGRenderStyle* svgStyle = style()->svgStyle(); + for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) { + ASSERT(svgStyle->hasStroke()); + float strokeWidth = this->strokeWidth(); + if (svgStyle->capStyle() == SquareCap) { + if (zeroLengthSubpathRect(m_zeroLengthLinecapLocations[i], strokeWidth).contains(point)) + return true; + } else { + ASSERT(svgStyle->capStyle() == RoundCap); + FloatPoint radiusVector(point.x() - m_zeroLengthLinecapLocations[i].x(), point.y() - m_zeroLengthLinecapLocations[i].y()); + if (radiusVector.lengthSquared() < strokeWidth * strokeWidth * .25f) + return true; + } + } + return false; +} + +bool RenderSVGPath::shouldStrokeZeroLengthSubpath() const +{ + // Spec(11.4): Any zero length subpath shall not be stroked if the "stroke-linecap" property has a value of butt + // but shall be stroked if the "stroke-linecap" property has a value of round or square + return style()->svgStyle()->hasStroke() && style()->svgStyle()->capStyle() != ButtCap; +} + +Path* RenderSVGPath::zeroLengthLinecapPath(const FloatPoint& linecapPosition) const +{ + DEFINE_STATIC_LOCAL(Path, tempPath, ()); + + tempPath.clear(); + if (style()->svgStyle()->capStyle() == SquareCap) + tempPath.addRect(zeroLengthSubpathRect(linecapPosition, this->strokeWidth())); + else + tempPath.addEllipse(zeroLengthSubpathRect(linecapPosition, this->strokeWidth())); + + return &tempPath; +} + +FloatRect RenderSVGPath::zeroLengthSubpathRect(const FloatPoint& linecapPosition, float strokeWidth) const +{ + return FloatRect(linecapPosition.x() - strokeWidth / 2, linecapPosition.y() - strokeWidth / 2, strokeWidth, strokeWidth); +} + +void RenderSVGPath::updateZeroLengthSubpaths() +{ + m_zeroLengthLinecapLocations.clear(); + + if (!strokeWidth() || !shouldStrokeZeroLengthSubpath()) + return; + + SVGSubpathData subpathData(m_zeroLengthLinecapLocations); + path().apply(&subpathData, SVGSubpathData::updateFromPathElement); + subpathData.pathIsDone(); +} + } #endif // ENABLE(SVG) diff --git a/Source/WebCore/rendering/svg/RenderSVGPath.h b/Source/WebCore/rendering/svg/RenderSVGPath.h index 77e99e5be..ab1cf1c0b 100644 --- a/Source/WebCore/rendering/svg/RenderSVGPath.h +++ b/Source/WebCore/rendering/svg/RenderSVGPath.h @@ -39,6 +39,19 @@ public: private: virtual bool isSVGPath() const { return true; } virtual const char* renderName() const { return "RenderSVGPath"; } + + virtual void updateShapeFromElement() OVERRIDE; + FloatRect calculateUpdatedStrokeBoundingBox() const; + + virtual void strokeShape(GraphicsContext*) const OVERRIDE; + virtual bool shapeDependentStrokeContains(const FloatPoint&) OVERRIDE; + + bool shouldStrokeZeroLengthSubpath() const; + Path* zeroLengthLinecapPath(const FloatPoint&) const; + FloatRect zeroLengthSubpathRect(const FloatPoint&, float) const; + void updateZeroLengthSubpaths(); + + Vector<FloatPoint> m_zeroLengthLinecapLocations; }; } diff --git a/Source/WebCore/rendering/svg/RenderSVGShape.cpp b/Source/WebCore/rendering/svg/RenderSVGShape.cpp index 282c50a0b..62a8c99ba 100755 --- a/Source/WebCore/rendering/svg/RenderSVGShape.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGShape.cpp @@ -44,7 +44,6 @@ #include "SVGResources.h" #include "SVGResourcesCache.h" #include "SVGStyledTransformableElement.h" -#include "SVGSubpathData.h" #include "SVGTransformList.h" #include "SVGURIReference.h" #include "StrokeStyleApplier.h" @@ -72,7 +71,6 @@ void RenderSVGShape::updateShapeFromElement() SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node()); updatePathFromGraphicsElement(element, path()); - processZeroLengthSubpaths(); processMarkerPositions(); m_fillBoundingBox = calculateObjectBoundingBox(); @@ -91,8 +89,13 @@ void RenderSVGShape::fillShape(GraphicsContext* context) const void RenderSVGShape::strokeShape(GraphicsContext* context) const { - if (style()->svgStyle()->hasVisibleStroke()) - context->strokePath(path()); + ASSERT(m_path); + Path* usePath = m_path.get(); + + if (hasNonScalingStroke()) + usePath = nonScalingStrokePath(usePath, nonScalingStrokeTransform()); + + context->strokePath(*usePath); } bool RenderSVGShape::shapeDependentStrokeContains(const FloatPoint& point) @@ -136,20 +139,6 @@ bool RenderSVGShape::strokeContains(const FloatPoint& point, bool requiresStroke if (requiresStroke && !RenderSVGResource::strokePaintingResource(this, style(), fallbackColor)) return false; - for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) { - ASSERT(style()->svgStyle()->hasStroke()); - float strokeWidth = this->strokeWidth(); - if (style()->svgStyle()->capStyle() == SquareCap) { - if (zeroLengthSubpathRect(m_zeroLengthLinecapLocations[i], strokeWidth).contains(point)) - return true; - } else { - ASSERT(style()->svgStyle()->capStyle() == RoundCap); - FloatPoint radiusVector(point.x() - m_zeroLengthLinecapLocations[i].x(), point.y() - m_zeroLengthLinecapLocations[i].y()); - if (radiusVector.lengthSquared() < strokeWidth * strokeWidth * .25f) - return true; - } - } - return shapeDependentStrokeContains(point); } @@ -212,13 +201,6 @@ AffineTransform RenderSVGShape::nonScalingStrokeTransform() const return element->getScreenCTM(SVGLocatable::DisallowStyleUpdate); } -bool RenderSVGShape::shouldStrokeZeroLengthSubpath() const -{ - // Spec(11.4): Any zero length subpath shall not be stroked if the "stroke-linecap" property has a value of butt - // but shall be stroked if the "stroke-linecap" property has a value of round or square - return style()->svgStyle()->hasStroke() && style()->svgStyle()->capStyle() != ButtCap; -} - bool RenderSVGShape::shouldGenerateMarkerPositions() const { if (!style()->svgStyle()->hasMarkers()) @@ -235,94 +217,55 @@ bool RenderSVGShape::shouldGenerateMarkerPositions() const return resources->markerStart() || resources->markerMid() || resources->markerEnd(); } -FloatRect RenderSVGShape::zeroLengthSubpathRect(const FloatPoint& linecapPosition, float strokeWidth) const -{ - return FloatRect(linecapPosition.x() - strokeWidth / 2, linecapPosition.y() - strokeWidth / 2, strokeWidth, strokeWidth); -} - -Path* RenderSVGShape::zeroLengthLinecapPath(const FloatPoint& linecapPosition) -{ - // Spec(11.4): Any zero length subpath shall not be stroked if the "stroke-linecap" property has a value of butt - // but shall be stroked if the "stroke-linecap" property has a value of round or square - DEFINE_STATIC_LOCAL(Path, tempPath, ()); - - tempPath.clear(); - float strokeWidth = this->strokeWidth(); - if (style()->svgStyle()->capStyle() == SquareCap) - tempPath.addRect(zeroLengthSubpathRect(linecapPosition, strokeWidth)); - else - tempPath.addEllipse(zeroLengthSubpathRect(linecapPosition, strokeWidth)); - - return &tempPath; -} - -void RenderSVGShape::fillShape(RenderStyle* style, GraphicsContext* context, Path* path, RenderSVGShape* shape) +void RenderSVGShape::fillShape(RenderStyle* style, GraphicsContext* context) { Color fallbackColor; if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(this, style, fallbackColor)) { if (fillPaintingResource->applyResource(this, style, context, ApplyToFillMode)) - fillPaintingResource->postApplyResource(this, context, ApplyToFillMode, path, shape); + fillPaintingResource->postApplyResource(this, context, ApplyToFillMode, 0, this); else if (fallbackColor.isValid()) { RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::sharedSolidPaintingResource(); fallbackResource->setColor(fallbackColor); if (fallbackResource->applyResource(this, style, context, ApplyToFillMode)) - fallbackResource->postApplyResource(this, context, ApplyToFillMode, path, shape); + fallbackResource->postApplyResource(this, context, ApplyToFillMode, 0, this); } } } -void RenderSVGShape::strokePath(RenderStyle* style, GraphicsContext* context, Path* path, RenderSVGResource* strokePaintingResource, - const Color& fallbackColor, int applyMode) +void RenderSVGShape::strokeShape(RenderStyle* style, GraphicsContext* context) { - if (!style->svgStyle()->hasVisibleStroke()) - return; - - if (strokePaintingResource->applyResource(this, style, context, applyMode)) { - strokePaintingResource->postApplyResource(this, context, applyMode, path, this); - return; + Color fallbackColor; + if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(this, style, fallbackColor)) { + if (strokePaintingResource->applyResource(this, style, context, ApplyToStrokeMode)) + strokePaintingResource->postApplyResource(this, context, ApplyToStrokeMode, 0, this); + else if (fallbackColor.isValid()) { + RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::sharedSolidPaintingResource(); + fallbackResource->setColor(fallbackColor); + if (fallbackResource->applyResource(this, style, context, ApplyToStrokeMode)) + fallbackResource->postApplyResource(this, context, ApplyToStrokeMode, 0, this); + } } - - if (!fallbackColor.isValid()) - return; - - RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::sharedSolidPaintingResource(); - fallbackResource->setColor(fallbackColor); - if (fallbackResource->applyResource(this, style, context, applyMode)) - fallbackResource->postApplyResource(this, context, applyMode, path, this); } -void RenderSVGShape::fillAndStrokePath(GraphicsContext* context) +void RenderSVGShape::fillAndStrokeShape(GraphicsContext* context) { RenderStyle* style = this->style(); - fillShape(style, context, 0, this); + fillShape(style, context); - Color fallbackColor = Color(); - RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(this, style, fallbackColor); - if (!strokePaintingResource) + if (!style->svgStyle()->hasVisibleStroke()) return; - Path* usePath = m_path.get(); GraphicsContextStateSaver stateSaver(*context, false); AffineTransform nonScalingTransform; if (hasNonScalingStroke()) { - nonScalingTransform = nonScalingStrokeTransform(); + AffineTransform nonScalingTransform = nonScalingStrokeTransform(); if (!setupNonScalingStrokeContext(nonScalingTransform, stateSaver)) return; - usePath = nonScalingStrokePath(usePath, nonScalingTransform); } - strokePath(style, context, usePath, strokePaintingResource, fallbackColor, ApplyToStrokeMode); - - // Spec(11.4): Any zero length subpath shall not be stroked if the "stroke-linecap" property has a value of butt - // but shall be stroked if the "stroke-linecap" property has a value of round or square - for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) { - Path* usePath = zeroLengthLinecapPath(m_zeroLengthLinecapLocations[i]); - if (hasNonScalingStroke()) - usePath = nonScalingStrokePath(usePath, nonScalingTransform); - strokePath(style, context, usePath, strokePaintingResource, fallbackColor, ApplyToFillMode); - } + strokeShape(style, context); } void RenderSVGShape::paint(PaintInfo& paintInfo, const LayoutPoint&) @@ -347,7 +290,7 @@ void RenderSVGShape::paint(PaintInfo& paintInfo, const LayoutPoint&) if (svgStyle->shapeRendering() == SR_CRISPEDGES) childPaintInfo.context->setShouldAntialias(false); - fillAndStrokePath(childPaintInfo.context); + fillAndStrokeShape(childPaintInfo.context); if (!m_markerPositions.isEmpty()) drawMarkers(childPaintInfo); } @@ -453,11 +396,6 @@ FloatRect RenderSVGShape::calculateStrokeBoundingBox() const } } else strokeBoundingBox.unite(path().strokeBoundingRect(&strokeStyle)); - - // FIXME: zero-length subpaths do not respect vector-effect = non-scaling-stroke. - float strokeWidth = this->strokeWidth(); - for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) - strokeBoundingBox.unite(zeroLengthSubpathRect(m_zeroLengthLinecapLocations[i], strokeWidth)); } if (!m_markerPositions.isEmpty()) @@ -510,21 +448,6 @@ void RenderSVGShape::drawMarkers(PaintInfo& paintInfo) } } -void RenderSVGShape::processZeroLengthSubpaths() -{ - m_zeroLengthLinecapLocations.clear(); - - float strokeWidth = this->strokeWidth(); - if (!strokeWidth || !shouldStrokeZeroLengthSubpath()) - return; - - ASSERT(m_path); - - SVGSubpathData subpathData(m_zeroLengthLinecapLocations); - m_path->apply(&subpathData, SVGSubpathData::updateFromPathElement); - subpathData.pathIsDone(); -} - void RenderSVGShape::processMarkerPositions() { m_markerPositions.clear(); diff --git a/Source/WebCore/rendering/svg/RenderSVGShape.h b/Source/WebCore/rendering/svg/RenderSVGShape.h index 81c6b370c..4796e8c31 100644 --- a/Source/WebCore/rendering/svg/RenderSVGShape.h +++ b/Source/WebCore/rendering/svg/RenderSVGShape.h @@ -89,9 +89,12 @@ protected: virtual bool shapeDependentFillContains(const FloatPoint&, const WindRule) const; float strokeWidth() const; bool hasPath() const { return m_path.get(); } - bool hasNonScalingStroke() const { return style()->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE; } bool hasSmoothStroke() const; + bool hasNonScalingStroke() const { return style()->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE; } + AffineTransform nonScalingStrokeTransform() const; + Path* nonScalingStrokePath(const Path*, const AffineTransform&) const; + FloatRect m_fillBoundingBox; FloatRect m_strokeBoundingBox; @@ -115,35 +118,25 @@ private: virtual FloatRect objectBoundingBox() const { return m_fillBoundingBox; } virtual FloatRect strokeBoundingBox() const { return m_strokeBoundingBox; } - FloatRect calculateObjectBoundingBox() const; FloatRect calculateStrokeBoundingBox() const; void updateRepaintBoundingBox(); - AffineTransform nonScalingStrokeTransform() const; bool setupNonScalingStrokeContext(AffineTransform&, GraphicsContextStateSaver&); - Path* nonScalingStrokePath(const Path*, const AffineTransform&) const; - - Path* zeroLengthLinecapPath(const FloatPoint&); - bool shouldStrokeZeroLengthSubpath() const; - FloatRect zeroLengthSubpathRect(const FloatPoint&, float) const; - void processZeroLengthSubpaths(); bool shouldGenerateMarkerPositions() const; FloatRect markerRect(float strokeWidth) const; void processMarkerPositions(); - void fillShape(RenderStyle*, GraphicsContext*, Path*, RenderSVGShape*); - void strokePath(RenderStyle*, GraphicsContext*, Path*, RenderSVGResource*, - const Color&, int); - void fillAndStrokePath(GraphicsContext*); + void fillShape(RenderStyle*, GraphicsContext*); + void strokeShape(RenderStyle*, GraphicsContext*); + void fillAndStrokeShape(GraphicsContext*); void drawMarkers(PaintInfo&); private: FloatRect m_repaintBoundingBox; AffineTransform m_localTransform; OwnPtr<Path> m_path; - Vector<FloatPoint> m_zeroLengthLinecapLocations; Vector<MarkerPosition> m_markerPositions; bool m_needsBoundariesUpdate : 1; diff --git a/Source/WebCore/svg/SVGImageElement.h b/Source/WebCore/svg/SVGImageElement.h index f2f8d9b03..4ee7d783c 100644 --- a/Source/WebCore/svg/SVGImageElement.h +++ b/Source/WebCore/svg/SVGImageElement.h @@ -22,6 +22,7 @@ #define SVGImageElement_h #if ENABLE(SVG) +#include "ImageLoaderClient.h" #include "SVGAnimatedBoolean.h" #include "SVGAnimatedLength.h" #include "SVGAnimatedPreserveAspectRatio.h" @@ -38,13 +39,14 @@ class SVGImageElement : public SVGStyledTransformableElement, public SVGTests, public SVGLangSpace, public SVGExternalResourcesRequired, - public SVGURIReference { + public SVGURIReference, + public ImageLoaderClientBase<SVGImageElement> { public: static PassRefPtr<SVGImageElement> create(const QualifiedName&, Document*); private: SVGImageElement(const QualifiedName&, Document*); - + virtual bool isValid() const { return SVGTests::isValid(); } virtual bool supportsFocus() const { return true; } diff --git a/Source/WebCore/svg/SVGImageLoader.cpp b/Source/WebCore/svg/SVGImageLoader.cpp index 4f33d569e..290acdb88 100644 --- a/Source/WebCore/svg/SVGImageLoader.cpp +++ b/Source/WebCore/svg/SVGImageLoader.cpp @@ -26,22 +26,23 @@ #include "Event.h" #include "EventNames.h" #include "HTMLParserIdioms.h" +#include "ImageLoaderClient.h" #include "RenderImage.h" #include "SVGImageElement.h" namespace WebCore { -SVGImageLoader::SVGImageLoader(SVGImageElement* node) - : ImageLoader(node) +SVGImageLoader::SVGImageLoader(ImageLoaderClient* client) + : ImageLoader(client) { } void SVGImageLoader::dispatchLoadEvent() { if (image()->errorOccurred()) - element()->dispatchEvent(Event::create(eventNames().errorEvent, false, false)); + client()->imageElement()->dispatchEvent(Event::create(eventNames().errorEvent, false, false)); else { - SVGImageElement* imageElement = static_cast<SVGImageElement*>(element()); + SVGImageElement* imageElement = static_cast<SVGImageElement*>(client()->imageElement()); if (imageElement->externalResourcesRequiredBaseValue()) imageElement->sendSVGLoadEventIfPossible(true); } @@ -49,10 +50,10 @@ void SVGImageLoader::dispatchLoadEvent() String SVGImageLoader::sourceURI(const AtomicString& attribute) const { - KURL base = element()->baseURI(); + KURL base = client()->sourceElement()->baseURI(); if (base.isValid()) return KURL(base, stripLeadingAndTrailingHTMLSpaces(attribute)).string(); - return element()->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(attribute)); + return client()->sourceElement()->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(attribute)); } } diff --git a/Source/WebCore/svg/SVGImageLoader.h b/Source/WebCore/svg/SVGImageLoader.h index b7a16175c..d617cd850 100644 --- a/Source/WebCore/svg/SVGImageLoader.h +++ b/Source/WebCore/svg/SVGImageLoader.h @@ -29,7 +29,7 @@ class SVGImageElement; class SVGImageLoader : public ImageLoader { public: - SVGImageLoader(SVGImageElement*); + SVGImageLoader(ImageLoaderClient*); private: virtual void dispatchLoadEvent(); diff --git a/Source/WebCore/svg/SVGStopElement.cpp b/Source/WebCore/svg/SVGStopElement.cpp index 87143ee62..5b0e69de3 100644 --- a/Source/WebCore/svg/SVGStopElement.cpp +++ b/Source/WebCore/svg/SVGStopElement.cpp @@ -113,10 +113,14 @@ bool SVGStopElement::rendererIsNeeded(const NodeRenderingContext&) Color SVGStopElement::stopColorIncludingOpacity() const { - ASSERT(renderer()); - ASSERT(renderer()->style()); - - const SVGRenderStyle* svgStyle = renderer()->style()->svgStyle(); + RenderStyle* style = renderer() ? renderer()->style() : 0; + // FIXME: This check for null style exists to address Bug WK 90814, a rare crash condition in + // which the renderer or style is null. This entire class is scheduled for removal (Bug WK 86941) + // and we will tolerate this null check until then. + if (!style || !style->svgStyle()) + return Color(Color::transparent, true); // Transparent black. + + const SVGRenderStyle* svgStyle = style->svgStyle(); return colorWithOverrideAlpha(svgStyle->stopColor().rgb(), svgStyle->stopOpacity()); } diff --git a/Source/WebCore/svg/animation/SVGSMILElement.cpp b/Source/WebCore/svg/animation/SVGSMILElement.cpp index d59cfffd4..0dc6a8a5d 100644 --- a/Source/WebCore/svg/animation/SVGSMILElement.cpp +++ b/Source/WebCore/svg/animation/SVGSMILElement.cpp @@ -1043,7 +1043,11 @@ bool SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, b // This call may obtain a new interval -- never call calculateAnimationPercentAndRepeat() before! if (seekToTime) { seekToIntervalCorrespondingToTime(elapsed); - ASSERT(elapsed >= m_intervalBegin); + if (elapsed < m_intervalBegin) { + // elapsed is not within an interval. + m_nextProgressTime = m_intervalBegin; + return false; + } } unsigned repeat = 0; diff --git a/Source/WebCore/testing/InternalSettings.cpp b/Source/WebCore/testing/InternalSettings.cpp index 6d04cc6ea..531b04f6c 100644 --- a/Source/WebCore/testing/InternalSettings.cpp +++ b/Source/WebCore/testing/InternalSettings.cpp @@ -144,6 +144,13 @@ InternalSettings::InternalSettings(Page* page) { } +#if ENABLE(PAGE_POPUP) +PagePopupController* InternalSettings::pagePopupController() +{ + return m_pagePopupDriver ? m_pagePopupDriver->pagePopupController() : 0; +} +#endif + void InternalSettings::reset() { TextRun::setAllowsRoundingHacks(false); @@ -520,7 +527,7 @@ bool InternalSettings::shouldDisplayTrackKind(const String& kind, ExceptionCode& #endif } -void InternalSettings::setPagination(const String& mode, int gap, ExceptionCode& ec) +void InternalSettings::setPagination(const String& mode, int gap, int pageLength, ExceptionCode& ec) { if (!page()) { ec = INVALID_ACCESS_ERR; @@ -544,6 +551,7 @@ void InternalSettings::setPagination(const String& mode, int gap, ExceptionCode& } pagination.gap = gap; + pagination.pageLength = pageLength; page()->setPagination(pagination); } diff --git a/Source/WebCore/testing/InternalSettings.h b/Source/WebCore/testing/InternalSettings.h index 1596836da..f04b1fa30 100644 --- a/Source/WebCore/testing/InternalSettings.h +++ b/Source/WebCore/testing/InternalSettings.h @@ -44,6 +44,7 @@ class Frame; class Document; class MockPagePopupDriver; class Page; +class PagePopupController; class Settings; class InternalSettings : public RefCountedSupplement<Page, InternalSettings> { @@ -81,7 +82,9 @@ public: static InternalSettings* from(Page*); virtual ~InternalSettings(); - +#if ENABLE(PAGE_POPUP) + PagePopupController* pagePopupController(); +#endif void reset(); void setInspectorResourcesDataSizeLimits(int maximumResourcesContentSize, int maximumSingleResourceContentSize, ExceptionCode&); @@ -124,7 +127,8 @@ public: void setJavaScriptProfilingEnabled(bool enabled, ExceptionCode&); Vector<String> userPreferredLanguages() const; void setUserPreferredLanguages(const Vector<String>&); - void setPagination(const String& mode, int gap, ExceptionCode&); + void setPagination(const String& mode, int gap, ExceptionCode& ec) { setPagination(mode, gap, 0, ec); } + void setPagination(const String& mode, int gap, int pageLength, ExceptionCode&); void allowRoundingHacks() const; void setShouldDisplayTrackKind(const String& kind, bool enabled, ExceptionCode&); bool shouldDisplayTrackKind(const String& kind, ExceptionCode&); diff --git a/Source/WebCore/testing/InternalSettings.idl b/Source/WebCore/testing/InternalSettings.idl index 0e4647283..3b95c6531 100644 --- a/Source/WebCore/testing/InternalSettings.idl +++ b/Source/WebCore/testing/InternalSettings.idl @@ -66,7 +66,7 @@ module window { void setWindowFocusRestricted(in boolean restricted) raises(DOMException); void setDialogElementEnabled(in boolean enabled) raises(DOMException); - void setPagination(in DOMString mode, in long gap) raises(DOMException); + void setPagination(in DOMString mode, in long gap, in [Optional] long pageLength) raises(DOMException); sequence<String> userPreferredLanguages(); void setUserPreferredLanguages(in sequence<String> languages); void allowRoundingHacks(); diff --git a/Source/WebCore/testing/Internals.cpp b/Source/WebCore/testing/Internals.cpp index 188175937..e32142316 100644 --- a/Source/WebCore/testing/Internals.cpp +++ b/Source/WebCore/testing/Internals.cpp @@ -79,6 +79,10 @@ #include "NetworkInfoController.h" #endif +#if ENABLE(PAGE_POPUP) +#include "PagePopupController.h" +#endif + #if ENABLE(TOUCH_ADJUSTMENT) #include "EventHandler.h" #include "WebKitPoint.h" @@ -481,6 +485,16 @@ void Internals::setFormControlStateOfPreviousHistoryItem(PassRefPtr<DOMStringLis ec = INVALID_ACCESS_ERR; } +#if ENABLE(PAGE_POPUP) +PassRefPtr<PagePopupController> Internals::pagePopupController() +{ + InternalSettings* settings = this->settings(); + if (!settings) + return 0; + return settings->pagePopupController(); +} +#endif + PassRefPtr<ClientRect> Internals::absoluteCaretBounds(Document* document, ExceptionCode& ec) { if (!document || !document->frame() || !document->frame()->selection()) { @@ -628,9 +642,9 @@ void Internals::setScrollViewPosition(Document* document, long x, long y, Except frameView->setConstrainsScrollingToContentEdge(constrainsScrollingToContentEdgeOldValue); } -void Internals::setPagination(Document*, const String& mode, int gap, ExceptionCode& ec) +void Internals::setPagination(Document*, const String& mode, int gap, int pageLength, ExceptionCode& ec) { - settings()->setPagination(mode, gap, ec); + settings()->setPagination(mode, gap, pageLength, ec); } String Internals::configurationForViewport(Document*, float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight, ExceptionCode& ec) @@ -1076,6 +1090,18 @@ String Internals::counterValue(Element* element) return counterValueForElement(element); } +PassRefPtr<DOMStringList> Internals::iconURLs(Document* document) const +{ + Vector<IconURL> iconURLs = document->iconURLs(); + RefPtr<DOMStringList> stringList = DOMStringList::create(); + + Vector<IconURL>::const_iterator iter(iconURLs.begin()); + for (; iter != iconURLs.end(); ++iter) + stringList->append(iter->m_iconURL.string()); + + return stringList.release(); +} + #if ENABLE(FULLSCREEN_API) void Internals::webkitWillEnterFullScreenForElement(Document* document, Element* element) { diff --git a/Source/WebCore/testing/Internals.h b/Source/WebCore/testing/Internals.h index 3a36ce2c1..040052378 100644 --- a/Source/WebCore/testing/Internals.h +++ b/Source/WebCore/testing/Internals.h @@ -44,6 +44,7 @@ class Element; class Frame; class InternalSettings; class Node; +class PagePopupController; class Range; class ScriptExecutionContext; class ShadowRoot; @@ -101,6 +102,9 @@ public: #endif PassRefPtr<DOMStringList> formControlStateOfPreviousHistoryItem(ExceptionCode&); void setFormControlStateOfPreviousHistoryItem(PassRefPtr<DOMStringList>, ExceptionCode&); +#if ENABLE(PAGE_POPUP) + PassRefPtr<PagePopupController> pagePopupController(); +#endif PassRefPtr<ClientRect> absoluteCaretBounds(Document*, ExceptionCode&); @@ -115,7 +119,8 @@ public: String markerDescriptionForNode(Node*, const String& markerType, unsigned index, ExceptionCode&); void setScrollViewPosition(Document*, long x, long y, ExceptionCode&); - void setPagination(Document*, const String& mode, int gap, ExceptionCode&); + void setPagination(Document* document, const String& mode, int gap, ExceptionCode& ec) { setPagination(document, mode, gap, 0, ec); } + void setPagination(Document*, const String& mode, int gap, int pageLength, ExceptionCode&); String configurationForViewport(Document*, float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight, ExceptionCode&); bool wasLastChangeUserEdit(Element* textField, ExceptionCode&); @@ -184,6 +189,7 @@ public: #endif String counterValue(Element*); + PassRefPtr<DOMStringList> iconURLs(Document*) const; #if ENABLE(FULLSCREEN_API) void webkitWillEnterFullScreenForElement(Document*, Element*); diff --git a/Source/WebCore/testing/Internals.idl b/Source/WebCore/testing/Internals.idl index de4458716..fde4577eb 100644 --- a/Source/WebCore/testing/Internals.idl +++ b/Source/WebCore/testing/Internals.idl @@ -71,6 +71,9 @@ module window { #endif DOMString[] formControlStateOfPreviousHistoryItem() raises(DOMException); void setFormControlStateOfPreviousHistoryItem(in DOMString[] values) raises(DOMException); +#if defined(ENABLE_PAGE_POPUP) && ENABLE_PAGE_POPUP + readonly attribute PagePopupController pagePopupController; +#endif ClientRect absoluteCaretBounds(in Document document) raises(DOMException); @@ -86,7 +89,7 @@ module window { void setScrollViewPosition(in Document document, in long x, in long y) raises(DOMException); - void setPagination(in Document document, in DOMString mode, in long gap) raises(DOMException); + void setPagination(in Document document, in DOMString mode, in long gap, in [Optional] long pageLength) raises(DOMException); DOMString configurationForViewport(in Document document, in float devicePixelRatio, @@ -165,6 +168,7 @@ module window { [Conditional=INSPECTOR] sequence<String> consoleMessageArgumentCounts(in Document document); DOMString counterValue(in Element element); + DOMString[] iconURLs(in Document document); #if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API void webkitWillEnterFullScreenForElement(in Document document, in Element element); diff --git a/Source/WebCore/testing/MockPagePopupDriver.cpp b/Source/WebCore/testing/MockPagePopupDriver.cpp index 2b196a426..1eb7c4a5c 100644 --- a/Source/WebCore/testing/MockPagePopupDriver.cpp +++ b/Source/WebCore/testing/MockPagePopupDriver.cpp @@ -50,12 +50,10 @@ private: PagePopupClient* m_popupClient; RefPtr<HTMLIFrameElement> m_iframe; - RefPtr<PagePopupController> m_controller; }; inline MockPagePopup::MockPagePopup(PagePopupClient* client, const IntRect& originBoundsInRootView, Frame* mainFrame) : m_popupClient(client) - , m_controller(PagePopupController::create(client)) { Document* document = mainFrame->document(); m_iframe = HTMLIFrameElement::create(HTMLNames::iframeTag, document); @@ -71,10 +69,10 @@ inline MockPagePopup::MockPagePopup(PagePopupClient* client, const IntRect& orig writer->setMIMEType("text/html"); writer->setEncoding("UTF-8", false); writer->begin(); + const char scriptToSetUpPagePopupController[] = "<script>window.pagePopupController = parent.internals.pagePopupController;</script>"; + writer->addData(scriptToSetUpPagePopupController, sizeof(scriptToSetUpPagePopupController)); m_popupClient->writeDocument(*writer); writer->end(); - - WebCoreTestSupport::injectPagePopupController(contentFrame, m_controller.get()); } PassOwnPtr<MockPagePopup> MockPagePopup::create(PagePopupClient* client, const IntRect& originBoundsInRootView, Frame* mainFrame) @@ -110,6 +108,7 @@ PagePopup* MockPagePopupDriver::openPagePopup(PagePopupClient* client, const Int closePagePopup(m_mockPagePopup.get()); if (!client || !m_mainFrame) return 0; + m_pagePopupController = PagePopupController::create(client); m_mockPagePopup = MockPagePopup::create(client, originBoundsInRootView, m_mainFrame); return m_mockPagePopup.get(); } @@ -119,6 +118,7 @@ void MockPagePopupDriver::closePagePopup(PagePopup* popup) if (!popup || popup != m_mockPagePopup.get()) return; m_mockPagePopup.clear(); + m_pagePopupController.clear(); } } diff --git a/Source/WebCore/testing/MockPagePopupDriver.h b/Source/WebCore/testing/MockPagePopupDriver.h index fdbb47f78..e69234bb4 100644 --- a/Source/WebCore/testing/MockPagePopupDriver.h +++ b/Source/WebCore/testing/MockPagePopupDriver.h @@ -37,11 +37,13 @@ class Frame; class IntRect; class MockPagePopup; class PagePopup; +class PagePopupController; class MockPagePopupDriver : public PagePopupDriver { public: static PassOwnPtr<MockPagePopupDriver> create(Frame* mainFrame); virtual ~MockPagePopupDriver(); + PagePopupController* pagePopupController() { return m_pagePopupController.get(); } private: MockPagePopupDriver(Frame* mainFrame); @@ -52,6 +54,7 @@ private: OwnPtr<MockPagePopup> m_mockPagePopup; Frame* m_mainFrame; + RefPtr<PagePopupController> m_pagePopupController; }; } diff --git a/Source/WebCore/testing/v8/WebCoreTestSupport.cpp b/Source/WebCore/testing/v8/WebCoreTestSupport.cpp index 2bdb7a959..218c51ce1 100644 --- a/Source/WebCore/testing/v8/WebCoreTestSupport.cpp +++ b/Source/WebCore/testing/v8/WebCoreTestSupport.cpp @@ -63,14 +63,4 @@ void resetInternalsObject(v8::Local<v8::Context> context) InternalSettings::from(static_cast<Document*>(scriptContext)->frame()->page())->reset(); } -#if ENABLE(PAGE_POPUP) -void injectPagePopupController(Frame* frame, PagePopupController* controller) -{ - ASSERT(frame); - ASSERT(controller); - v8::HandleScope scope; - V8Proxy::mainWorldContext(frame)->Global()->Set(v8::String::New("pagePopupController"), toV8(controller)); -} -#endif - } diff --git a/Source/WebCore/testing/v8/WebCoreTestSupport.h b/Source/WebCore/testing/v8/WebCoreTestSupport.h index 258eea329..1ff2d7678 100644 --- a/Source/WebCore/testing/v8/WebCoreTestSupport.h +++ b/Source/WebCore/testing/v8/WebCoreTestSupport.h @@ -41,10 +41,6 @@ namespace WebCoreTestSupport { void injectInternalsObject(v8::Local<v8::Context>); void resetInternalsObject(v8::Local<v8::Context>); -#if ENABLE(PAGE_POPUP) -void injectPagePopupController(WebCore::Frame*, WebCore::PagePopupController*); -#endif - } // namespace WebCore #endif diff --git a/Source/WebKit/CMakeLists.txt b/Source/WebKit/CMakeLists.txt index 37ad19732..d25fb8127 100644 --- a/Source/WebKit/CMakeLists.txt +++ b/Source/WebKit/CMakeLists.txt @@ -16,6 +16,7 @@ SET(WebKit_INCLUDE_DIRECTORIES "${WEBCORE_DIR}/editing" "${WEBCORE_DIR}/history" "${WEBCORE_DIR}/html" + "${WEBCORE_DIR}/html/shadow" "${WEBCORE_DIR}/inspector" "${WEBCORE_DIR}/loader" "${WEBCORE_DIR}/loader/appcache" diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog index 7614d4154..eee8a48f6 100644 --- a/Source/WebKit/ChangeLog +++ b/Source/WebKit/ChangeLog @@ -1,3 +1,71 @@ +2012-07-18 Thiago Marcos P. Santos <thiago.santos@intel.com> + + [CMake] Make gtest a shared library + https://bugs.webkit.org/show_bug.cgi?id=90973 + + Reviewed by Daniel Bates. + + No need to link with gtest dependencies now since it is a shared library. + + * PlatformEfl.cmake: + +2012-07-17 Ryuan Choi <ryuan.choi@samsung.com> + + [EFL] Move codes related to theme setting from Widget to RenderTheme + https://bugs.webkit.org/show_bug.cgi?id=89842 + + Reviewed by Kenneth Rohde Christiansen. + + * CMakeLists.txt: Added html/shadow to WebKit_INCLUDE_DIRECTORIES. + +2012-07-16 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Add RegisterProtocolHandlerClient to the Modules/protocolhandler + https://bugs.webkit.org/show_bug.cgi?id=90940 + + Reviewed by Hajime Morita. + + As a step to let protocol handler be moved to the modules, RegisterProtocolHandlerClient needs + to be added to the Modules/protocolhandler. Because ChromeClient has some virtual functions for + protocol handlers, virtual functions should be moved to RegisterProtocolHandlerClient. + + * PlatformEfl.cmake: Add RegisterProtocolHandlerEfl files and include path. + +2012-07-16 Joshua Netterfield <jnetterfield@rim.com> + + [BlackBerry] Upstream WebGL Code + https://bugs.webkit.org/show_bug.cgi?id=91143 + + Reviewed by Rob Buis. + + This patch includes BlackBerry-specific fixes for anti-aliasing, logging, and shader compilation. + + * PlatformBlackBerry.cmake: Define WTF_USE_OPENGL_ES_2 on WebGL-enabled builds. + +2012-07-16 Frederik Gladhorn <frederik.gladhorn@nokia.com> + + Add accessible for QWebView. + https://bugs.webkit.org/show_bug.cgi?id=91073 + + Reviewed by Simon Hausmann. + + Add classes to enable accessibility on the widget level. + + * WebKit.pri: + * WebKit1.pro: + +2012-07-15 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + [EFL] Move files guarded by #ifdef to existing file list. + https://bugs.webkit.org/show_bug.cgi?id=91336 + + Reviewed by Ryosuke Niwa. + + Some EFL files are already guared by #ifdef. So, cmake files doesn't need to guard + them again. In addition, some files are missing #ifdef guard its header files. + + * PlatformEfl.cmake: + 2012-07-13 Thiago Marcos P. Santos <thiago.santos@intel.com> [CMake] Proper handling of ENABLE_API_TESTS build option diff --git a/Source/WebKit/PlatformBlackBerry.cmake b/Source/WebKit/PlatformBlackBerry.cmake index aac068b48..0c2f18336 100644 --- a/Source/WebKit/PlatformBlackBerry.cmake +++ b/Source/WebKit/PlatformBlackBerry.cmake @@ -109,6 +109,7 @@ LIST(APPEND WebKit_SOURCES ) IF (ENABLE_WEBGL) + ADD_DEFINITIONS (-DWTF_USE_OPENGL_ES_2=1) LIST(APPEND WebKit_INCLUDE_DIRECTORIES ${OPENGL_INCLUDE_DIR} ${THIRDPARTY_DIR}/ANGLE/src diff --git a/Source/WebKit/PlatformEfl.cmake b/Source/WebKit/PlatformEfl.cmake index f6800af57..c6243da30 100644 --- a/Source/WebKit/PlatformEfl.cmake +++ b/Source/WebKit/PlatformEfl.cmake @@ -75,9 +75,6 @@ IF (ENABLE_NETWORK_INFO) "${WEBCORE_DIR}/Modules/networkinfo" ${EEZE_INCLUDE_DIRS} ) - LIST(APPEND WebKit_SOURCES - efl/WebCoreSupport/NetworkInfoClientEfl.cpp - ) LIST(APPEND WebKit_LIBRARIES ${EEZE_LIBRARIES} ) @@ -89,6 +86,24 @@ IF (ENABLE_NOTIFICATIONS) ) ENDIF () +IF (ENABLE_VIBRATION) + LIST(APPEND WebKit_INCLUDE_DIRECTORIES + "${WEBCORE_DIR}/Modules/vibration" + ) +ENDIF () + +IF (ENABLE_BATTERY_STATUS) + LIST(APPEND WebKit_INCLUDE_DIRECTORIES + "${WEBCORE_DIR}/Modules/battery" + ) +ENDIF () + +IF (ENABLE_REGISTER_PROTOCOL_HANDLER OR ENABLE_CUSTOM_SCHEME_HANDLER) + LIST(APPEND WebKit_INCLUDE_DIRECTORIES + "${WEBCORE_DIR}/Modules/protocolhandler" + ) +ENDIF () + LIST(APPEND WebKit_SOURCES efl/WebCoreSupport/AssertMatchingEnums.cpp efl/WebCoreSupport/BatteryClientEfl.cpp @@ -102,16 +117,20 @@ LIST(APPEND WebKit_SOURCES efl/WebCoreSupport/FrameNetworkingContextEfl.cpp efl/WebCoreSupport/FullscreenVideoControllerEfl.cpp efl/WebCoreSupport/IconDatabaseClientEfl.cpp - efl/WebCoreSupport/StorageTrackerClientEfl.cpp efl/WebCoreSupport/InspectorClientEfl.cpp + efl/WebCoreSupport/NetworkInfoClientEfl.cpp efl/WebCoreSupport/NotificationPresenterClientEfl.cpp efl/WebCoreSupport/PageClientEfl.cpp efl/WebCoreSupport/PlatformStrategiesEfl.cpp + efl/WebCoreSupport/RegisterProtocolHandlerClientEfl.cpp + efl/WebCoreSupport/StorageTrackerClientEfl.cpp + efl/WebCoreSupport/VibrationClientEfl.cpp efl/ewk/ewk_auth.cpp efl/ewk/ewk_auth_soup.cpp efl/ewk/ewk_contextmenu.cpp efl/ewk/ewk_cookies.cpp + efl/ewk/ewk_custom_handler.cpp efl/ewk/ewk_frame.cpp efl/ewk/ewk_history.cpp efl/ewk/ewk_intent.cpp @@ -151,25 +170,6 @@ LIST(APPEND WebKit_LIBRARIES ${LIBSOUP24_LIBRARIES} ) -IF (ENABLE_VIBRATION) - LIST(APPEND WebKit_INCLUDE_DIRECTORIES - ${WEBCORE_DIR}/Modules/vibration - ) - LIST(APPEND WebKit_SOURCES - efl/WebCoreSupport/VibrationClientEfl.cpp - ) -ENDIF () - -IF (ENABLE_BATTERY_STATUS) - LIST(APPEND WebKit_INCLUDE_DIRECTORIES ${WEBCORE_DIR}/Modules/battery) -ENDIF () - -IF (ENABLE_REGISTER_PROTOCOL_HANDLER) - LIST(APPEND WebKit_SOURCES - efl/ewk/ewk_custom_handler.cpp - ) -ENDIF () - SET(WebKit_THEME_DEFINITION "") IF (ENABLE_PROGRESS_TAG) LIST(APPEND WebKit_THEME_DEFINITION "-DENABLE_PROGRESS_TAG") @@ -297,6 +297,7 @@ INSTALL(FILES ${WebKit_THEME} INCLUDE_DIRECTORIES(${THIRDPARTY_DIR}/gtest/include) SET(EWKUnitTests_LIBRARIES + ${WTF_LIBRARY_NAME} ${JavaScriptCore_LIBRARY_NAME} ${WebCore_LIBRARY_NAME} ${WebKit_LIBRARY_NAME} @@ -304,6 +305,7 @@ SET(EWKUnitTests_LIBRARIES ${ECORE_EVAS_LIBRARIES} ${EVAS_LIBRARIES} ${EDJE_LIBRARIES} + gtest ) SET(EWKUnitTests_INCLUDE_DIRECTORIES @@ -335,8 +337,10 @@ ENDIF () SET(DEFAULT_TEST_PAGE_DIR ${CMAKE_SOURCE_DIR}/Source/WebKit/efl/tests/resources) -ADD_DEFINITIONS(-DDEFAULT_TEST_PAGE_DIR=\"${DEFAULT_TEST_PAGE_DIR}\") -ADD_DEFINITIONS(-DDEFAULT_THEME_PATH=\"${THEME_BINARY_DIR}\") +ADD_DEFINITIONS(-DDEFAULT_TEST_PAGE_DIR=\"${DEFAULT_TEST_PAGE_DIR}\" + -DDEFAULT_THEME_PATH=\"${THEME_BINARY_DIR}\" + -DGTEST_LINKED_AS_SHARED_LIBRARY=1 +) ADD_LIBRARY(ewkTestUtils ${WEBKIT_DIR}/efl/tests/UnitTestUtils/EWKTestBase.cpp @@ -354,7 +358,7 @@ IF (ENABLE_API_TESTS) FOREACH (testName ${EWKUnitTests_BINARIES}) ADD_EXECUTABLE(${testName} ${WEBKIT_EFL_TEST_DIR}/${testName}.cpp ${WEBKIT_EFL_TEST_DIR}/test_runner.cpp) ADD_TEST(${testName} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${testName}) - TARGET_LINK_LIBRARIES(${testName} ${EWKUnitTests_LIBRARIES} ewkTestUtils gtest pthread) + TARGET_LINK_LIBRARIES(${testName} ${EWKUnitTests_LIBRARIES} ewkTestUtils) ADD_TARGET_PROPERTIES(${testName} LINK_FLAGS "${EWKUnitTests_LINK_FLAGS}") SET_TARGET_PROPERTIES(${testName} PROPERTIES FOLDER "WebKit") ENDFOREACH () diff --git a/Source/WebKit/WebKit.pri b/Source/WebKit/WebKit.pri index 3c0dbdf3d..a2d9d4bdf 100644 --- a/Source/WebKit/WebKit.pri +++ b/Source/WebKit/WebKit.pri @@ -37,3 +37,8 @@ HEADERS += \ $$PWD/qt/Api/qwebplugindatabase_p.h \ $$PWD/qt/Api/qhttpheader_p.h +haveQt(5): contains(CONFIG, accessibility) { + SOURCES += $$PWD/qt/Api/qwebviewaccessible.cpp + HEADERS += $$PWD/qt/Api/qwebviewaccessible_p.h +} + diff --git a/Source/WebKit/WebKit1.pro b/Source/WebKit/WebKit1.pro index b8f54b1f5..8b030bfc9 100644 --- a/Source/WebKit/WebKit1.pro +++ b/Source/WebKit/WebKit1.pro @@ -94,6 +94,11 @@ HEADERS += \ $$PWD/qt/WebCoreSupport/PlatformStrategiesQt.h \ $$PWD/qt/WebCoreSupport/WebEventConversion.h +haveQt(5): contains(QT_CONFIG,accessibility) { + SOURCES += $$PWD/qt/Api/qwebviewaccessible.cpp + HEADERS += $$PWD/qt/Api/qwebviewaccessible_p.h +} + INCLUDEPATH += \ $$PWD/qt/Api \ $$PWD/qt/WebCoreSupport diff --git a/Source/WebKit/blackberry/Api/BackingStore.cpp b/Source/WebKit/blackberry/Api/BackingStore.cpp index 588ee9d52..61fddfa16 100644 --- a/Source/WebKit/blackberry/Api/BackingStore.cpp +++ b/Source/WebKit/blackberry/Api/BackingStore.cpp @@ -2520,30 +2520,6 @@ void BackingStorePrivate::invalidateWindow(const Platform::IntRect& dst) window->post(dstRect); } -void BackingStorePrivate::clearWindow() -{ - if (!BlackBerry::Platform::userInterfaceThreadMessageClient()->isCurrentThread() && !shouldDirectRenderingToWindow()) { - typedef void (BlackBerry::WebKit::BackingStorePrivate::*FunctionType)(); - BlackBerry::Platform::userInterfaceThreadMessageClient()->dispatchMessage( - BlackBerry::Platform::createMethodCallMessage<FunctionType, BackingStorePrivate>( - &BackingStorePrivate::clearWindow, this)); - return; - } - - BlackBerry::Platform::Graphics::Buffer* dstBuffer = buffer(); - ASSERT(dstBuffer); - if (!dstBuffer) - BlackBerry::Platform::log(BlackBerry::Platform::LogLevelWarn, "Empty window buffer, couldn't clearWindow"); - - windowFrontBufferState()->clearBlittedRegion(); - windowBackBufferState()->addBlittedRegion(Platform::IntRect( - Platform::IntPoint(0, 0), surfaceSize())); - - Color color(m_webPage->settings()->backgroundColor()); - BlackBerry::Platform::Graphics::clearBuffer(dstBuffer, - color.red(), color.green(), color.blue(), color.alpha()); -} - void BackingStorePrivate::clearWindow(const Platform::IntRect& rect, unsigned char red, unsigned char green, diff --git a/Source/WebKit/blackberry/Api/BackingStore_p.h b/Source/WebKit/blackberry/Api/BackingStore_p.h index a09ecd43a..e140064e2 100644 --- a/Source/WebKit/blackberry/Api/BackingStore_p.h +++ b/Source/WebKit/blackberry/Api/BackingStore_p.h @@ -311,7 +311,6 @@ public: void invalidateWindow(); void invalidateWindow(const Platform::IntRect& dst); - void clearWindow(); void clearWindow(const Platform::IntRect&, unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha = 255); bool isScrollingOrZooming() const; diff --git a/Source/WebKit/blackberry/Api/WebPage.cpp b/Source/WebKit/blackberry/Api/WebPage.cpp index 97b56a7b2..2e5098d37 100644 --- a/Source/WebKit/blackberry/Api/WebPage.cpp +++ b/Source/WebKit/blackberry/Api/WebPage.cpp @@ -330,6 +330,7 @@ void WebPage::autofillTextField(const string& item) WebPagePrivate::WebPagePrivate(WebPage* webPage, WebPageClient* client, const IntRect& rect) : m_webPage(webPage) , m_client(client) + , m_inspectorClient(0) , m_page(0) // Initialized by init. , m_mainFrame(0) // Initialized by init. , m_currentContextNode(0) @@ -488,9 +489,8 @@ void WebPagePrivate::init(const WebString& pageGroupName) #if ENABLE(DRAG_SUPPORT) dragClient = new DragClientBlackBerry(); #endif - InspectorClientBlackBerry* inspectorClient = 0; #if ENABLE(INSPECTOR) - inspectorClient = new InspectorClientBlackBerry(this); + m_inspectorClient = new InspectorClientBlackBerry(this); #endif FrameLoaderClientBlackBerry* frameLoaderClient = new FrameLoaderClientBlackBerry(); @@ -500,7 +500,7 @@ void WebPagePrivate::init(const WebString& pageGroupName) pageClients.contextMenuClient = contextMenuClient; pageClients.editorClient = editorClient; pageClients.dragClient = dragClient; - pageClients.inspectorClient = inspectorClient; + pageClients.inspectorClient = m_inspectorClient; m_page = new Page(pageClients); #if !defined(PUBLIC_BUILD) || !PUBLIC_BUILD @@ -520,7 +520,7 @@ void WebPagePrivate::init(const WebString& pageGroupName) #endif #if ENABLE(BATTERY_STATUS) - WebCore::provideBatteryTo(m_page, new WebCore::BatteryClientBlackBerry); + WebCore::provideBatteryTo(m_page, new WebCore::BatteryClientBlackBerry(this)); #endif #if ENABLE(MEDIA_STREAM) @@ -1271,7 +1271,6 @@ bool WebPagePrivate::zoomAboutPoint(double unclampedScale, const FloatPoint& anc // Clear window to make sure there are no artifacts. if (shouldRender) { - m_backingStore->d->clearWindow(); // Resume all screen updates to the backingstore and render+blit visible contents to screen. m_backingStore->d->resumeScreenAndBackingStoreUpdates(BackingStore::RenderAndBlit); } else { @@ -2383,9 +2382,6 @@ Platform::WebContext WebPagePrivate::webContext(TargetDetectionStrategy strategy } } - if (!nodeAllowSelectionOverride && !node->canStartSelection()) - context.resetFlag(Platform::WebContext::IsSelectable); - if (node->isHTMLElement()) { HTMLImageElement* imageElement = 0; HTMLMediaElement* mediaElement = 0; @@ -2429,9 +2425,18 @@ Platform::WebContext WebPagePrivate::webContext(TargetDetectionStrategy strategy context.setText(curText->wholeText().utf8().data()); } + bool canStartSelection = node->canStartSelection(); + if (node->isElementNode()) { Element* element = static_cast<Element*>(node->shadowAncestorNode()); if (DOMSupport::isTextBasedContentEditableElement(element)) { + if (!canStartSelection) { + // Input fields host node is by spec non-editable unless the field itself has content editable enabled. + // Enable selection if the shadow tree for the input field is selectable. + Node* nodeUnderFinger = m_touchEventHandler->lastFatFingersResult().isValid() ? m_touchEventHandler->lastFatFingersResult().node(FatFingersResult::ShadowContentAllowed) : 0; + if (nodeUnderFinger) + canStartSelection = nodeUnderFinger->canStartSelection(); + } context.setFlag(Platform::WebContext::IsInput); if (element->hasTagName(HTMLNames::inputTag)) context.setFlag(Platform::WebContext::IsSingleLine); @@ -2444,6 +2449,9 @@ Platform::WebContext WebPagePrivate::webContext(TargetDetectionStrategy strategy } } + if (!nodeAllowSelectionOverride && !canStartSelection) + context.resetFlag(Platform::WebContext::IsSelectable); + if (node->isFocusable()) context.setFlag(Platform::WebContext::IsFocusable); @@ -3163,7 +3171,6 @@ void WebPagePrivate::zoomBlock() } notifyTransformChanged(); - m_backingStore->d->clearWindow(); m_backingStore->d->resumeScreenAndBackingStoreUpdates(BackingStore::RenderAndBlit); m_client->zoomChanged(m_webPage->isMinZoomed(), m_webPage->isMaxZoomed(), !shouldZoomOnEscape(), currentScale()); } @@ -5709,7 +5716,10 @@ void WebPage::onCertificateStoreLocationSet(const WebString& caPath) void WebPage::enableWebInspector() { - d->m_page->inspectorController()->connectFrontend(); + if (!d->m_inspectorClient) + return; + + d->m_page->inspectorController()->connectFrontend(d->m_inspectorClient); d->m_page->settings()->setDeveloperExtrasEnabled(true); } diff --git a/Source/WebKit/blackberry/Api/WebPageClient.h b/Source/WebKit/blackberry/Api/WebPageClient.h index 2742492d1..e931d6050 100644 --- a/Source/WebKit/blackberry/Api/WebPageClient.h +++ b/Source/WebKit/blackberry/Api/WebPageClient.h @@ -259,6 +259,16 @@ public: virtual bool hasKeyboardFocus() = 0; virtual bool createPopupWebView(const Platform::IntRect&) = 0; virtual void closePopupWebView() = 0; + + // Match with ChromeClient::CustomHandlersState. + enum ProtocolHandlersState { + ProtocolHandlersNew, + ProtocolHandlersRegistered, + ProtocolHandlersDeclined + }; + virtual void registerProtocolHandler(const WebString& /*scheme*/, const WebString& /*baseURL*/, const WebString& /*url*/, const WebString& /*title*/) = 0; + virtual ProtocolHandlersState isProtocolHandlerRegistered(const WebString& /*scheme*/, const WebString& /*baseURL*/, const WebString& /*url*/) = 0; + virtual void unregisterProtocolHandler(const WebString& /*scheme*/, const WebString& /*baseURL*/, const WebString& /*url*/) = 0; }; } // namespace WebKit } // namespace BlackBerry diff --git a/Source/WebKit/blackberry/Api/WebPage_p.h b/Source/WebKit/blackberry/Api/WebPage_p.h index 0e46b73c5..005631e1b 100644 --- a/Source/WebKit/blackberry/Api/WebPage_p.h +++ b/Source/WebKit/blackberry/Api/WebPage_p.h @@ -20,6 +20,7 @@ #define WebPage_p_h #include "ChromeClient.h" +#include "InspectorClientBlackBerry.h" #include "InspectorOverlay.h" #if USE(ACCELERATED_COMPOSITING) #include "GLES2Context.h" @@ -451,6 +452,7 @@ public: WebPage* m_webPage; WebPageClient* m_client; + WebCore::InspectorClientBlackBerry* m_inspectorClient; WebCore::Page* m_page; WebCore::Frame* m_mainFrame; RefPtr<WebCore::Node> m_currentContextNode; diff --git a/Source/WebKit/blackberry/ChangeLog b/Source/WebKit/blackberry/ChangeLog index 46ae45d59..351354a16 100644 --- a/Source/WebKit/blackberry/ChangeLog +++ b/Source/WebKit/blackberry/ChangeLog @@ -1,3 +1,161 @@ +2012-07-17 Jakob Petsovits <jpetsovits@rim.com> + + [BlackBerry] Remove unnecessary clearWindow() calls and the method itself + https://bugs.webkit.org/show_bug.cgi?id=91540 + RIM PR 174365 + + Reviewed by Adam Treat. + + If we resume the backingstore right afterwards with + RenderAndBlit then that'll fill the whole visible area + with content, making a clearWindow() call unnecessary. + This call is a remnant from ages ago, and is well suited + to disappear into nothingness. + + (There is still a clearWindow() call, with rect argument, + which we continue using. This commit only removes the + rect-less version.) + + * Api/BackingStore.cpp: + * Api/BackingStore_p.h: + (BackingStorePrivate): + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPagePrivate::zoomAboutPoint): + (BlackBerry::WebKit::WebPagePrivate::zoomBlock): + +2012-07-17 Vivek Galatage <vivekgalatage@gmail.com> + + Web Inspector: refactor InspectorController::connectFrontend() to accept InspectorFrontendChannel. + https://bugs.webkit.org/show_bug.cgi?id=91196 + + Reviewed by Pavel Feldman. + + Refactoring InspectorClients. InspectorClient::openInspectorFrontend + now returning the InspectorFrontendChannel. + + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPagePrivate::WebPagePrivate): + (BlackBerry::WebKit::WebPagePrivate::init): + (BlackBerry::WebKit::WebPage::enableWebInspector): + * Api/WebPage_p.h: + (WebPagePrivate): + * WebCoreSupport/InspectorClientBlackBerry.cpp: + (WebCore::InspectorClientBlackBerry::openInspectorFrontend): + * WebCoreSupport/InspectorClientBlackBerry.h: + (InspectorClientBlackBerry): + +2012-07-17 Chris Guan <chris.guan@torchmobile.com.cn> + + [BlackBerry] Enable registerProtocolHandler for Blackberry + https://bugs.webkit.org/show_bug.cgi?id=90422 + + Reviewed by George Staikos. + + Implements APIs were added in Custom Scheme Handler specification + which is at http://dev.w3.org/html5/spec/Overview.html#custom-handlers. + + Test cases: + fast/dom/register-protocol-handler.html + fast/dom/unregister-protocol-handler.html + + * Api/WebPageClient.h: + * WebCoreSupport/ChromeClientBlackBerry.cpp: + (WebCore::ChromeClientBlackBerry::isProtocolHandlerRegistered): + (WebCore::ChromeClientBlackBerry::unregisterProtocolHandler): + (WebCore::ChromeClientBlackBerry::registerProtocolHandler): + * WebCoreSupport/ChromeClientBlackBerry.h: + (ChromeClientBlackBerry): + +2012-07-16 Benjamin C Meyer <bmeyer@rim.com> + + Any webpage can crash webkit via qnx.callExtensionMethod assuming 'this' is the 'qnx' object. + https://bugs.webkit.org/show_bug.cgi?id=91419 + + Run the following in inspector to crash WebKit + + qnx.callExtensionMethod.apply(window, []); + + In the c++ that handles the function it assumes that when callExtensionMethod + is called that 'this' is the object 'qnx'. The qnx object has a hidden + variable that the code casts and uses, but when 'this' is not qnx such as the + example this will cause a crash. Any website can insert the above JavaScript + to cause the crash. + + Reviewed by Yong Li. + + * WebCoreSupport/ClientExtension.cpp: + (clientExtensionMethod): + +2012-07-16 Yong Li <yoli@rim.com> + + [BlackBerry] Improve about:memory page + https://bugs.webkit.org/show_bug.cgi?id=87676 + + Reviewed by Rob Buis. + + Add a table for process memory usage summary for easy read. + + * WebCoreSupport/AboutData.cpp: + (WebCore::memoryPage): + +2012-07-16 Kihong Kwon <kihong.kwon@samsung.com> + + Remove setController from BatteryClient + https://bugs.webkit.org/show_bug.cgi?id=90944 + + Reviewed by Adam Barth. + + BatteryClient doesn't need to keep m_controller, + because BatteryController can be accessed using BatteryController::from(). + Remove m_controller and Add webPagePrivate to BatteryClientBlackBerry. + And change all m_controller to BatteryController::from. + + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPagePrivate::init): + * WebCoreSupport/BatteryClientBlackBerry.cpp: + (WebCore::BatteryClientBlackBerry::BatteryClientBlackBerry): + (WebCore::BatteryClientBlackBerry::onLevelChange): + (WebCore::BatteryClientBlackBerry::onChargingChange): + (WebCore::BatteryClientBlackBerry::onChargingTimeChange): + (WebCore::BatteryClientBlackBerry::onDischargingTimeChange): + * WebCoreSupport/BatteryClientBlackBerry.h: + (BatteryClientBlackBerry): + +2012-07-16 Yongxin Dai <yodai@rim.com> + + [BlackBerry] Text selection with touch hold does not start on text field in some cases + https://bugs.webkit.org/show_bug.cgi?id=91267 + + Reviewed by Antonio Gomes. + + Input fields host node is by spec non-editable unless the field itself has content editable enabled. + We enable selection if the shadow tree for the input field is selectable. + PR # 173450 + + Reviewed Internally by Mike Fenton. + + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPagePrivate::webContext): + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPagePrivate::webContext): + +2012-07-15 Jonathan Dong <jonathan.dong@torchmobile.com.cn> + + [BlackBerry] Move icon database to application data directory. + https://bugs.webkit.org/show_bug.cgi?id=91195 + + Reviewed by Rob Buis. + + RIM PR: 156852 + Create icon database in application data directory instead of + database or local storage directory, by doing this we can make + things easier when clearing database or local storage data files. + + Internally reviewed by Charles Wei <charles.wei@torchmobile.com.cn> + + * WebCoreSupport/IconDatabaseClientBlackBerry.cpp: + (WebCore::IconDatabaseClientBlackBerry::initIconDatabase): + 2012-07-13 Xianzhu Wang <wangxianzhu@chromium.org> Move WebCore/platform/text/Base64 to WTF/wtf/text diff --git a/Source/WebKit/blackberry/WebCoreSupport/AboutData.cpp b/Source/WebKit/blackberry/WebCoreSupport/AboutData.cpp index 7f50d7f87..34499ba07 100644 --- a/Source/WebKit/blackberry/WebCoreSupport/AboutData.cpp +++ b/Source/WebKit/blackberry/WebCoreSupport/AboutData.cpp @@ -241,6 +241,19 @@ String memoryPage() OwnPtr<JSC::TypeCountSet> objectTypeCounts = mainHeap.objectTypeCounts(); OwnPtr<JSC::TypeCountSet> protectedObjectTypeCounts = mainHeap.protectedObjectTypeCounts(); + // Malloc info. + struct mallinfo mallocInfo = mallinfo(); + + page += "<div class='box'><div class='box-title'>Process memory usage summary</div><table class='fixed-table'><col width=75%><col width=25%>"; + + page += numberToHTMLTr("Total memory usage (malloc + JSC)", mallocInfo.arena + jscMemoryStat.stackBytes + jscMemoryStat.JITBytes + mainHeap.capacity()); + + struct stat processInfo; + if (!stat(String::format("/proc/%u/as", getpid()).latin1().data(), &processInfo)) + page += numberToHTMLTr("Total mapped memory", processInfo.st_size); + + page += "</table></div><br>"; + page += "<div class='box'><div class='box-title'>JS engine memory usage</div><table class='fixed-table'><col width=75%><col width=25%>"; page += numberToHTMLTr("Stack size", jscMemoryStat.stackBytes); @@ -254,17 +267,14 @@ String memoryPage() page += "</table></div><br>"; - page += "<div class='box'><div class='box-title'>Object type counts</div><table class='fixed-table'><col width=75%><col width=25%>"; + page += "<div class='box'><div class='box-title'>JS object type counts</div><table class='fixed-table'><col width=75%><col width=25%>"; dumpJSCTypeCountSetToTableHTML(page, objectTypeCounts.get()); page += "</table></div><br>"; - page += "<div class='box'><div class='box-title'>Protected object type counts</div><table class='fixed-table'><col width=75%><col width=25%>"; + page += "<div class='box'><div class='box-title'>JS protected object type counts</div><table class='fixed-table'><col width=75%><col width=25%>"; dumpJSCTypeCountSetToTableHTML(page, protectedObjectTypeCounts.get()); page += "</table></div><br>"; - // Malloc info. - struct mallinfo mallocInfo = mallinfo(); - page += "<div class='box'><div class='box-title'>Malloc Information</div><table class='fixed-table'><col width=75%><col width=25%>"; page += numberToHTMLTr("Total space in use", mallocInfo.usmblks + mallocInfo.uordblks); @@ -279,10 +289,6 @@ String memoryPage() page += numberToHTMLTr("Space in big blocks in use", mallocInfo.uordblks); page += numberToHTMLTr("Memory in free big blocks", mallocInfo.fordblks); - struct stat processInfo; - if (!stat(String::format("/proc/%u/as", getpid()).latin1().data(), &processInfo)) - page += numberToHTMLTr("Process total mapped memory", processInfo.st_size); - page += "</table></div>"; #endif diff --git a/Source/WebKit/blackberry/WebCoreSupport/BatteryClientBlackBerry.cpp b/Source/WebKit/blackberry/WebCoreSupport/BatteryClientBlackBerry.cpp index 7a6679dc8..c39f0698f 100644 --- a/Source/WebKit/blackberry/WebCoreSupport/BatteryClientBlackBerry.cpp +++ b/Source/WebKit/blackberry/WebCoreSupport/BatteryClientBlackBerry.cpp @@ -26,17 +26,12 @@ namespace WebCore { -BatteryClientBlackBerry::BatteryClientBlackBerry() +BatteryClientBlackBerry::BatteryClientBlackBerry(BlackBerry::WebKit::WebPagePrivate* webPagePrivate) + : m_webPagePrivate(webPagePrivate) : m_tracker(0) - , m_controller(0) { } -void BatteryClientBlackBerry::setController(BatteryController* controller) -{ - m_controller = controller; -} - void BatteryClientBlackBerry::startUpdating() { if (m_tracker) @@ -58,34 +53,22 @@ void BatteryClientBlackBerry::batteryControllerDestroyed() void BatteryClientBlackBerry::onLevelChange(bool charging, double chargingTime, double dischargingTime, double level) { - if (!m_controller) - return; - - m_controller->didChangeBatteryStatus("levelchange", BatteryStatus::create(charging, chargingTime, dischargingTime, level)); + BatteryController::from(m_webPagePrivate->m_page)->didChangeBatteryStatus("levelchange", BatteryStatus::create(charging, chargingTime, dischargingTime, level)); } void BatteryClientBlackBerry::onChargingChange(bool charging, double chargingTime, double dischargingTime, double level) { - if (!m_controller) - return; - - m_controller->didChangeBatteryStatus("chargingchange", BatteryStatus::create(charging, chargingTime, dischargingTime, level)); + BatteryController::from(m_webPagePrivate->m_page)->didChangeBatteryStatus("chargingchange", BatteryStatus::create(charging, chargingTime, dischargingTime, level)); } void BatteryClientBlackBerry::onChargingTimeChange(bool charging, double chargingTime, double dischargingTime, double level) { - if (!m_controller) - return; - - m_controller->didChangeBatteryStatus("chargingtimechange", BatteryStatus::create(charging, chargingTime, dischargingTime, level)); + BatteryController::from(m_webPagePrivate->m_page)->didChangeBatteryStatus("chargingtimechange", BatteryStatus::create(charging, chargingTime, dischargingTime, level)); } void BatteryClientBlackBerry::onDischargingTimeChange(bool charging, double chargingTime, double dischargingTime, double level) { - if (!m_controller) - return; - - m_controller->didChangeBatteryStatus("dischargingtimechange", BatteryStatus::create(charging, chargingTime, dischargingTime, level)); + BatteryController::from(m_webPagePrivate->m_page)->didChangeBatteryStatus("dischargingtimechange", BatteryStatus::create(charging, chargingTime, dischargingTime, level)); } } diff --git a/Source/WebKit/blackberry/WebCoreSupport/BatteryClientBlackBerry.h b/Source/WebKit/blackberry/WebCoreSupport/BatteryClientBlackBerry.h index 8d631cc78..a9f27a7e0 100644 --- a/Source/WebKit/blackberry/WebCoreSupport/BatteryClientBlackBerry.h +++ b/Source/WebKit/blackberry/WebCoreSupport/BatteryClientBlackBerry.h @@ -28,15 +28,13 @@ namespace WebCore { -class BatteryController; class BatteryStatus; class BatteryClientBlackBerry : public BatteryClient, public BlackBerry::Platform::BatteryStatusTrackerListener { public: - BatteryClientBlackBerry(); + explicit BatteryClientBlackBerry(BlackBerry::WebKit::WebPagePrivate*); ~BatteryClientBlackBerry() { } - virtual void setController(BatteryController*); virtual void startUpdating(); virtual void stopUpdating(); virtual void batteryControllerDestroyed(); @@ -47,8 +45,8 @@ public: void onDischargingTimeChange(bool charging, double chargingTime, double dischargingTime, double level); private: + BlackBerry::WebKit::WebPagePrivate* m_webPagePrivate; BlackBerry::Platform::BatteryStatusTracker* m_tracker; - BatteryController* m_controller; }; } diff --git a/Source/WebKit/blackberry/WebCoreSupport/ChromeClientBlackBerry.cpp b/Source/WebKit/blackberry/WebCoreSupport/ChromeClientBlackBerry.cpp index 6c09c64a2..e9741a25b 100644 --- a/Source/WebKit/blackberry/WebCoreSupport/ChromeClientBlackBerry.cpp +++ b/Source/WebKit/blackberry/WebCoreSupport/ChromeClientBlackBerry.cpp @@ -817,19 +817,21 @@ PassOwnPtr<ColorChooser> ChromeClientBlackBerry::createColorChooser(ColorChooser } #if ENABLE(CUSTOM_SCHEME_HANDLER) -ChromeClient::CustomHandlersState ChromeClientBlackBerry::isProtocolHandlerRegistered(const String&, const String&, const String&) +ChromeClient::CustomHandlersState ChromeClientBlackBerry::isProtocolHandlerRegistered(const String& scheme, const String& baseURL, const String& url) { - return ChromeClient::CustomHandlersDeclined; + return static_cast<CustomHandlersState>(m_webPagePrivate->m_client->isProtocolHandlerRegistered(scheme, baseURL, url)); } -void ChromeClientBlackBerry::unregisterProtocolHandler(const String&, const String&, const String&) +void ChromeClientBlackBerry::unregisterProtocolHandler(const String& scheme, const String& baseURL, const String& url) { + m_webPagePrivate->m_client->unregisterProtocolHandler(scheme, baseURL, url); } #endif #if ENABLE(REGISTER_PROTOCOL_HANDLER) -void ChromeClientBlackBerry::registerProtocolHandler(const WTF::String&, const WTF::String&, const WTF::String&, const WTF::String&) +void ChromeClientBlackBerry::registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title) { + m_webPagePrivate->m_client->registerProtocolHandler(scheme, baseURL, url, title); } #endif diff --git a/Source/WebKit/blackberry/WebCoreSupport/ChromeClientBlackBerry.h b/Source/WebKit/blackberry/WebCoreSupport/ChromeClientBlackBerry.h index 818beeb21..692d08052 100644 --- a/Source/WebKit/blackberry/WebCoreSupport/ChromeClientBlackBerry.h +++ b/Source/WebKit/blackberry/WebCoreSupport/ChromeClientBlackBerry.h @@ -156,12 +156,12 @@ public: #endif #if ENABLE(REGISTER_PROTOCOL_HANDLER) - virtual void registerProtocolHandler(const WTF::String&, const WTF::String&, const WTF::String&, const WTF::String&); + virtual void registerProtocolHandler(const String& /*scheme*/, const String& /*baseURL*/, const String& /*url*/, const String& /*title*/); #endif #if ENABLE(CUSTOM_SCHEME_HANDLER) - virtual CustomHandlersState isProtocolHandlerRegistered(const String&, const String&, const String&); - virtual void unregisterProtocolHandler(const String&, const String&, const String&); + virtual CustomHandlersState isProtocolHandlerRegistered(const String& /*scheme*/, const String& /*baseURL*/, const String& /*url*/); + virtual void unregisterProtocolHandler(const String& /*scheme*/, const String& /*baseURL*/, const String& /*url*/); #endif BlackBerry::WebKit::WebPagePrivate* webPagePrivate() const { return m_webPagePrivate; } diff --git a/Source/WebKit/blackberry/WebCoreSupport/ClientExtension.cpp b/Source/WebKit/blackberry/WebCoreSupport/ClientExtension.cpp index c6d0a6e24..392097189 100644 --- a/Source/WebKit/blackberry/WebCoreSupport/ClientExtension.cpp +++ b/Source/WebKit/blackberry/WebCoreSupport/ClientExtension.cpp @@ -50,7 +50,9 @@ static JSValueRef clientExtensionMethod( } WebPageClient* client = reinterpret_cast<WebPageClient*>(JSObjectGetPrivate(thisObject)); - string retVal = client->invokeClientJavaScriptCallback(strArgs, argumentCount).utf8(); + string retVal; + if (client) + retVal = client->invokeClientJavaScriptCallback(strArgs, argumentCount).utf8(); if (!retVal.empty()) jsRetVal = JSValueMakeString(ctx, JSStringCreateWithUTF8CString(retVal.c_str())); diff --git a/Source/WebKit/blackberry/WebCoreSupport/IconDatabaseClientBlackBerry.cpp b/Source/WebKit/blackberry/WebCoreSupport/IconDatabaseClientBlackBerry.cpp index 174de15b7..5f6442fdf 100644 --- a/Source/WebKit/blackberry/WebCoreSupport/IconDatabaseClientBlackBerry.cpp +++ b/Source/WebKit/blackberry/WebCoreSupport/IconDatabaseClientBlackBerry.cpp @@ -19,6 +19,7 @@ #include "config.h" #include "IconDatabaseClientBlackBerry.h" +#include "BlackBerryPlatformClient.h" #include "IconDatabase.h" #include "WebSettings.h" #include "WebString.h" @@ -50,12 +51,8 @@ bool IconDatabaseClientBlackBerry::initIconDatabase(const BlackBerry::WebKit::We iconDatabase().setClient(this); - BlackBerry::WebKit::WebString path = settings->databasePath(); - - if (path.isEmpty()) - path = settings->localStoragePath(); - - m_initState = iconDatabase().open(path, IconDatabase::defaultDatabaseFilename()) ? InitializeSucceeded : InitializeFailed; + m_initState = iconDatabase().open(BlackBerry::Platform::Client::get()->getApplicationDataDirectory().c_str(), + IconDatabase::defaultDatabaseFilename()) ? InitializeSucceeded : InitializeFailed; return m_initState == InitializeSucceeded; } diff --git a/Source/WebKit/blackberry/WebCoreSupport/InspectorClientBlackBerry.cpp b/Source/WebKit/blackberry/WebCoreSupport/InspectorClientBlackBerry.cpp index bc8236013..26c23f0ba 100644 --- a/Source/WebKit/blackberry/WebCoreSupport/InspectorClientBlackBerry.cpp +++ b/Source/WebKit/blackberry/WebCoreSupport/InspectorClientBlackBerry.cpp @@ -53,9 +53,10 @@ void InspectorClientBlackBerry::hideHighlight() m_webPagePrivate->setInspectorOverlayClient(0); } -void InspectorClientBlackBerry::openInspectorFrontend(InspectorController*) +InspectorFrontendChannel* InspectorClientBlackBerry::openInspectorFrontend(InspectorController*) { notImplemented(); + return 0; } void InspectorClientBlackBerry::closeInspectorFrontend() diff --git a/Source/WebKit/blackberry/WebCoreSupport/InspectorClientBlackBerry.h b/Source/WebKit/blackberry/WebCoreSupport/InspectorClientBlackBerry.h index 720592cde..e51631541 100644 --- a/Source/WebKit/blackberry/WebCoreSupport/InspectorClientBlackBerry.h +++ b/Source/WebKit/blackberry/WebCoreSupport/InspectorClientBlackBerry.h @@ -21,6 +21,7 @@ #define InspectorClientBlackBerry_h #include "InspectorClient.h" +#include "InspectorFrontendChannel.h" #include "InspectorOverlay.h" #include "PlatformString.h" #include <wtf/HashMap.h> @@ -33,7 +34,7 @@ class WebPagePrivate; namespace WebCore { -class InspectorClientBlackBerry : public InspectorClient, public InspectorOverlay::InspectorOverlayClient { +class InspectorClientBlackBerry : public InspectorClient, public InspectorFrontendChannel, public InspectorOverlay::InspectorOverlayClient { public: InspectorClientBlackBerry(BlackBerry::WebKit::WebPagePrivate*); virtual void inspectorDestroyed(); @@ -41,7 +42,7 @@ public: virtual void highlight(); virtual void hideHighlight(); - virtual void openInspectorFrontend(InspectorController*); + virtual InspectorFrontendChannel* openInspectorFrontend(InspectorController*); virtual void closeInspectorFrontend(); virtual void bringFrontendToFront(); diff --git a/Source/WebKit/chromium/ChangeLog b/Source/WebKit/chromium/ChangeLog index ca0049168..1654cc675 100644 --- a/Source/WebKit/chromium/ChangeLog +++ b/Source/WebKit/chromium/ChangeLog @@ -1,3 +1,357 @@ +2012-07-18 Yoshifumi Inoue <yosin@chromium.org> + + Decimal::toString should not round integer value. + https://bugs.webkit.org/show_bug.cgi?id=91481 + + Reviewed by Kent Tamura. + + This patch adds a new test cases for Decimal::toString() for failed + value and maximum coefficient value with various exponent. + + * tests/DecimalTest.cpp: + (TEST_F): DecimalTest.toString: Add test cases for big coefficient values. + +2012-07-18 Hans Wennborg <hans@chromium.org> + + Add copy constructor to WebSpeechGrammar.h + https://bugs.webkit.org/show_bug.cgi?id=91484 + + Reviewed by Adam Barth. + + Provide user-defined copy constructor (and assign function) for WebSpeechGrammar. + Without this, we were hitting the implicit copy constructor, which in + turn used the implicit copy constructor of WebPrivatePtr. This was bad, + because the implicit copy constructor wouldn't increace the reference + count on the wrapped object, causing us to crash. + + Also add one for WebSpeechRecognitionResult; haven't seen any problems + here, but I noticed it was missing. + + * public/WebSpeechGrammar.h: + (WebKit::WebSpeechGrammar::WebSpeechGrammar): + (WebSpeechGrammar): + * public/WebSpeechRecognitionResult.h: + (WebKit::WebSpeechRecognitionResult::WebSpeechRecognitionResult): + (WebSpeechRecognitionResult): + * src/WebSpeechGrammar.cpp: + (WebKit::WebSpeechGrammar::assign): + (WebKit): + +2012-07-17 Yoshifumi Inoue <yosin@chromium.org> + + Decimal constructor with 99999999999999999 loses last digit + https://bugs.webkit.org/show_bug.cgi?id=91579 + + Reviewed by Kent Tamura. + + This patch adds test cases for Decimal::EncodedData constructors for + testing edge cases in addition to common cases which they aren't + covered by other test cases. + + * tests/DecimalTest.cpp: + (EXPECT_DECIMAL_ENCODED_DATA_EQ): Introduce a new macro for ease of + writing test cases for verifying components of Decimal::EncodedData. + (TEST_F): Added a new test entry DecimalTest.Constructor. + +2012-07-17 Yoshifumi Inoue <yosin@chromium.org> + + Test cases in DecimalTest should use EXPECT_STREQ for ease of debugging test case + https://bugs.webkit.org/show_bug.cgi?id=91572 + + Reviewed by Kent Tamura. + + This patch introduces EXPECT_DECIMAL_STREQ macro to replace EXPECT_EQ + with String class for displaying text string rather than object dump + for ease of debugging test cases. + + * tests/DecimalTest.cpp: + (DecimalTest::stepDown): Changed to return Decimal instead of String + to use EXPECT_DECIMAL_STREQ. + (DecimalTest::stepUp): ditto. + (TEST_F): Replaced EXPECT_EQ + String class to EXPECT_DECIMAL_STREQ. + +2012-07-17 Joshua Bell <jsbell@chromium.org> + + IndexedDB: Key generator state not maintained across connections + https://bugs.webkit.org/show_bug.cgi?id=91456 + + Reviewed by Tony Chang. + + Add stub method implementations to test class. + + * tests/IDBFakeBackingStore.h: + +2012-07-17 Tony Chang <tony@chromium.org> + + Unreviewed, rolling out r122884. + http://trac.webkit.org/changeset/122884 + https://bugs.webkit.org/show_bug.cgi?id=91408 + + Broke the chromium-win build. + + * public/WebIDBMetadata.h: + (WebIDBMetadata): + (WebKit::WebIDBMetadata::WebIDBMetadata): + +2012-07-17 David Grogan <dgrogan@chromium.org> + + IndexedDB: Add intVersion to chromium/public/WebIDBMetadata.h + https://bugs.webkit.org/show_bug.cgi?id=91408 + + Reviewed by Adam Barth. + + This is in support of the new upgradeneeded versioning api. + intVersion will eventually replace the WebString version member. + + * public/WebIDBMetadata.h: + (WebIDBMetadata): The spec uses unsigned long long for version + numbers but we use int64_t here so that we can use -1 as a sentinel. + It indicates that a database still uses a string version. + +2012-07-17 Tony Chang <tony@chromium.org> + + Unreviewed. Rolled DEPS. + + * DEPS: + +2012-07-17 Vivek Galatage <vivekgalatage@gmail.com> + + Web Inspector: refactor InspectorController::connectFrontend() to accept InspectorFrontendChannel. + https://bugs.webkit.org/show_bug.cgi?id=91196 + + Reviewed by Pavel Feldman. + + Refactoring InspectorClients. InspectorClient::openInspectorFrontend + now returning the InspectorFrontendChannel. + + * src/InspectorClientImpl.cpp: + (WebKit::InspectorClientImpl::openInspectorFrontend): + * src/InspectorClientImpl.h: + (InspectorClientImpl): + * src/WebDevToolsAgentImpl.cpp: + (WebKit::WebDevToolsAgentImpl::reattach): + (WebKit::WebDevToolsAgentImpl::openInspectorFrontend): + * src/WebDevToolsAgentImpl.h: + (WebDevToolsAgentImpl): + +2012-07-16 Adam Barth <abarth@webkit.org> + + Unreviewed. Remove two empty directories. + + * public/linuxish: Removed. + * src/linuxish: Removed. + +2012-07-16 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Add RegisterProtocolHandlerClient to the Modules/protocolhandler + https://bugs.webkit.org/show_bug.cgi?id=90940 + + Reviewed by Hajime Morita. + + As a step to let protocol handler be moved to the modules, RegisterProtocolHandlerClient needs + to be added to the Modules/protocolhandler. Because ChromeClient has some virtual functions for + protocol handlers, virtual functions should be moved to RegisterProtocolHandlerClient. + + In order to support this, RegisterProtocolHandlerClientImpl class is added to ChromeClientImpl files. + + In addition, existing functions related to protocol handler in ChromeClientImpl class are moved to + RegisterProtocolHandlerClientImpl class. + + * WebKit.gyp: + * src/ChromeClientImpl.cpp: Implement RegisterProtocolHandlerClientImpl class. + (WebKit): + (WebKit::RegisterProtocolHandlerClientImpl::create): + (WebKit::RegisterProtocolHandlerClientImpl::RegisterProtocolHandlerClientImpl): + (WebKit::RegisterProtocolHandlerClientImpl::registerProtocolHandler): + * src/ChromeClientImpl.h: + (ChromeClientImpl): + (RegisterProtocolHandlerClientImpl): + (WebKit::RegisterProtocolHandlerClientImpl::~RegisterProtocolHandlerClientImpl): + (WebKit): + * src/WebViewImpl.cpp: Register RegisterProtocolHandlerClientImpl in order to support supplement. + (WebKit::WebViewImpl::WebViewImpl): + * src/WebViewImpl.h: + +2012-07-16 Yoshifumi Inoue <yosin@chromium.org> + + REGRESSION(r122552): DecimalTest tests (CeilingSmallExponent and FloorSmallExponent) started failing. + https://bugs.webkit.org/show_bug.cgi?id=91244 + + Reviewed by Kent Tamura. + + This patch enables and updates disabled test cases of DecimalTest + caused by fixes in r122552 of Decimal::ceiling() and Decimal::floor() + for small fraction numbers and added test cases. Fixes in r122552 + itself is correct however, it didn't update existing tests for very small + fraction numbers. + + * tests/DecimalTest.cpp: + (TEST_F): CeilingSmallExponent: Change expected value to 1 for ceiling(1e-1000), + ceiling rounds number toward positive infinity. + (TEST_F): FloorSmallExponent: Change expected value to -1 for floor(-1e-1000), + floor rounds number toward negative infinity. + +2012-07-16 Koji Ishii <kojiishi@gmail.com> + + Vertical alternate glyph (GSUB) support for OpenTypeVerticalData + https://bugs.webkit.org/show_bug.cgi?id=81389 + + Reviewed by Tony Chang. + + Tests for pointer validations for OpenType tables. + + * WebKit.gypi: + * tests/OpenTypeVerticalDataTest.cpp: Added. + (WebCore): + (TestTable): + (WebCore::TestTable::validateOffset): + (WebCore::TEST): + +2012-07-16 Alexandre Elias <aelias@google.com> + + [chromium] Fix WebFrameTest flakiness due to synthetic mouse events + https://bugs.webkit.org/show_bug.cgi?id=91428 + + Reviewed by Adam Barth. + + Synthetic mouse move events on scrolling can cause segfaults in + WebFrameTest due to delayed callbacks on the message loop after + state destruction. This is currently only affecting + the Android port, but has the potential to affect other platforms in the + future. + + We can avoid the issue by disabling the deviceSupportsMouse + setting, which shouldn't be needed by any WebFrameTest. + + * tests/FrameTestHelpers.cpp: + (WebKit::FrameTestHelpers::createWebViewAndLoad): + +2012-07-16 Alec Flett <alecflett@chromium.org> + + IndexedDB: Introduce putWithIndexKeys and calculate them in the renderer + https://bugs.webkit.org/show_bug.cgi?id=90923 + + Reviewed by Darin Fisher. + + Stub out implementations of putWithIndexKeys(), already implemented + on the chromium side. + + * public/WebIDBObjectStore.h: + (WebKit::WebIDBObjectStore::putWithIndexKeys): + * src/IDBObjectStoreBackendProxy.cpp: + (WebKit::IDBObjectStoreBackendProxy::putWithIndexKeys): + (WebKit): + * src/IDBObjectStoreBackendProxy.h: + (IDBObjectStoreBackendProxy): + +2012-07-16 Adrienne Walker <enne@google.com> + + [chromium] Unify compositor quad transforms into content space + https://bugs.webkit.org/show_bug.cgi?id=91350 + + Reviewed by Kenneth Russell. + + Update tests to add bounds/contentBounds properties to layers. This + exposed a bug in the quad culler tests where the draw transform was + incorrectly being set to the origin transform rather than being a + transform that operates on centered layer rects. Fixed this bug. + + * tests/CCQuadCullerTest.cpp: + * tests/CCSolidColorLayerImplTest.cpp: + (CCLayerTestCommon::TEST): + * tests/CCTiledLayerImplTest.cpp: + (CCLayerTestCommon::createLayer): + +2012-07-16 Adrienne Walker <enne@google.com> + + [chromium] Unify compositor quad transforms into content space + https://bugs.webkit.org/show_bug.cgi?id=91350 + + Reviewed by Kenneth Russell. + + Update tests to add bounds/contentBounds properties to layers. This + exposed a bug in the quad culler tests where the draw transform was + incorrectly being set to the origin transform rather than being a + transform that operates on centered layer rects. Fixed this bug. + + * tests/CCQuadCullerTest.cpp: + * tests/CCSolidColorLayerImplTest.cpp: + (CCLayerTestCommon::TEST): + * tests/CCTiledLayerImplTest.cpp: + (CCLayerTestCommon::createLayer): + +2012-07-16 Dana Jansens <danakj@chromium.org> + + [chromium] Remove targetRenderSurface concept, give layers a renderTarget which is the layer whose coordinate space they draw into + https://bugs.webkit.org/show_bug.cgi?id=91288 + + Reviewed by Adrienne Walker. + + * tests/CCDamageTrackerTest.cpp: + (WebKitTests::TEST_F): + * tests/CCLayerImplTest.cpp: + (WebCore::TEST): + * tests/CCLayerTreeHostCommonTest.cpp: + * tests/CCOcclusionTrackerTest.cpp: + (WebKitTests::CCOcclusionTrackerTestOverlappingSurfaceSiblings::runMyTest): + (WebKitTests::CCOcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms::runMyTest): + (WebKitTests::CCOcclusionTrackerTestAnimationOpacity1OnMainThread::runMyTest): + (WebKitTests::CCOcclusionTrackerTestAnimationOpacity0OnMainThread::runMyTest): + (WebKitTests::CCOcclusionTrackerTestAnimationTranslateOnMainThread::runMyTest): + (WebKitTests::CCOcclusionTrackerTestReplicaOccluded::runMyTest): + (WebKitTests::CCOcclusionTrackerTestSurfaceWithReplicaUnoccluded::runMyTest): + (WebKitTests::CCOcclusionTrackerTestSurfaceAndReplicaOccludedDifferently::runMyTest): + (WebKitTests::CCOcclusionTrackerTestSurfaceChildOfSurface::runMyTest): + (WebKitTests::CCOcclusionTrackerTestTopmostSurfaceIsClippedToScissor::runMyTest): + (WebKitTests::CCOcclusionTrackerTestSurfaceChildOfClippingSurface::runMyTest): + * tests/CCQuadCullerTest.cpp: + * tests/CCTiledLayerTestCommon.cpp: + (WebKitTests::FakeTiledLayerChromium::setTexturePriorities): + * tests/LayerChromiumTest.cpp: + +2012-07-16 Sami Kyostila <skyostil@chromium.org> + + [chromium] Only apply page scale delta to root scroll layer + https://bugs.webkit.org/show_bug.cgi?id=91374 + + Reviewed by Adrienne Walker. + + New unit test + CCLayerTreeHostImplTest.pageScaleDeltaAppliedToRootScrollLayerOnly to verify + the transformation of child layer while pinch zooming. + + * tests/CCLayerTreeHostImplTest.cpp: + +2012-07-16 Kihong Kwon <kihong.kwon@samsung.com> + + Remove setController from BatteryClient + https://bugs.webkit.org/show_bug.cgi?id=90944 + + Reviewed by Adam Barth. + + Remove virtual identifier from setController because setController is removed from WebCore::BatteryClient. + In addition, BatteryController is set to instance of BatteryClientImpl in the constructor of WebViewImpl. + + * src/BatteryClientImpl.h: + (BatteryClientImpl): + * src/WebViewImpl.cpp: + (WebKit::WebViewImpl::WebViewImpl): + +2012-07-16 Dana Jansens <danakj@chromium.org> + + [chromium] Incorrect assertion: Replicas will cause a RenderPass to be removed twice + https://bugs.webkit.org/show_bug.cgi?id=91328 + + Reviewed by Adrienne Walker. + + Add replicas to the surfaces in the test. + + * tests/CCLayerTreeHostTest.cpp: + (WTF::CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit::CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit): + (WTF::CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit::beginTest): + (WTF::CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit::afterTest): + (CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit): + 2012-07-13 Eric Penner <epenner@google.com> [chromium] Add 'self-managed' option to CCPrioritizedTexture to enable render-surface and canvas use cases. diff --git a/Source/WebKit/chromium/DEPS b/Source/WebKit/chromium/DEPS index b33ddc339..6194e131a 100644 --- a/Source/WebKit/chromium/DEPS +++ b/Source/WebKit/chromium/DEPS @@ -32,7 +32,7 @@ vars = { 'chromium_svn': 'http://src.chromium.org/svn/trunk/src', - 'chromium_rev': '146381' + 'chromium_rev': '146999' } deps = { diff --git a/Source/WebKit/chromium/WebKit.gypi b/Source/WebKit/chromium/WebKit.gypi index 59c00795e..40b23be49 100644 --- a/Source/WebKit/chromium/WebKit.gypi +++ b/Source/WebKit/chromium/WebKit.gypi @@ -126,6 +126,7 @@ 'tests/LocalizedNumberICUTest.cpp', 'tests/MockCCQuadCuller.h', 'tests/OpaqueRectTrackingContentLayerDelegateTest.cpp', + 'tests/OpenTypeVerticalDataTest.cpp', 'tests/PaintAggregatorTest.cpp', 'tests/PlatformGestureCurveTest.cpp', 'tests/PlatformContextSkiaTest.cpp', diff --git a/Source/WebKit/chromium/public/WebIDBObjectStore.h b/Source/WebKit/chromium/public/WebIDBObjectStore.h index ec153a719..3893c9595 100644 --- a/Source/WebKit/chromium/public/WebIDBObjectStore.h +++ b/Source/WebKit/chromium/public/WebIDBObjectStore.h @@ -51,7 +51,10 @@ public: CursorUpdate }; + typedef WebVector<WebIDBKey> WebIndexKeys; + virtual void put(const WebSerializedScriptValue&, const WebIDBKey&, PutMode, WebIDBCallbacks*, const WebIDBTransaction&, WebExceptionCode&) { WEBKIT_ASSERT_NOT_REACHED(); } + virtual void putWithIndexKeys(const WebSerializedScriptValue&, const WebIDBKey&, PutMode, WebIDBCallbacks*, const WebIDBTransaction&, const WebVector<WebString>& indexNames, const WebVector<WebIndexKeys>&, WebExceptionCode&) { WEBKIT_ASSERT_NOT_REACHED(); } virtual void deleteFunction(const WebIDBKeyRange&, WebIDBCallbacks*, const WebIDBTransaction&, WebExceptionCode&) { WEBKIT_ASSERT_NOT_REACHED(); } virtual void clear(WebIDBCallbacks*, const WebIDBTransaction&, WebExceptionCode&) { WEBKIT_ASSERT_NOT_REACHED(); } virtual WebIDBIndex* createIndex(const WebString&, const WebIDBKeyPath&, bool, bool, const WebIDBTransaction&, WebExceptionCode&) diff --git a/Source/WebKit/chromium/public/WebSpeechGrammar.h b/Source/WebKit/chromium/public/WebSpeechGrammar.h index d3c36523d..a971ff710 100644 --- a/Source/WebKit/chromium/public/WebSpeechGrammar.h +++ b/Source/WebKit/chromium/public/WebSpeechGrammar.h @@ -39,12 +39,14 @@ namespace WebKit { class WebSpeechGrammar { public: WebSpeechGrammar() { } + WebSpeechGrammar(const WebSpeechGrammar& grammar) { assign(grammar); } ~WebSpeechGrammar() { reset(); } WEBKIT_EXPORT WebURL src() const; WEBKIT_EXPORT float weight() const; WEBKIT_EXPORT void reset(); + WEBKIT_EXPORT void assign(const WebSpeechGrammar&); #if WEBKIT_IMPLEMENTATION WebSpeechGrammar(const WTF::PassRefPtr<WebCore::SpeechGrammar>&); diff --git a/Source/WebKit/chromium/public/WebSpeechRecognitionResult.h b/Source/WebKit/chromium/public/WebSpeechRecognitionResult.h index 899f28556..c225845cd 100644 --- a/Source/WebKit/chromium/public/WebSpeechRecognitionResult.h +++ b/Source/WebKit/chromium/public/WebSpeechRecognitionResult.h @@ -40,6 +40,7 @@ namespace WebKit { class WebSpeechRecognitionResult { public: WebSpeechRecognitionResult() { } + WebSpeechRecognitionResult(const WebSpeechRecognitionResult& result) { assign(result); } ~WebSpeechRecognitionResult() { reset(); } WEBKIT_EXPORT void assign(const WebVector<WebString>& transcripts, const WebVector<float>& confidences, bool final); diff --git a/Source/WebKit/chromium/src/BatteryClientImpl.h b/Source/WebKit/chromium/src/BatteryClientImpl.h index a3b1fa5d8..96ab20f20 100644 --- a/Source/WebKit/chromium/src/BatteryClientImpl.h +++ b/Source/WebKit/chromium/src/BatteryClientImpl.h @@ -36,6 +36,8 @@ #include "BatteryClient.h" #include "WebBatteryStatus.h" +namespace WebCore { class BatteryController; } + namespace WebKit { class WebBatteryStatusClient; @@ -46,9 +48,9 @@ public: virtual ~BatteryClientImpl() { } void updateBatteryStatus(const WebBatteryStatus&); + void setController(WebCore::BatteryController*); // WebCore::BatteryClient methods: - virtual void setController(WebCore::BatteryController*) OVERRIDE; virtual void startUpdating() OVERRIDE; virtual void stopUpdating() OVERRIDE; virtual void batteryControllerDestroyed() OVERRIDE; diff --git a/Source/WebKit/chromium/src/ChromeClientImpl.cpp b/Source/WebKit/chromium/src/ChromeClientImpl.cpp index b2219454c..ed5d73e50 100644 --- a/Source/WebKit/chromium/src/ChromeClientImpl.cpp +++ b/Source/WebKit/chromium/src/ChromeClientImpl.cpp @@ -103,6 +103,7 @@ #include "WindowFeatures.h" #include "WrappedResourceRequest.h" #include <public/Platform.h> +#include <wtf/text/CString.h> #include <wtf/text/StringBuilder.h> #include <wtf/text/StringConcatenate.h> #include <wtf/unicode/CharacterNames.h> @@ -496,13 +497,6 @@ IntRect ChromeClientImpl::windowResizerRect() const return result; } -#if ENABLE(REGISTER_PROTOCOL_HANDLER) -void ChromeClientImpl::registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title) -{ - m_webView->client()->registerProtocolHandler(scheme, baseURL, url, title); -} -#endif - void ChromeClientImpl::invalidateRootView(const IntRect&, bool) { notImplemented(); @@ -1118,4 +1112,21 @@ bool ChromeClientImpl::isPointerLocked() } #endif +#if ENABLE(REGISTER_PROTOCOL_HANDLER) +PassOwnPtr<RegisterProtocolHandlerClientImpl> RegisterProtocolHandlerClientImpl::create(WebViewImpl* webView) +{ + return adoptPtr(new RegisterProtocolHandlerClientImpl(webView)); +} + +RegisterProtocolHandlerClientImpl::RegisterProtocolHandlerClientImpl(WebViewImpl* webView) + : m_webView(webView) +{ +} + +void RegisterProtocolHandlerClientImpl::registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title) +{ + m_webView->client()->registerProtocolHandler(scheme, baseURL, url, title); +} +#endif + } // namespace WebKit diff --git a/Source/WebKit/chromium/src/ChromeClientImpl.h b/Source/WebKit/chromium/src/ChromeClientImpl.h index 86ff7ba68..9aa8dff32 100644 --- a/Source/WebKit/chromium/src/ChromeClientImpl.h +++ b/Source/WebKit/chromium/src/ChromeClientImpl.h @@ -34,8 +34,10 @@ #include "ChromeClientChromium.h" #include "PopupMenu.h" +#include "RegisterProtocolHandlerClient.h" #include "SearchPopupMenu.h" #include "WebNavigationPolicy.h" +#include <wtf/PassOwnPtr.h> namespace WebCore { class AccessibilityObject; @@ -107,9 +109,6 @@ public: virtual bool shouldInterruptJavaScript(); virtual WebCore::KeyboardUIMode keyboardUIMode(); virtual WebCore::IntRect windowResizerRect() const; -#if ENABLE(REGISTER_PROTOCOL_HANDLER) - virtual void registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title); -#endif virtual void invalidateRootView(const WebCore::IntRect&, bool); virtual void invalidateContentsAndRootView(const WebCore::IntRect&, bool); virtual void invalidateContentsForSlowScroll(const WebCore::IntRect&, bool); @@ -235,6 +234,19 @@ private: #endif }; +class RegisterProtocolHandlerClientImpl : public WebCore::RegisterProtocolHandlerClient { +public: + static PassOwnPtr<RegisterProtocolHandlerClientImpl> create(WebViewImpl*); + ~RegisterProtocolHandlerClientImpl() { } + + virtual void registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title) OVERRIDE; + +private: + explicit RegisterProtocolHandlerClientImpl(WebViewImpl*); + + WebViewImpl* m_webView; +}; + } // namespace WebKit #endif diff --git a/Source/WebKit/chromium/src/IDBObjectStoreBackendProxy.cpp b/Source/WebKit/chromium/src/IDBObjectStoreBackendProxy.cpp index 42f808c85..826407330 100755 --- a/Source/WebKit/chromium/src/IDBObjectStoreBackendProxy.cpp +++ b/Source/WebKit/chromium/src/IDBObjectStoreBackendProxy.cpp @@ -75,6 +75,16 @@ void IDBObjectStoreBackendProxy::put(PassRefPtr<SerializedScriptValue> value, Pa m_webIDBObjectStore->put(value, key, static_cast<WebIDBObjectStore::PutMode>(putMode), new WebIDBCallbacksImpl(callbacks), *transactionProxy->getWebIDBTransaction(), ec); } +void IDBObjectStoreBackendProxy::putWithIndexKeys(PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction, const Vector<String>& indexNames, const Vector<IndexKeys>& indexKeys, ExceptionCode& ec) +{ + // The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer, + // all implementations of IDB interfaces are proxy objects. + IDBTransactionBackendProxy* transactionProxy = static_cast<IDBTransactionBackendProxy*>(transaction); + WebVector<WebString> webIndexNames(indexNames); + WebVector<IndexKeys> webIndexKeys(indexKeys); + m_webIDBObjectStore->putWithIndexKeys(value, key, static_cast<WebIDBObjectStore::PutMode>(putMode), new WebIDBCallbacksImpl(callbacks), *transactionProxy->getWebIDBTransaction(), webIndexNames, webIndexKeys, ec); +} + void IDBObjectStoreBackendProxy::deleteFunction(PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction, ExceptionCode& ec) { // The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer, diff --git a/Source/WebKit/chromium/src/IDBObjectStoreBackendProxy.h b/Source/WebKit/chromium/src/IDBObjectStoreBackendProxy.h index c666c9fc7..c64028cff 100644 --- a/Source/WebKit/chromium/src/IDBObjectStoreBackendProxy.h +++ b/Source/WebKit/chromium/src/IDBObjectStoreBackendProxy.h @@ -45,6 +45,7 @@ public: virtual void get(PassRefPtr<WebCore::IDBKeyRange>, PassRefPtr<WebCore::IDBCallbacks>, WebCore::IDBTransactionBackendInterface*, WebCore::ExceptionCode&); virtual void put(PassRefPtr<WebCore::SerializedScriptValue>, PassRefPtr<WebCore::IDBKey>, PutMode, PassRefPtr<WebCore::IDBCallbacks>, WebCore::IDBTransactionBackendInterface*, WebCore::ExceptionCode&); + virtual void putWithIndexKeys(PassRefPtr<WebCore::SerializedScriptValue>, PassRefPtr<WebCore::IDBKey>, PutMode, PassRefPtr<WebCore::IDBCallbacks>, WebCore::IDBTransactionBackendInterface*, const WTF::Vector<WTF::String>&, const WTF::Vector<IndexKeys>&, WebCore::ExceptionCode&); virtual void deleteFunction(PassRefPtr<WebCore::IDBKeyRange>, PassRefPtr<WebCore::IDBCallbacks>, WebCore::IDBTransactionBackendInterface*, WebCore::ExceptionCode&); virtual void clear(PassRefPtr<WebCore::IDBCallbacks>, WebCore::IDBTransactionBackendInterface*, WebCore::ExceptionCode&); diff --git a/Source/WebKit/chromium/src/InspectorClientImpl.cpp b/Source/WebKit/chromium/src/InspectorClientImpl.cpp index 025876446..6948982c8 100644 --- a/Source/WebKit/chromium/src/InspectorClientImpl.cpp +++ b/Source/WebKit/chromium/src/InspectorClientImpl.cpp @@ -65,10 +65,11 @@ void InspectorClientImpl::inspectorDestroyed() agent->inspectorDestroyed(); } -void InspectorClientImpl::openInspectorFrontend(InspectorController* controller) +InspectorFrontendChannel* InspectorClientImpl::openInspectorFrontend(InspectorController* controller) { if (WebDevToolsAgentImpl* agent = devToolsAgent()) - agent->openInspectorFrontend(controller); + return agent->openInspectorFrontend(controller); + return 0; } void InspectorClientImpl::closeInspectorFrontend() diff --git a/Source/WebKit/chromium/src/InspectorClientImpl.h b/Source/WebKit/chromium/src/InspectorClientImpl.h index 5ea6baeb3..7abbd3bf5 100644 --- a/Source/WebKit/chromium/src/InspectorClientImpl.h +++ b/Source/WebKit/chromium/src/InspectorClientImpl.h @@ -33,6 +33,7 @@ #include "InspectorClient.h" #include "InspectorController.h" +#include "InspectorFrontendChannel.h" #include "platform/WebThread.h" #include <wtf/OwnPtr.h> @@ -43,6 +44,7 @@ class WebDevToolsAgentImpl; class WebViewImpl; class InspectorClientImpl : public WebCore::InspectorClient, + public WebCore::InspectorFrontendChannel, public WebThread::TaskObserver { public: InspectorClientImpl(WebViewImpl*); @@ -50,7 +52,7 @@ public: // InspectorClient methods: virtual void inspectorDestroyed(); - virtual void openInspectorFrontend(WebCore::InspectorController*); + virtual WebCore::InspectorFrontendChannel* openInspectorFrontend(WebCore::InspectorController*); virtual void closeInspectorFrontend(); virtual void bringFrontendToFront(); diff --git a/Source/WebKit/chromium/src/WebDevToolsAgentImpl.cpp b/Source/WebKit/chromium/src/WebDevToolsAgentImpl.cpp index 1bd1595b6..7a4617ddc 100644 --- a/Source/WebKit/chromium/src/WebDevToolsAgentImpl.cpp +++ b/Source/WebKit/chromium/src/WebDevToolsAgentImpl.cpp @@ -389,7 +389,7 @@ void WebDevToolsAgentImpl::attach() return; ClientMessageLoopAdapter::ensureClientMessageLoopCreated(m_client); - inspectorController()->connectFrontend(); + inspectorController()->connectFrontend(this); m_attached = true; } @@ -399,7 +399,7 @@ void WebDevToolsAgentImpl::reattach(const WebString& savedState) return; ClientMessageLoopAdapter::ensureClientMessageLoopCreated(m_client); - inspectorController()->restoreInspectorStateFromCookie(savedState); + inspectorController()->reconnectFrontend(this, savedState); m_attached = true; } @@ -492,8 +492,9 @@ void WebDevToolsAgentImpl::inspectorDestroyed() // Our lifetime is bound to the WebViewImpl. } -void WebDevToolsAgentImpl::openInspectorFrontend(InspectorController*) +InspectorFrontendChannel* WebDevToolsAgentImpl::openInspectorFrontend(InspectorController*) { + return 0; } void WebDevToolsAgentImpl::closeInspectorFrontend() diff --git a/Source/WebKit/chromium/src/WebDevToolsAgentImpl.h b/Source/WebKit/chromium/src/WebDevToolsAgentImpl.h index 6b5247617..f1af576cb 100644 --- a/Source/WebKit/chromium/src/WebDevToolsAgentImpl.h +++ b/Source/WebKit/chromium/src/WebDevToolsAgentImpl.h @@ -32,6 +32,7 @@ #define WebDevToolsAgentImpl_h #include "InspectorClient.h" +#include "InspectorFrontendChannel.h" #include "WebDevToolsAgentPrivate.h" #include "WebPageOverlay.h" @@ -65,6 +66,7 @@ struct WebDevToolsMessageData; class WebDevToolsAgentImpl : public WebDevToolsAgentPrivate, public WebCore::InspectorClient, + public WebCore::InspectorFrontendChannel, public WebPageOverlay { public: WebDevToolsAgentImpl(WebViewImpl* webViewImpl, WebDevToolsAgentClient* client); @@ -88,7 +90,7 @@ public: // InspectorClient implementation. virtual void inspectorDestroyed(); - virtual void openInspectorFrontend(WebCore::InspectorController*); + virtual WebCore::InspectorFrontendChannel* openInspectorFrontend(WebCore::InspectorController*); virtual void closeInspectorFrontend(); virtual void bringFrontendToFront(); diff --git a/Source/WebKit/chromium/src/WebSpeechGrammar.cpp b/Source/WebKit/chromium/src/WebSpeechGrammar.cpp index b28509de8..2a84767d4 100644 --- a/Source/WebKit/chromium/src/WebSpeechGrammar.cpp +++ b/Source/WebKit/chromium/src/WebSpeechGrammar.cpp @@ -36,6 +36,11 @@ void WebSpeechGrammar::reset() m_private.reset(); } +void WebSpeechGrammar::assign(const WebSpeechGrammar& other) +{ + m_private = other.m_private; +} + WebSpeechGrammar::WebSpeechGrammar(const PassRefPtr<WebCore::SpeechGrammar>& value) : m_private(value) { diff --git a/Source/WebKit/chromium/src/WebViewImpl.cpp b/Source/WebKit/chromium/src/WebViewImpl.cpp index 721bfc1d6..e349151fa 100644 --- a/Source/WebKit/chromium/src/WebViewImpl.cpp +++ b/Source/WebKit/chromium/src/WebViewImpl.cpp @@ -36,6 +36,7 @@ #include "AutofillPopupMenuClient.h" #include "BackForwardListChromium.h" #include "BatteryClientImpl.h" +#include "BatteryController.h" #include "CSSValueKeywords.h" #include "Chrome.h" #include "Color.h" @@ -427,6 +428,9 @@ WebViewImpl::WebViewImpl(WebViewClient* client) #if ENABLE(MEDIA_STREAM) , m_userMediaClientImpl(this) #endif +#if ENABLE(REGISTER_PROTOCOL_HANDLER) + , m_registerProtocolHandlerClient(RegisterProtocolHandlerClientImpl::create(this)) +#endif , m_flingModifier(0) { // WebKit/win/WebView.cpp does the same thing, except they call the @@ -456,6 +460,9 @@ WebViewImpl::WebViewImpl(WebViewClient* client) #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) provideNotification(m_page.get(), notificationPresenterImpl()); #endif +#if ENABLE(REGISTER_PROTOCOL_HANDLER) + provideRegisterProtocolHandlerTo(m_page.get(), m_registerProtocolHandlerClient.get()); +#endif provideContextFeaturesTo(m_page.get(), m_featureSwitchClient.get()); provideDeviceOrientationTo(m_page.get(), m_deviceOrientationClientProxy.get()); @@ -464,6 +471,7 @@ WebViewImpl::WebViewImpl(WebViewClient* client) #if ENABLE(BATTERY_STATUS) provideBatteryTo(m_page.get(), m_batteryClient.get()); + m_batteryClient->setController(BatteryController::from(m_page.get())); #endif m_page->setGroupName(pageGroupName); diff --git a/Source/WebKit/chromium/src/WebViewImpl.h b/Source/WebKit/chromium/src/WebViewImpl.h index 4596dcafc..8f6bdf40b 100644 --- a/Source/WebKit/chromium/src/WebViewImpl.h +++ b/Source/WebKit/chromium/src/WebViewImpl.h @@ -821,6 +821,9 @@ private: #if ENABLE(MEDIA_STREAM) UserMediaClientImpl m_userMediaClientImpl; #endif +#if ENABLE(REGISTER_PROTOCOL_HANDLER) + OwnPtr<RegisterProtocolHandlerClientImpl> m_registerProtocolHandlerClient; +#endif OwnPtr<WebCore::ActivePlatformGestureAnimation> m_gestureAnimation; WebPoint m_lastWheelPosition; WebPoint m_lastWheelGlobalPosition; diff --git a/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp b/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp index f498069f0..9433d89da 100644 --- a/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp +++ b/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp @@ -1107,7 +1107,7 @@ TEST_F(CCDamageTrackerTest, verifyDamageForEmptyLayerList) OwnPtr<CCLayerImpl> root = CCLayerImpl::create(1); root->createRenderSurface(); - ASSERT_TRUE(root->renderSurface() == root->targetRenderSurface()); + ASSERT_TRUE(root == root->renderTarget()); CCRenderSurface* targetSurface = root->renderSurface(); targetSurface->clearLayerList(); targetSurface->damageTracker()->updateDamageTrackingState(targetSurface->layerList(), targetSurface->owningLayerId(), false, IntRect(), 0, WebFilterOperations()); diff --git a/Source/WebKit/chromium/tests/CCLayerImplTest.cpp b/Source/WebKit/chromium/tests/CCLayerImplTest.cpp index 892da4f2f..22cf897cb 100644 --- a/Source/WebKit/chromium/tests/CCLayerImplTest.cpp +++ b/Source/WebKit/chromium/tests/CCLayerImplTest.cpp @@ -170,7 +170,7 @@ TEST(CCLayerImplTest, verifyLayerChangesAreTrackedProperly) EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->setClipRect(arbitraryIntRect)); EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->setUsesLayerClipping(true)); EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->setDrawOpacity(arbitraryNumber)); - EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->setTargetRenderSurface(0)); + EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->setRenderTarget(0)); EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->setDrawTransform(arbitraryTransform)); EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->setScreenSpaceTransform(arbitraryTransform)); EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->setDrawableContentRect(arbitraryIntRect)); diff --git a/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp b/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp index 54409514c..0fa742548 100644 --- a/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp +++ b/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp @@ -357,7 +357,7 @@ TEST(CCLayerTreeHostCommonTest, verifyTransformsForSingleRenderSurface) // Render surface should have been created now. ASSERT_TRUE(child->renderSurface()); - ASSERT_EQ(child->renderSurface(), child->targetRenderSurface()); + ASSERT_EQ(child, child->renderTarget()); // The child layer's draw transform should refer to its new render surface; they only differ by a translation to center. // The screen-space transform, however, should still refer to the root. @@ -365,11 +365,11 @@ TEST(CCLayerTreeHostCommonTest, verifyTransformsForSingleRenderSurface) EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpaceTransform()); // Without clipping, the origin transform and draw transform (in this particular case) should be the same. - EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->targetRenderSurface()->originTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->targetRenderSurface()->drawTransform()); + EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->renderTarget()->renderSurface()->originTransform()); + EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->renderTarget()->renderSurface()->drawTransform()); // The screen space is the same as the target since the child surface draws into the root. - EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->targetRenderSurface()->screenSpaceTransform()); + EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->renderTarget()->renderSurface()->screenSpaceTransform()); } TEST(CCLayerTreeHostCommonTest, scissorRectNoClip) @@ -464,11 +464,11 @@ TEST(CCLayerTreeHostCommonTest, scissorRectNoClip) IntRect rootDamage(rootRect); CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage); - EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(root->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); // child surface doesn't have a clip rect, therefore it will be computed as intersection // between root surface's contentrect and child surface's drawable content rect. - EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(childRect.x(), childRect.y(), rootRect.width() - childRect.x(), rootRect.height() - childRect.y())); + EXPECT_EQ(childPtr->renderTarget()->renderSurface()->scissorRect(), IntRect(childRect.x(), childRect.y(), rootRect.width() - childRect.x(), rootRect.height() - childRect.y())); EXPECT_EQ(root->scissorRect(), IntRect(rootRect)); @@ -486,8 +486,8 @@ TEST(CCLayerTreeHostCommonTest, scissorRectNoClip) CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage); // Empty damage == empty scissor - EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); - EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(root->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(childPtr->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); EXPECT_EQ(root->scissorRect(), IntRect(0, 0, 0, 0)); EXPECT_EQ(childPtr->scissorRect(), IntRect(0, 0, 0, 0)); @@ -498,10 +498,10 @@ TEST(CCLayerTreeHostCommonTest, scissorRectNoClip) CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage); // Scissors are not computed for root - EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(root->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); // Entire damage rect is within the root surface - EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), rootDamage); + EXPECT_EQ(childPtr->renderTarget()->renderSurface()->scissorRect(), rootDamage); // Entire damage rect is within the layer EXPECT_EQ(root->scissorRect(), rootDamage); @@ -517,10 +517,10 @@ TEST(CCLayerTreeHostCommonTest, scissorRectNoClip) CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage); // Scissors are not computed for root - EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(root->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); // Entire damage rect is within the root surface - EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), rootDamage); + EXPECT_EQ(childPtr->renderTarget()->renderSurface()->scissorRect(), rootDamage); // Entire damage rect is within the layer EXPECT_EQ(root->scissorRect(), rootDamage); @@ -536,11 +536,11 @@ TEST(CCLayerTreeHostCommonTest, scissorRectNoClip) CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage); // Scissors are not computed for root - EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(root->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); // Root surface does not have a clipRect, so its contentRect will be used to intersect with damage. // Result is that root damage rect is clipped at root layer boundary - EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(rootDamage.x(), rootDamage.y(), rootRect.width() - rootDamage.x(), rootRect.height() - rootDamage.y())); + EXPECT_EQ(childPtr->renderTarget()->renderSurface()->scissorRect(), IntRect(rootDamage.x(), rootDamage.y(), rootRect.width() - rootDamage.x(), rootRect.height() - rootDamage.y())); // Root does not use layer clipping, so its content rect will be used to intersect with damage // Result is that root damage rect is clipped at root layer boundary @@ -648,8 +648,8 @@ TEST(CCLayerTreeHostCommonTest, scissorRectWithClip) IntRect rootDamage(rootRect); CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage); - EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); - EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(rootRect)); + EXPECT_EQ(root->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(childPtr->renderTarget()->renderSurface()->scissorRect(), IntRect(rootRect)); EXPECT_EQ(root->scissorRect(), IntRect(rootRect)); @@ -667,8 +667,8 @@ TEST(CCLayerTreeHostCommonTest, scissorRectWithClip) CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage); // Empty damage == empty scissor - EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); - EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(root->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(childPtr->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); EXPECT_EQ(root->scissorRect(), IntRect(0, 0, 0, 0)); EXPECT_EQ(childPtr->scissorRect(), IntRect(0, 0, 0, 0)); @@ -679,10 +679,10 @@ TEST(CCLayerTreeHostCommonTest, scissorRectWithClip) CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage); // Scissors are not computed for root - EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(root->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); // Entire damage rect is within the root surface - EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), rootDamage); + EXPECT_EQ(childPtr->renderTarget()->renderSurface()->scissorRect(), rootDamage); // Entire damage rect is within the layer EXPECT_EQ(root->scissorRect(), rootDamage); @@ -698,10 +698,10 @@ TEST(CCLayerTreeHostCommonTest, scissorRectWithClip) CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage); // Scissors are not computed for root - EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(root->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); // Entire damage rect is within the root surface - EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), rootDamage); + EXPECT_EQ(childPtr->renderTarget()->renderSurface()->scissorRect(), rootDamage); // Entire damage rect is within the layer EXPECT_EQ(root->scissorRect(), rootDamage); @@ -717,11 +717,11 @@ TEST(CCLayerTreeHostCommonTest, scissorRectWithClip) CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage); // Scissors are not computed for root - EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(root->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); // Root surface does not have a clipRect, so its contentRect will be used to intersect with damage. // Result is that root damage rect is clipped at root layer boundary - EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(rootDamage.x(), rootDamage.y(), rootRect.width() - rootDamage.x(), rootRect.height() - rootDamage.y())); + EXPECT_EQ(childPtr->renderTarget()->renderSurface()->scissorRect(), IntRect(rootDamage.x(), rootDamage.y(), rootRect.width() - rootDamage.x(), rootRect.height() - rootDamage.y())); // Root does not use layer clipping, so its content rect will be used to intersect with damage // Result is that root damage rect is clipped at root layer boundary @@ -839,8 +839,8 @@ TEST(CCLayerTreeHostCommonTest, scissorRectWithClipAndSpaceTransform) IntRect rootDamage(rootRect); CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage); - EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); - EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(rootRect)); + EXPECT_EQ(root->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(childPtr->renderTarget()->renderSurface()->scissorRect(), IntRect(rootRect)); EXPECT_EQ(root->scissorRect(), IntRect(rootRect)); @@ -857,8 +857,8 @@ TEST(CCLayerTreeHostCommonTest, scissorRectWithClipAndSpaceTransform) CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage); // Empty damage == empty scissor - EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); - EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(root->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(childPtr->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); EXPECT_EQ(root->scissorRect(), IntRect(0, 0, 0, 0)); EXPECT_EQ(childPtr->scissorRect(), IntRect(0, 0, 0, 0)); @@ -869,10 +869,10 @@ TEST(CCLayerTreeHostCommonTest, scissorRectWithClipAndSpaceTransform) CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage); // Scissors are not computed for root - EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(root->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); // Entire damage rect is within the root surface - EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), rootDamage); + EXPECT_EQ(childPtr->renderTarget()->renderSurface()->scissorRect(), rootDamage); // Entire damage rect is within the layer EXPECT_EQ(root->scissorRect(), rootDamage); @@ -888,10 +888,10 @@ TEST(CCLayerTreeHostCommonTest, scissorRectWithClipAndSpaceTransform) CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage); // Scissors are not computed for root - EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(root->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); // Entire damage rect is within the root surface - EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), rootDamage); + EXPECT_EQ(childPtr->renderTarget()->renderSurface()->scissorRect(), rootDamage); // Entire damage rect is within the layer EXPECT_EQ(root->scissorRect(), rootDamage); @@ -907,11 +907,11 @@ TEST(CCLayerTreeHostCommonTest, scissorRectWithClipAndSpaceTransform) CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage); // Scissors are not computed for root - EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); + EXPECT_EQ(root->renderTarget()->renderSurface()->scissorRect(), IntRect(0, 0, 0, 0)); // Root surface does not have a clipRect, so its contentRect will be used to intersect with damage. // Result is that root damage rect is clipped at root layer boundary - EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(rootDamage.x(), rootDamage.y(), rootRect.width() - rootDamage.x(), rootRect.height() - rootDamage.y())); + EXPECT_EQ(childPtr->renderTarget()->renderSurface()->scissorRect(), IntRect(rootDamage.x(), rootDamage.y(), rootRect.width() - rootDamage.x(), rootRect.height() - rootDamage.y())); // Root does not use layer clipping, so its content rect will be used to intersect with damage // Result is that root damage rect is clipped at root layer boundary @@ -966,10 +966,10 @@ TEST(CCLayerTreeHostCommonTest, verifyTransformsForReplica) // Render surface should have been created now. ASSERT_TRUE(child->renderSurface()); - ASSERT_EQ(child->renderSurface(), child->targetRenderSurface()); + ASSERT_EQ(child, child->renderTarget()); - EXPECT_TRANSFORMATION_MATRIX_EQ(replicaCompositeTransform, child->targetRenderSurface()->replicaOriginTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(replicaCompositeTransform, child->targetRenderSurface()->replicaScreenSpaceTransform()); + EXPECT_TRANSFORMATION_MATRIX_EQ(replicaCompositeTransform, child->renderTarget()->renderSurface()->replicaOriginTransform()); + EXPECT_TRANSFORMATION_MATRIX_EQ(replicaCompositeTransform, child->renderTarget()->renderSurface()->replicaScreenSpaceTransform()); } TEST(CCLayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy) @@ -979,7 +979,7 @@ TEST(CCLayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy) // - A render surface described w.r.t. an ancestor render surface: should have a draw transform described w.r.t. that ancestor surface // - Replicas of a render surface are described w.r.t. the replica's transform around its anchor, along with the surface itself. // - Sanity check on recursion: verify transforms of layers described w.r.t. a render surface that is described w.r.t. an ancestor render surface. - // - verifying that each layer has a reference to the correct renderSurface and targetRenderSurface values. + // - verifying that each layer has a reference to the correct renderSurface and renderTarget values. RefPtr<LayerChromium> parent = LayerChromium::create(); RefPtr<LayerChromium> renderSurface1 = LayerChromium::create(); @@ -1058,19 +1058,19 @@ TEST(CCLayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy) ASSERT_FALSE(childOfRS2->renderSurface()); ASSERT_FALSE(grandChildOfRS2->renderSurface()); - // Verify all targetRenderSurface accessors + // Verify all renderTarget accessors // - EXPECT_EQ(parent->renderSurface(), parent->targetRenderSurface()); - EXPECT_EQ(parent->renderSurface(), childOfRoot->targetRenderSurface()); - EXPECT_EQ(parent->renderSurface(), grandChildOfRoot->targetRenderSurface()); + EXPECT_EQ(parent, parent->renderTarget()); + EXPECT_EQ(parent, childOfRoot->renderTarget()); + EXPECT_EQ(parent, grandChildOfRoot->renderTarget()); - EXPECT_EQ(renderSurface1->renderSurface(), renderSurface1->targetRenderSurface()); - EXPECT_EQ(renderSurface1->renderSurface(), childOfRS1->targetRenderSurface()); - EXPECT_EQ(renderSurface1->renderSurface(), grandChildOfRS1->targetRenderSurface()); + EXPECT_EQ(renderSurface1, renderSurface1->renderTarget()); + EXPECT_EQ(renderSurface1, childOfRS1->renderTarget()); + EXPECT_EQ(renderSurface1, grandChildOfRS1->renderTarget()); - EXPECT_EQ(renderSurface2->renderSurface(), renderSurface2->targetRenderSurface()); - EXPECT_EQ(renderSurface2->renderSurface(), childOfRS2->targetRenderSurface()); - EXPECT_EQ(renderSurface2->renderSurface(), grandChildOfRS2->targetRenderSurface()); + EXPECT_EQ(renderSurface2, renderSurface2->renderTarget()); + EXPECT_EQ(renderSurface2, childOfRS2->renderTarget()); + EXPECT_EQ(renderSurface2, grandChildOfRS2->renderTarget()); // Verify layer draw transforms // note that draw transforms are described with respect to the nearest ancestor render surface @@ -1278,7 +1278,7 @@ TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWit CCLayerImpl* child = root->children()[0].get(); CCLayerImpl* grandChild = child->children()[0].get(); - // This scale will cause child and grandChild to be effectively 200 x 800 with respect to the targetRenderSurface. + // This scale will cause child and grandChild to be effectively 200 x 800 with respect to the renderTarget. WebTransformationMatrix nonUniformScale; nonUniformScale.scaleNonUniform(2, 8); child->setTransform(nonUniformScale); @@ -1378,7 +1378,7 @@ TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWit child->setTransform(rotationAboutZ); grandChild->setPosition(FloatPoint(8, 6)); grandChild->setTransform(rotationAboutZ); - greatGrandChild->setFixedToContainerLayer(true); // greatGrandChild is positioned upside-down with respect to the targetRenderSurface + greatGrandChild->setFixedToContainerLayer(true); // greatGrandChild is positioned upside-down with respect to the renderTarget. // Case 1: scrollDelta of 0, 0 child->setScrollDelta(IntSize(0, 0)); @@ -1444,7 +1444,7 @@ TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWit child->setTransform(rotationAboutZ); grandChild->setPosition(FloatPoint(8, 6)); grandChild->setTransform(rotationAboutZ); - greatGrandChild->setFixedToContainerLayer(true); // greatGrandChild is positioned upside-down with respect to the targetRenderSurface + greatGrandChild->setFixedToContainerLayer(true); // greatGrandChild is positioned upside-down with respect to the renderTarget. // Case 1: scrollDelta of 0, 0 child->setScrollDelta(IntSize(0, 0)); @@ -1685,7 +1685,7 @@ TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWit { // This test checks for correct scroll compensation when the fixed-position container // itself has a renderSurface. In this case, the container layer should be treated - // like a layer that contributes to a targetRenderSurface, and that targetRenderSurface + // like a layer that contributes to a renderTarget, and that renderTarget // is completely irrelevant; it should not affect the scroll compensation. DebugScopedSetImplThread scopedImplThread; @@ -2231,19 +2231,19 @@ TEST(CCLayerTreeHostCommonTest, verifyAnimationsForRenderSurfaceHierarchy) ASSERT_FALSE(childOfRS2->renderSurface()); ASSERT_FALSE(grandChildOfRS2->renderSurface()); - // Verify all targetRenderSurface accessors + // Verify all renderTarget accessors // - EXPECT_EQ(parent->renderSurface(), parent->targetRenderSurface()); - EXPECT_EQ(parent->renderSurface(), childOfRoot->targetRenderSurface()); - EXPECT_EQ(parent->renderSurface(), grandChildOfRoot->targetRenderSurface()); + EXPECT_EQ(parent, parent->renderTarget()); + EXPECT_EQ(parent, childOfRoot->renderTarget()); + EXPECT_EQ(parent, grandChildOfRoot->renderTarget()); - EXPECT_EQ(renderSurface1->renderSurface(), renderSurface1->targetRenderSurface()); - EXPECT_EQ(renderSurface1->renderSurface(), childOfRS1->targetRenderSurface()); - EXPECT_EQ(renderSurface1->renderSurface(), grandChildOfRS1->targetRenderSurface()); + EXPECT_EQ(renderSurface1, renderSurface1->renderTarget()); + EXPECT_EQ(renderSurface1, childOfRS1->renderTarget()); + EXPECT_EQ(renderSurface1, grandChildOfRS1->renderTarget()); - EXPECT_EQ(renderSurface2->renderSurface(), renderSurface2->targetRenderSurface()); - EXPECT_EQ(renderSurface2->renderSurface(), childOfRS2->targetRenderSurface()); - EXPECT_EQ(renderSurface2->renderSurface(), grandChildOfRS2->targetRenderSurface()); + EXPECT_EQ(renderSurface2, renderSurface2->renderTarget()); + EXPECT_EQ(renderSurface2, childOfRS2->renderTarget()); + EXPECT_EQ(renderSurface2, grandChildOfRS2->renderTarget()); // Verify drawOpacityIsAnimating values // @@ -3789,7 +3789,7 @@ TEST(CCLayerTreeHostCommonTest, verifySubtreeSearch) // - add a case that checks if a render surface's replicaTransform is computed correctly. // - test all the conditions under which render surfaces are created // - if possible, test all conditions under which render surfaces are not created -// - verify that the layer lists of render surfaces are correct, verify that "targetRenderSurface" values for each layer are correct. +// - verify that the layer lists of render surfaces are correct, verify that renderTarget's RenderSurface values for each layer are correct. // - test the computation of clip rects and content rects // - test the special cases for mask layers and replica layers // - test the other functions in CCLayerTreeHostCommon diff --git a/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp b/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp index cb2b7f36f..e9b9f0281 100644 --- a/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp +++ b/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp @@ -989,6 +989,45 @@ TEST_F(CCLayerTreeHostImplTest, scrollRootAndChangePageScaleOnImplThread) EXPECT_EQ(m_hostImpl->rootLayer()->pageScaleDelta(), pageScale); } +TEST_F(CCLayerTreeHostImplTest, pageScaleDeltaAppliedToRootScrollLayerOnly) +{ + IntSize surfaceSize(10, 10); + float defaultPageScale = 1; + float newPageScale = 2; + + // Create a normal scrollable root layer and another scrollable child layer. + setupScrollAndContentsLayers(surfaceSize); + CCLayerImpl* root = m_hostImpl->rootLayer(); + CCLayerImpl* child = root->children()[0].get(); + + OwnPtr<CCLayerImpl> scrollableChild = createScrollableLayer(3, FloatPoint(5, 5), surfaceSize); + child->addChild(scrollableChild.release()); + CCLayerImpl* grandChild = child->children()[0].get(); + + // Set new page scale on impl thread by pinching. + m_hostImpl->pinchGestureBegin(); + m_hostImpl->pinchGestureUpdate(newPageScale, IntPoint()); + m_hostImpl->pinchGestureEnd(); + + // The page scale delta should only be applied to the scrollable root layer. + EXPECT_EQ(root->pageScaleDelta(), newPageScale); + EXPECT_EQ(child->pageScaleDelta(), defaultPageScale); + EXPECT_EQ(grandChild->pageScaleDelta(), defaultPageScale); + + // Make sure all the layers are drawn with the page scale delta applied, i.e., the page scale + // delta on the root layer is applied hierarchically. + CCLayerTreeHostImpl::FrameData frame; + EXPECT_TRUE(m_hostImpl->prepareToDraw(frame)); + m_hostImpl->drawLayers(frame); + m_hostImpl->didDrawAllLayers(frame); + + WebTransformationMatrix pageScaleTransform; + pageScaleTransform.scale(newPageScale); + EXPECT_EQ(root->drawTransform(), pageScaleTransform); + EXPECT_EQ(child->drawTransform(), pageScaleTransform); + EXPECT_EQ(grandChild->drawTransform(), pageScaleTransform); +} + TEST_F(CCLayerTreeHostImplTest, scrollChildAndChangePageScaleOnMainThread) { IntSize surfaceSize(10, 10); diff --git a/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp b/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp index 97d4568da..b0e9ee8d6 100644 --- a/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp +++ b/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp @@ -2267,7 +2267,9 @@ public: CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit() : m_rootLayer(ContentLayerChromiumWithUpdateTracking::create(&m_mockDelegate)) , m_surfaceLayer1(ContentLayerChromiumWithUpdateTracking::create(&m_mockDelegate)) + , m_replicaLayer1(ContentLayerChromiumWithUpdateTracking::create(&m_mockDelegate)) , m_surfaceLayer2(ContentLayerChromiumWithUpdateTracking::create(&m_mockDelegate)) + , m_replicaLayer2(ContentLayerChromiumWithUpdateTracking::create(&m_mockDelegate)) { } @@ -2283,6 +2285,9 @@ public: m_surfaceLayer2->setForceRenderSurface(true); m_surfaceLayer2->setOpacity(0.5); + m_surfaceLayer1->setReplicaLayer(m_replicaLayer1.get()); + m_surfaceLayer2->setReplicaLayer(m_replicaLayer2.get()); + m_rootLayer->addChild(m_surfaceLayer1); m_surfaceLayer1->addChild(m_surfaceLayer2); m_layerTreeHost->setRootLayer(m_rootLayer); @@ -2321,14 +2326,18 @@ public: // Clear layer references so CCLayerTreeHost dies. m_rootLayer.clear(); m_surfaceLayer1.clear(); + m_replicaLayer1.clear(); m_surfaceLayer2.clear(); + m_replicaLayer2.clear(); } private: MockContentLayerDelegate m_mockDelegate; RefPtr<ContentLayerChromiumWithUpdateTracking> m_rootLayer; RefPtr<ContentLayerChromiumWithUpdateTracking> m_surfaceLayer1; + RefPtr<ContentLayerChromiumWithUpdateTracking> m_replicaLayer1; RefPtr<ContentLayerChromiumWithUpdateTracking> m_surfaceLayer2; + RefPtr<ContentLayerChromiumWithUpdateTracking> m_replicaLayer2; }; SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit) diff --git a/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp b/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp index f0bfd0ea3..87bde5117 100644 --- a/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp +++ b/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp @@ -1044,7 +1044,7 @@ protected: occlusion.setLayerScissorRect(IntRect(-20, -20, 1000, 1000)); // There is nothing above child2's surface in the z-order. - EXPECT_INT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2->renderSurface(), false, IntRect(-10, 420, 70, 80))); + EXPECT_INT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2, false, IntRect(-10, 420, 70, 80))); this->leaveContributingSurface(child2, occlusion); this->visitLayer(layer1, occlusion); @@ -1062,7 +1062,7 @@ protected: EXPECT_FALSE(occlusion.occluded(child1, IntRect(-10, 430, 80, 71))); // child2's contents will occlude child1 below it. - EXPECT_INT_RECT_EQ(IntRect(-10, 430, 10, 70), occlusion.unoccludedContributingSurfaceContentRect(child1->renderSurface(), false, IntRect(-10, 430, 80, 70))); + EXPECT_INT_RECT_EQ(IntRect(-10, 430, 10, 70), occlusion.unoccludedContributingSurfaceContentRect(child1, false, IntRect(-10, 430, 80, 70))); this->leaveContributingSurface(child1, occlusion); this->enterLayer(parent, occlusion); @@ -1153,7 +1153,7 @@ protected: this->enterContributingSurface(child2, occlusion); // There is nothing above child2's surface in the z-order. - EXPECT_INT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2->renderSurface(), false, IntRect(-10, 420, 70, 80))); + EXPECT_INT_RECT_EQ(IntRect(-10, 420, 70, 80), occlusion.unoccludedContributingSurfaceContentRect(child2, false, IntRect(-10, 420, 70, 80))); this->leaveContributingSurface(child2, occlusion); this->visitLayer(layer1, occlusion); @@ -1171,9 +1171,9 @@ protected: EXPECT_FALSE(occlusion.occluded(child1, IntRect(421, -20, 80, 90))); // child2's contents will occlude child1 below it. - EXPECT_INT_RECT_EQ(IntRect(420, -20, 80, 90), occlusion.unoccludedContributingSurfaceContentRect(child1->renderSurface(), false, IntRect(420, -20, 80, 90))); - EXPECT_INT_RECT_EQ(IntRect(490, -10, 10, 80), occlusion.unoccludedContributingSurfaceContentRect(child1->renderSurface(), false, IntRect(420, -10, 80, 90))); - EXPECT_INT_RECT_EQ(IntRect(420, -20, 70, 10), occlusion.unoccludedContributingSurfaceContentRect(child1->renderSurface(), false, IntRect(420, -20, 70, 90))); + EXPECT_INT_RECT_EQ(IntRect(420, -20, 80, 90), occlusion.unoccludedContributingSurfaceContentRect(child1, false, IntRect(420, -20, 80, 90))); + EXPECT_INT_RECT_EQ(IntRect(490, -10, 10, 80), occlusion.unoccludedContributingSurfaceContentRect(child1, false, IntRect(420, -10, 80, 90))); + EXPECT_INT_RECT_EQ(IntRect(420, -20, 70, 10), occlusion.unoccludedContributingSurfaceContentRect(child1, false, IntRect(420, -20, 70, 90))); this->leaveContributingSurface(child1, occlusion); this->enterLayer(parent, occlusion); @@ -2077,7 +2077,7 @@ protected: this->enterContributingSurface(surface, occlusion); // Occlusion within the surface is lost when leaving the animating surface. - EXPECT_INT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 300, 300))); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 300, 300))); this->leaveContributingSurface(surface, occlusion); this->visitLayer(layer, occlusion); @@ -2129,7 +2129,7 @@ protected: this->enterContributingSurface(surface, occlusion); // Occlusion within the surface is lost when leaving the animating surface. - EXPECT_INT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 300, 300))); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 250, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 300, 300))); this->leaveContributingSurface(surface, occlusion); this->visitLayer(layer, occlusion); @@ -2218,7 +2218,7 @@ protected: this->enterContributingSurface(surface, occlusion); // The contributing |surface| is animating so it can't be occluded. - EXPECT_INT_RECT_EQ(IntRect(0, 0, 300, 300), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 300, 300))); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 300, 300), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 300, 300))); this->leaveContributingSurface(surface, occlusion); this->enterLayer(layer, occlusion); @@ -2333,7 +2333,7 @@ protected: this->enterContributingSurface(surface, occlusion); // Surface is not occluded so it shouldn't think it is. - EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 100, 100))); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100))); } }; @@ -2371,8 +2371,8 @@ protected: this->enterContributingSurface(surface, occlusion); // Surface is occluded, but only the top 10px of the replica. - EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 100, 100))); - EXPECT_INT_RECT_EQ(IntRect(0, 10, 100, 90), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), true, IntRect(0, 0, 100, 100))); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 0, 0), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100))); + EXPECT_INT_RECT_EQ(IntRect(0, 10, 100, 90), occlusion.unoccludedContributingSurfaceContentRect(surface, true, IntRect(0, 0, 100, 100))); } }; @@ -2412,8 +2412,8 @@ protected: this->enterContributingSurface(surface, occlusion); // Surface and replica are occluded different amounts. - EXPECT_INT_RECT_EQ(IntRect(40, 0, 60, 100), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 100, 100))); - EXPECT_INT_RECT_EQ(IntRect(50, 0, 50, 100), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), true, IntRect(0, 0, 100, 100))); + EXPECT_INT_RECT_EQ(IntRect(40, 0, 60, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100))); + EXPECT_INT_RECT_EQ(IntRect(50, 0, 50, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, true, IntRect(0, 0, 100, 100))); } }; @@ -2458,7 +2458,7 @@ protected: this->enterContributingSurface(surfaceChild, occlusion); // The surfaceChild's parent does not have a clipRect as it owns a render surface. Make sure the unoccluded rect // does not get clipped away inappropriately. - EXPECT_INT_RECT_EQ(IntRect(0, 40, 100, 10), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild->renderSurface(), false, IntRect(0, 0, 100, 50))); + EXPECT_INT_RECT_EQ(IntRect(0, 40, 100, 10), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild, false, IntRect(0, 0, 100, 50))); this->leaveContributingSurface(surfaceChild, occlusion); // When the surfaceChild's occlusion is transformed up to its parent, make sure it is not clipped away inappropriately also. @@ -2471,7 +2471,7 @@ protected: this->enterContributingSurface(surface, occlusion); // The surface's parent does have a clipRect as it is the root layer. - EXPECT_INT_RECT_EQ(IntRect(0, 50, 100, 50), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 100, 100))); + EXPECT_INT_RECT_EQ(IntRect(0, 50, 100, 50), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100))); } }; @@ -2497,7 +2497,7 @@ protected: // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect. this->enterContributingSurface(surface, occlusion); // Make sure the parent's clipRect clips the unoccluded region of the child surface. - EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 200), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 100, 300))); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 200), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 300))); } this->resetLayerIterator(); { @@ -2509,7 +2509,7 @@ protected: // The root layer always has a clipRect. So the parent of |surface| has a clipRect giving the surface itself a clipRect. this->enterContributingSurface(surface, occlusion); // Make sure the screen scissor rect clips the unoccluded region of the child surface. - EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 100, 300))); + EXPECT_INT_RECT_EQ(IntRect(0, 0, 100, 100), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 300))); } } }; @@ -2554,13 +2554,13 @@ protected: this->enterContributingSurface(surfaceChild, occlusion); // The surfaceChild's parent does not have a clipRect as it owns a render surface. - EXPECT_INT_RECT_EQ(IntRect(0, 50, 80, 50), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild->renderSurface(), false, IntRect(0, 0, 100, 100))); + EXPECT_INT_RECT_EQ(IntRect(0, 50, 80, 50), occlusion.unoccludedContributingSurfaceContentRect(surfaceChild, false, IntRect(0, 0, 100, 100))); this->leaveContributingSurface(surfaceChild, occlusion); this->visitLayer(surface, occlusion); this->enterContributingSurface(surface, occlusion); // The surface's parent does have a clipRect as it is the root layer. - EXPECT_INT_RECT_EQ(IntRect(0, 50, 80, 50), occlusion.unoccludedContributingSurfaceContentRect(surface->renderSurface(), false, IntRect(0, 0, 100, 100))); + EXPECT_INT_RECT_EQ(IntRect(0, 50, 80, 50), occlusion.unoccludedContributingSurfaceContentRect(surface, false, IntRect(0, 0, 100, 100))); } }; diff --git a/Source/WebKit/chromium/tests/CCQuadCullerTest.cpp b/Source/WebKit/chromium/tests/CCQuadCullerTest.cpp index 624d24711..e1d9fb367 100644 --- a/Source/WebKit/chromium/tests/CCQuadCullerTest.cpp +++ b/Source/WebKit/chromium/tests/CCQuadCullerTest.cpp @@ -58,18 +58,22 @@ private: typedef CCLayerIterator<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, CCLayerIteratorActions::FrontToBack> CCLayerIteratorType; -static PassOwnPtr<CCTiledLayerImpl> makeLayer(CCTiledLayerImpl* parent, const WebTransformationMatrix& drawTransform, const IntRect& layerRect, float opacity, bool opaque, const IntRect& layerOpaqueRect, Vector<CCLayerImpl*>& surfaceLayerList) +static PassOwnPtr<CCTiledLayerImpl> makeLayer(CCTiledLayerImpl* parent, const WebTransformationMatrix& originTransform, const IntRect& layerRect, float opacity, bool opaque, const IntRect& layerOpaqueRect, Vector<CCLayerImpl*>& surfaceLayerList) { OwnPtr<CCTiledLayerImpl> layer = CCTiledLayerImpl::create(1); OwnPtr<CCLayerTilingData> tiler = CCLayerTilingData::create(IntSize(100, 100), CCLayerTilingData::NoBorderTexels); tiler->setBounds(layerRect.size()); layer->setTilingData(*tiler); layer->setSkipsDraw(false); + WebTransformationMatrix drawTransform = originTransform; + drawTransform.translate(0.5 * layerRect.width(), 0.5 * layerRect.height()); layer->setDrawTransform(drawTransform); - layer->setScreenSpaceTransform(drawTransform); + layer->setScreenSpaceTransform(originTransform); layer->setVisibleContentRect(layerRect); layer->setDrawOpacity(opacity); layer->setOpaque(opaque); + layer->setBounds(layerRect.size()); + layer->setContentBounds(layerRect.size()); int textureId = 1; for (int i = 0; i < tiler->numTilesX(); ++i) @@ -80,11 +84,10 @@ static PassOwnPtr<CCTiledLayerImpl> makeLayer(CCTiledLayerImpl* parent, const We if (!parent) { layer->createRenderSurface(); - layer->setTargetRenderSurface(layer->renderSurface()); surfaceLayerList.append(layer.get()); layer->renderSurface()->layerList().append(layer.get()); } else { - layer->setTargetRenderSurface(parent->targetRenderSurface()); + layer->setRenderTarget(parent->renderTarget()); parent->renderSurface()->layerList().append(layer.get()); } @@ -195,7 +198,7 @@ TEST(CCQuadCullerTest, verifyCullCenterTileOnly) appendQuads(quadList, sharedStateList, childLayer.get(), it, occlusionTracker); appendQuads(quadList, sharedStateList, rootLayer.get(), it, occlusionTracker); - EXPECT_EQ(quadList.size(), 12u); + ASSERT_EQ(quadList.size(), 12u); IntRect quadVisibleRect1 = quadList[5].get()->quadVisibleRect(); EXPECT_EQ(quadVisibleRect1.height(), 50); diff --git a/Source/WebKit/chromium/tests/CCSolidColorLayerImplTest.cpp b/Source/WebKit/chromium/tests/CCSolidColorLayerImplTest.cpp index 1bfc81d8c..f9a9292b7 100644 --- a/Source/WebKit/chromium/tests/CCSolidColorLayerImplTest.cpp +++ b/Source/WebKit/chromium/tests/CCSolidColorLayerImplTest.cpp @@ -50,6 +50,7 @@ TEST(CCSolidColorLayerImplTest, verifyTilingCompleteAndNoOverlap) OwnPtr<CCSolidColorLayerImpl> layer = CCSolidColorLayerImpl::create(1); layer->setVisibleContentRect(visibleContentRect); layer->setBounds(layerSize); + layer->setContentBounds(layerSize); OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState(); bool hadMissingTiles = false; @@ -71,6 +72,7 @@ TEST(CCSolidColorLayerImplTest, verifyCorrectBackgroundColorInQuad) OwnPtr<CCSolidColorLayerImpl> layer = CCSolidColorLayerImpl::create(1); layer->setVisibleContentRect(visibleContentRect); layer->setBounds(layerSize); + layer->setContentBounds(layerSize); layer->setBackgroundColor(testColor); OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState(); @@ -94,6 +96,7 @@ TEST(CCSolidColorLayerImplTest, verifyCorrectOpacityInQuad) OwnPtr<CCSolidColorLayerImpl> layer = CCSolidColorLayerImpl::create(1); layer->setVisibleContentRect(visibleContentRect); layer->setBounds(layerSize); + layer->setContentBounds(layerSize); layer->setDrawOpacity(opacity); OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState(); diff --git a/Source/WebKit/chromium/tests/CCTiledLayerImplTest.cpp b/Source/WebKit/chromium/tests/CCTiledLayerImplTest.cpp index 588c0ff08..00d38a7ec 100644 --- a/Source/WebKit/chromium/tests/CCTiledLayerImplTest.cpp +++ b/Source/WebKit/chromium/tests/CCTiledLayerImplTest.cpp @@ -50,6 +50,8 @@ static PassOwnPtr<CCTiledLayerImpl> createLayer(const IntSize& tileSize, const I layer->setSkipsDraw(false); layer->setVisibleContentRect(IntRect(IntPoint(), layerSize)); layer->setDrawOpacity(1); + layer->setBounds(layerSize); + layer->setContentBounds(layerSize); int textureId = 1; for (int i = 0; i < tiler->numTilesX(); ++i) diff --git a/Source/WebKit/chromium/tests/CCTiledLayerTestCommon.cpp b/Source/WebKit/chromium/tests/CCTiledLayerTestCommon.cpp index 2d1603e48..26ffd9079 100644 --- a/Source/WebKit/chromium/tests/CCTiledLayerTestCommon.cpp +++ b/Source/WebKit/chromium/tests/CCTiledLayerTestCommon.cpp @@ -125,18 +125,16 @@ void FakeTiledLayerChromium::setTexturePriorities(const CCPriorityCalculator& ca { // Ensure there is always a target render surface available. If none has been // set (the layer is an orphan for the test), then just set a surface on itself. - bool missingTargetRenderSurface = !targetRenderSurface(); + bool missingTargetRenderSurface = !renderTarget(); - if (missingTargetRenderSurface) { + if (missingTargetRenderSurface) createRenderSurface(); - setTargetRenderSurface(renderSurface()); - } TiledLayerChromium::setTexturePriorities(calculator); if (missingTargetRenderSurface) { clearRenderSurface(); - setTargetRenderSurface(0); + setRenderTarget(0); } } diff --git a/Source/WebKit/chromium/tests/DecimalTest.cpp b/Source/WebKit/chromium/tests/DecimalTest.cpp index 454dfea2c..8d4106260 100644 --- a/Source/WebKit/chromium/tests/DecimalTest.cpp +++ b/Source/WebKit/chromium/tests/DecimalTest.cpp @@ -89,7 +89,7 @@ protected: return Decimal::fromString(string); } - protected: String stepDown(const String& minimum, const String& maximum, const String& step, const String& valueString, int numberOfStepTimes) + protected: Decimal stepDown(const String& minimum, const String& maximum, const String& step, const String& valueString, int numberOfStepTimes) { DecimalStepRange stepRange(fromString(minimum), fromString(maximum), fromString(step)); Decimal value = fromString(valueString); @@ -97,10 +97,10 @@ protected: value -= stepRange.step; value = stepRange.clampValue(value); } - return value.toString(); + return value; } - protected: String stepUp(const String& minimum, const String& maximum, const String& step, const String& valueString, int numberOfStepTimes) + protected: Decimal stepUp(const String& minimum, const String& maximum, const String& step, const String& valueString, int numberOfStepTimes) { DecimalStepRange stepRange(fromString(minimum), fromString(maximum), fromString(step)); Decimal value = fromString(valueString); @@ -108,10 +108,18 @@ protected: value += stepRange.step; value = stepRange.clampValue(value); } - return value.toString(); + return value; } }; +// FIXME: We should use expectedSign without "Decimal::", however, g++ causes undefined references for DecimalTest::Positive and Negative. +#define EXPECT_DECIMAL_ENCODED_DATA_EQ(expectedCoefficient, expectedExponent, expectedSign, decimal) \ + EXPECT_EQ((expectedCoefficient), (decimal).value().coefficient()); \ + EXPECT_EQ((expectedExponent), (decimal).value().exponent()); \ + EXPECT_EQ(Decimal::expectedSign, (decimal).value().sign()); + +#define EXPECT_DECIMAL_STREQ(expected, decimal) EXPECT_STREQ((expected), (decimal).toString().ascii().data()) + TEST_F(DecimalTest, Abs) { EXPECT_EQ(encode(0, 0, Positive), encode(0, 0, Positive).abs()); @@ -231,9 +239,9 @@ TEST_F(DecimalTest, CeilingBigExponent) EXPECT_EQ(encode(1, 1000, Negative), encode(1, 1000, Negative).ceiling()); } -TEST_F(DecimalTest, DISABLED_CeilingSmallExponent) +TEST_F(DecimalTest, CeilingSmallExponent) { - EXPECT_EQ(encode(0, 0, Positive), encode(1, -1000, Positive).ceiling()); + EXPECT_EQ(encode(1, 0, Positive), encode(1, -1000, Positive).ceiling()); EXPECT_EQ(encode(0, 0, Negative), encode(1, -1000, Negative).ceiling()); } @@ -445,6 +453,28 @@ TEST_F(DecimalTest, CompareSpecialValues) EXPECT_TRUE(NaN >= NaN); } +TEST_F(DecimalTest, Constructor) +{ + EXPECT_DECIMAL_ENCODED_DATA_EQ(0u, 0, Positive, encode(0, 0, Positive)); + EXPECT_DECIMAL_ENCODED_DATA_EQ(0u, 0, Negative, encode(0, 0, Negative)); + EXPECT_DECIMAL_ENCODED_DATA_EQ(1u, 0, Positive, encode(1, 0, Positive)); + EXPECT_DECIMAL_ENCODED_DATA_EQ(1u, 0, Negative, encode(1, 0, Negative)); + EXPECT_DECIMAL_ENCODED_DATA_EQ(1u, 1022, Positive, encode(1, 1022, Positive)); + EXPECT_DECIMAL_ENCODED_DATA_EQ(1u, 1022, Negative, encode(1, 1022, Negative)); + EXPECT_DECIMAL_ENCODED_DATA_EQ(1u, 1023, Positive, encode(1, 1023, Positive)); + EXPECT_DECIMAL_ENCODED_DATA_EQ(1u, 1023, Negative, encode(1, 1023, Negative)); + EXPECT_TRUE(encode(1, 2000, Positive).isInfinity()); + EXPECT_TRUE(encode(1, 2000, Negative).isInfinity()); + EXPECT_DECIMAL_ENCODED_DATA_EQ(0u, 0, Positive, encode(1, -2000, Positive)); + EXPECT_DECIMAL_ENCODED_DATA_EQ(0u, 0, Negative, encode(1, -2000, Negative)); + EXPECT_DECIMAL_ENCODED_DATA_EQ(UINT64_C(99999999999999998), 0, Positive, encode(UINT64_C(99999999999999998), 0, Positive)); + EXPECT_DECIMAL_ENCODED_DATA_EQ(UINT64_C(99999999999999998), 0, Negative, encode(UINT64_C(99999999999999998), 0, Negative)); + EXPECT_DECIMAL_ENCODED_DATA_EQ(UINT64_C(99999999999999999), 0, Positive, encode(UINT64_C(99999999999999999), 0, Positive)); + EXPECT_DECIMAL_ENCODED_DATA_EQ(UINT64_C(99999999999999999), 0, Negative, encode(UINT64_C(99999999999999999), 0, Negative)); + EXPECT_DECIMAL_ENCODED_DATA_EQ(UINT64_C(10000000000000000), 1, Positive, encode(UINT64_C(100000000000000000), 0, Positive)); + EXPECT_DECIMAL_ENCODED_DATA_EQ(UINT64_C(10000000000000000), 1, Negative, encode(UINT64_C(100000000000000000), 0, Negative)); +} + TEST_F(DecimalTest, Division) { EXPECT_EQ(encode(0, 0, Positive), Decimal(0) / Decimal(1)); @@ -547,10 +577,10 @@ TEST_F(DecimalTest, FloorBigExponent) EXPECT_EQ(encode(1, 1000, Negative), encode(1, 1000, Negative).floor()); } -TEST_F(DecimalTest, DISABLED_FloorSmallExponent) +TEST_F(DecimalTest, FloorSmallExponent) { EXPECT_EQ(encode(0, 0, Positive), encode(1, -1000, Positive).floor()); - EXPECT_EQ(encode(0, 0, Negative), encode(1, -1000, Negative).floor()); + EXPECT_EQ(encode(1, 0, Negative), encode(1, -1000, Negative).floor()); } TEST_F(DecimalTest, FloorSpecialValues) @@ -840,29 +870,29 @@ TEST_F(DecimalTest, PredicatesSpecialValues) // LayoutTests/fast/forms/number/number-stepup-stepdown-from-renderer TEST_F(DecimalTest, RealWorldExampleNumberStepUpStepDownFromRenderer) { - EXPECT_EQ(String("10"), stepDown("0", "100", "10", "19", 1)); - EXPECT_EQ(String("90"), stepUp("0", "99", "10", "89", 1)); - EXPECT_EQ(String("1"), stepUp("0", "1", "0.33333333333333333", "0", 3)); // step=1/3 - EXPECT_EQ(String("0.01"), stepUp("0", "0.01", "0.0033333333333333333", "0", 3)); // step=1/300 - EXPECT_EQ(String("1"), stepUp("0", "1", "0.003921568627450980", "0", 255)); // step=1/255 - EXPECT_EQ(String("1"), stepUp("0", "1", "0.1", "0", 10)); + EXPECT_DECIMAL_STREQ("10", stepDown("0", "100", "10", "19", 1)); + EXPECT_DECIMAL_STREQ("90", stepUp("0", "99", "10", "89", 1)); + EXPECT_DECIMAL_STREQ("1", stepUp("0", "1", "0.33333333333333333", "0", 3)); // step=1/3 + EXPECT_DECIMAL_STREQ("0.01", stepUp("0", "0.01", "0.0033333333333333333", "0", 3)); // step=1/300 + EXPECT_DECIMAL_STREQ("1", stepUp("0", "1", "0.003921568627450980", "0", 255)); // step=1/255 + EXPECT_DECIMAL_STREQ("1", stepUp("0", "1", "0.1", "0", 10)); } TEST_F(DecimalTest, RealWorldExampleNumberStepUpStepDownFromRendererRounding) { - EXPECT_EQ(String("5.015"), stepUp("0", "100", "0.005", "5.005", 2)); - EXPECT_EQ(String("5.06"), stepUp("0", "100", "0.005", "5.005", 11)); - EXPECT_EQ(String("5.065"), stepUp("0", "100", "0.005", "5.005", 12)); + EXPECT_DECIMAL_STREQ("5.015", stepUp("0", "100", "0.005", "5.005", 2)); + EXPECT_DECIMAL_STREQ("5.06", stepUp("0", "100", "0.005", "5.005", 11)); + EXPECT_DECIMAL_STREQ("5.065", stepUp("0", "100", "0.005", "5.005", 12)); - EXPECT_EQ(String("5.015"), stepUp("4", "9", "0.005", "5.005", 2)); - EXPECT_EQ(String("5.06"), stepUp("4", "9", "0.005", "5.005", 11)); - EXPECT_EQ(String("5.065"), stepUp("4", "9", "0.005", "5.005", 12)); + EXPECT_DECIMAL_STREQ("5.015", stepUp("4", "9", "0.005", "5.005", 2)); + EXPECT_DECIMAL_STREQ("5.06", stepUp("4", "9", "0.005", "5.005", 11)); + EXPECT_DECIMAL_STREQ("5.065", stepUp("4", "9", "0.005", "5.005", 12)); } TEST_F(DecimalTest, RealWorldExampleRangeStepUpStepDown) { - EXPECT_EQ(String("1e+38"), stepUp("0", "1E38", "1", "1E38", 9)); - EXPECT_EQ(String("1e+38"), stepDown("0", "1E38", "1", "1E38", 9)); + EXPECT_DECIMAL_STREQ("1e+38", stepUp("0", "1E38", "1", "1E38", 9)); + EXPECT_DECIMAL_STREQ("1e+38", stepDown("0", "1E38", "1", "1E38", 9)); } TEST_F(DecimalTest, Remainder) @@ -1022,31 +1052,41 @@ TEST_F(DecimalTest, ToDoubleSpecialValues) TEST_F(DecimalTest, ToString) { - EXPECT_EQ(String("0"), Decimal::zero(Positive).toString()); - EXPECT_EQ(String("-0"), Decimal::zero(Negative).toString()); - EXPECT_EQ(String("1"), Decimal(1).toString()); - EXPECT_EQ(String("-1"), Decimal(-1).toString()); - EXPECT_EQ(String("1234567"), Decimal(1234567).toString()); - EXPECT_EQ(String("-1234567"), Decimal(-1234567).toString()); - EXPECT_EQ(String("0.5"), encode(5, -1, Positive).toString()); - EXPECT_EQ(String("-0.5"), encode(5, -1, Negative).toString()); - EXPECT_EQ(String("12.345"), encode(12345, -3, Positive).toString()); - EXPECT_EQ(String("-12.345"), encode(12345, -3, Negative).toString()); - EXPECT_EQ(String("0.12345"), encode(12345, -5, Positive).toString()); - EXPECT_EQ(String("-0.12345"), encode(12345, -5, Negative).toString()); - EXPECT_EQ(String("50"), encode(50, 0, Positive).toString()); - EXPECT_EQ(String("-50"), encode(50, 0, Negative).toString()); - EXPECT_EQ(String("5e+1"), encode(5, 1, Positive).toString()); - EXPECT_EQ(String("-5e+1"), encode(5, 1, Negative).toString()); - EXPECT_EQ(String("5.678e+103"), encode(5678, 100, Positive).toString()); - EXPECT_EQ(String("-5.678e+103"), encode(5678, 100, Negative).toString()); - EXPECT_EQ(String("5.678e-97"), encode(5678, -100, Positive).toString()); - EXPECT_EQ(String("-5.678e-97"), encode(5678, -100, Negative).toString()); + EXPECT_DECIMAL_STREQ("0", Decimal::zero(Positive)); + EXPECT_DECIMAL_STREQ("-0", Decimal::zero(Negative)); + EXPECT_DECIMAL_STREQ("1", Decimal(1)); + EXPECT_DECIMAL_STREQ("-1", Decimal(-1)); + EXPECT_DECIMAL_STREQ("1234567", Decimal(1234567)); + EXPECT_DECIMAL_STREQ("-1234567", Decimal(-1234567)); + EXPECT_DECIMAL_STREQ("0.5", encode(5, -1, Positive)); + EXPECT_DECIMAL_STREQ("-0.5", encode(5, -1, Negative)); + EXPECT_DECIMAL_STREQ("12.345", encode(12345, -3, Positive)); + EXPECT_DECIMAL_STREQ("-12.345", encode(12345, -3, Negative)); + EXPECT_DECIMAL_STREQ("0.12345", encode(12345, -5, Positive)); + EXPECT_DECIMAL_STREQ("-0.12345", encode(12345, -5, Negative)); + EXPECT_DECIMAL_STREQ("50", encode(50, 0, Positive)); + EXPECT_DECIMAL_STREQ("-50", encode(50, 0, Negative)); + EXPECT_DECIMAL_STREQ("5e+1", encode(5, 1, Positive)); + EXPECT_DECIMAL_STREQ("-5e+1", encode(5, 1, Negative)); + EXPECT_DECIMAL_STREQ("5.678e+103", encode(5678, 100, Positive)); + EXPECT_DECIMAL_STREQ("-5.678e+103", encode(5678, 100, Negative)); + EXPECT_DECIMAL_STREQ("5.678e-97", encode(5678, -100, Positive)); + EXPECT_DECIMAL_STREQ("-5.678e-97", encode(5678, -100, Negative)); + EXPECT_DECIMAL_STREQ("8639999913600001", encode(UINT64_C(8639999913600001), 0, Positive)); + EXPECT_DECIMAL_STREQ("9007199254740991", encode((static_cast<uint64_t>(1) << DBL_MANT_DIG) - 1, 0, Positive)); + EXPECT_DECIMAL_STREQ("99999999999999999", encode(UINT64_C(99999999999999999), 0, Positive)); + EXPECT_DECIMAL_STREQ("9.9999999999999999e+17", encode(UINT64_C(99999999999999999), 1, Positive)); + EXPECT_DECIMAL_STREQ("9.9999999999999999e+18", encode(UINT64_C(99999999999999999), 2, Positive)); + EXPECT_DECIMAL_STREQ("1e+16", encode(UINT64_C(99999999999999999), -1, Positive)); + EXPECT_DECIMAL_STREQ("1000000000000000", encode(UINT64_C(99999999999999999), -2, Positive)); + EXPECT_DECIMAL_STREQ("1", encode(UINT64_C(99999999999999999), -17, Positive)); + EXPECT_DECIMAL_STREQ("0.001", encode(UINT64_C(99999999999999999), -20, Positive)); + EXPECT_DECIMAL_STREQ("1e-83", encode(UINT64_C(99999999999999999), -100, Positive)); } TEST_F(DecimalTest, ToStringSpecialValues) { - EXPECT_EQ(String("Infinity"), Decimal::infinity(Positive).toString()); - EXPECT_EQ(String("-Infinity"), Decimal::infinity(Negative).toString()); - EXPECT_EQ(String("NaN"), Decimal::nan().toString()); + EXPECT_DECIMAL_STREQ("Infinity", Decimal::infinity(Positive)); + EXPECT_DECIMAL_STREQ("-Infinity", Decimal::infinity(Negative)); + EXPECT_DECIMAL_STREQ("NaN", Decimal::nan()); } diff --git a/Source/WebKit/chromium/tests/FrameTestHelpers.cpp b/Source/WebKit/chromium/tests/FrameTestHelpers.cpp index a2b1675c0..c3e8bf08d 100644 --- a/Source/WebKit/chromium/tests/FrameTestHelpers.cpp +++ b/Source/WebKit/chromium/tests/FrameTestHelpers.cpp @@ -80,6 +80,7 @@ WebView* createWebViewAndLoad(const std::string& url, bool enableJavascript, Web webViewClient = defaultWebViewClient(); WebView* webView = WebView::create(webViewClient); webView->settings()->setJavaScriptEnabled(enableJavascript); + webView->settings()->setDeviceSupportsMouse(false); webView->initializeMainFrame(webFrameClient); loadFrame(webView->mainFrame(), url); diff --git a/Source/WebKit/chromium/tests/IDBFakeBackingStore.h b/Source/WebKit/chromium/tests/IDBFakeBackingStore.h index ed894cb19..08405ce0a 100644 --- a/Source/WebKit/chromium/tests/IDBFakeBackingStore.h +++ b/Source/WebKit/chromium/tests/IDBFakeBackingStore.h @@ -48,7 +48,8 @@ public: virtual bool putObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const IDBKey&, const String& value, ObjectStoreRecordIdentifier*) OVERRIDE { return false; } virtual void clearObjectStore(int64_t databaseId, int64_t objectStoreId) OVERRIDE { } virtual void deleteObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const ObjectStoreRecordIdentifier*) OVERRIDE { } - virtual int64_t nextAutoIncrementNumber(int64_t databaseId, int64_t objectStoreId) OVERRIDE { return 0.0; } + virtual int64_t getKeyGeneratorCurrentNumber(int64_t databaseId, int64_t objectStoreId) OVERRIDE { return 0; } + virtual bool maybeUpdateKeyGeneratorCurrentNumber(int64_t databaseId, int64_t objectStoreId, int64_t newNumber, bool checkCurrent) OVERRIDE { return false; } virtual bool keyExistsInObjectStore(int64_t databaseId, int64_t objectStoreId, const IDBKey&, ObjectStoreRecordIdentifier* foundRecordIdentifier) OVERRIDE { return false; } virtual bool forEachObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, ObjectStoreRecordCallback&) OVERRIDE { return false; } diff --git a/Source/WebKit/chromium/tests/LayerChromiumTest.cpp b/Source/WebKit/chromium/tests/LayerChromiumTest.cpp index fdae37c6a..a794a2846 100644 --- a/Source/WebKit/chromium/tests/LayerChromiumTest.cpp +++ b/Source/WebKit/chromium/tests/LayerChromiumTest.cpp @@ -499,7 +499,7 @@ TEST_F(LayerChromiumTest, checkPropertyChangeCausesCorrectBehavior) EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setIsNonCompositedContent(true)); EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setDrawOpacity(0.5f)); EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setClipRect(IntRect(3, 3, 8, 8))); - EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setTargetRenderSurface(0)); + EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setRenderTarget(0)); EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setDrawTransform(WebTransformationMatrix())); EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setScreenSpaceTransform(WebTransformationMatrix())); EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setDrawableContentRect(IntRect(4, 5, 6, 7))); diff --git a/Source/WebKit/chromium/tests/OpenTypeVerticalDataTest.cpp b/Source/WebKit/chromium/tests/OpenTypeVerticalDataTest.cpp new file mode 100644 index 000000000..e05a20541 --- /dev/null +++ b/Source/WebKit/chromium/tests/OpenTypeVerticalDataTest.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2012 Koji Ishii <kojiishi@gmail.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(OPENTYPE_VERTICAL) + +#include "OpenTypeTypes.h" +#include "SharedBuffer.h" +#include <gtest/gtest.h> +#include <wtf/RefPtr.h> + +using namespace WebCore; + +namespace { + +struct TestTable : OpenType::TableBase { + OpenType::Fixed version; + OpenType::Int16 ascender; + + template <typename T> const T* validateOffset(const SharedBuffer& buffer, uint16_t offset) const + { + return TableBase::validateOffset<T>(buffer, offset); + } +}; + +TEST(OpenTypeVerticalDataTest, ValidateTableTest) +{ + RefPtr<SharedBuffer> buffer = SharedBuffer::create(sizeof(TestTable)); + const TestTable* table = OpenType::validateTable<TestTable>(buffer); + EXPECT_TRUE(table); + + buffer = SharedBuffer::create(sizeof(TestTable) - 1); + table = OpenType::validateTable<TestTable>(buffer); + EXPECT_FALSE(table); + + buffer = SharedBuffer::create(sizeof(TestTable) + 1); + table = OpenType::validateTable<TestTable>(buffer); + EXPECT_TRUE(table); +} + +TEST(OpenTypeVerticalDataTest, ValidateOffsetTest) +{ + RefPtr<SharedBuffer> buffer = SharedBuffer::create(sizeof(TestTable)); + const TestTable* table = OpenType::validateTable<TestTable>(buffer); + ASSERT_TRUE(table); + + // Test overflow + EXPECT_FALSE(table->validateOffset<uint8_t>(*buffer, -1)); + + // uint8_t is valid for all offsets + for (uint16_t offset = 0; offset < sizeof(TestTable); offset++) + EXPECT_TRUE(table->validateOffset<uint8_t>(*buffer, offset)); + EXPECT_FALSE(table->validateOffset<uint8_t>(*buffer, sizeof(TestTable))); + EXPECT_FALSE(table->validateOffset<uint8_t>(*buffer, sizeof(TestTable) + 1)); + + // For uint16_t, the last byte is invalid + for (uint16_t offset = 0; offset < sizeof(TestTable) - 1; offset++) + EXPECT_TRUE(table->validateOffset<uint16_t>(*buffer, offset)); + EXPECT_FALSE(table->validateOffset<uint16_t>(*buffer, sizeof(TestTable) - 1)); +} + +} // namespace + +#endif // ENABLE(OPENTYPE_VERTICAL) diff --git a/Source/WebKit/efl/ChangeLog b/Source/WebKit/efl/ChangeLog index 7c379dcee..7d313e348 100644 --- a/Source/WebKit/efl/ChangeLog +++ b/Source/WebKit/efl/ChangeLog @@ -1,3 +1,135 @@ +2012-07-17 Christophe Dumez <christophe.dumez@intel.com> + + [EFL] Replace 0 by NULL in public headers documentation + https://bugs.webkit.org/show_bug.cgi?id=91470 + + Reviewed by Dirk Pranke. + + Use NULL instead of 0 for pointer types in public + C headers. + + * ewk/ewk_contextmenu.h: + * ewk/ewk_cookies.h: + * ewk/ewk_frame.h: + * ewk/ewk_intent.h: + * ewk/ewk_intent_request.h: + * ewk/ewk_network.h: + * ewk/ewk_security_origin.h: + * ewk/ewk_settings.h: + * ewk/ewk_view.h: + * ewk/ewk_window_features.h: + +2012-07-17 Vivek Galatage <vivekgalatage@gmail.com> + + Web Inspector: refactor InspectorController::connectFrontend() to accept InspectorFrontendChannel. + https://bugs.webkit.org/show_bug.cgi?id=91196 + + Reviewed by Pavel Feldman. + + Refactoring InspectorClients. InspectorClient::openInspectorFrontend + now returning the InspectorFrontendChannel. + + * WebCoreSupport/InspectorClientEfl.cpp: + (WebCore::InspectorClientEfl::openInspectorFrontend): + * WebCoreSupport/InspectorClientEfl.h: + (InspectorClientEfl): + +2012-07-17 Ryuan Choi <ryuan.choi@samsung.com> + + [EFL] Move codes related to theme setting from Widget to RenderTheme + https://bugs.webkit.org/show_bug.cgi?id=89842 + + Reviewed by Kenneth Rohde Christiansen. + + * ewk/ewk_frame.cpp: + (ewk_frame_view_create_for_view): Removed codes which set theme in FrameView. + * ewk/ewk_view.cpp: + (ewk_view_theme_set): Called RenderThemeEfl::setThemePath instead of setting theme in FrameView. + +2012-07-16 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Add RegisterProtocolHandlerClient to the Modules/protocolhandler + https://bugs.webkit.org/show_bug.cgi?id=90940 + + Reviewed by Hajime Morita. + + As a step to let protocol handler be moved to the modules, RegisterProtocolHandlerClient needs + to be added to the Modules/protocolhandler. Because ChromeClient has some virtual functions for + protocol handlers, virtual functions should be moved to RegisterProtocolHandlerClient + + In order to support this, RegisterProtocolHandlerClientEfl class is added and ewk_view registers + RegisterProtocolHandlerClientEfl. In addition, existing concrete functions in ChromeClientEfl are moved + to RegisterProtocolHandlerClientEfl. + + * WebCoreSupport/ChromeClientEfl.cpp: + (WebCore): + * WebCoreSupport/ChromeClientEfl.h: + * WebCoreSupport/RegisterProtocolHandlerClientEfl.cpp: Added. + (WebCore): + (WebCore::customHandlerDataCreate): + (WebCore::customHandlerDataDelete): + (WebCore::RegisterProtocolHandlerClientEfl::RegisterProtocolHandlerClientEfl): + (WebCore::RegisterProtocolHandlerClientEfl::registerProtocolHandler): + (WebCore::RegisterProtocolHandlerClientEfl::isProtocolHandlerRegistered): + (WebCore::RegisterProtocolHandlerClientEfl::unregisterProtocolHandler): + * WebCoreSupport/RegisterProtocolHandlerClientEfl.h: Added. + (RegisterProtocolHandlerClientEfl): + (WebCore::RegisterProtocolHandlerClientEfl::~RegisterProtocolHandlerClientEfl): + * ewk/ewk_view.cpp: + (_ewk_view_priv_new): + +2012-07-16 Kihong Kwon <kihong.kwon@samsung.com> + + Remove setController from BatteryClient + https://bugs.webkit.org/show_bug.cgi?id=90944 + + Reviewed by Adam Barth. + + BatteryClient doesn't need to keep m_controller, + because BatteryController can be accessed using BatteryController::from(). + Remove m_controller and Add ewk view evas object to BatteryClientEfl. + And change all m_controller to BatteryController::from. + + * WebCoreSupport/BatteryClientEfl.cpp: + (BatteryClientEfl::BatteryClientEfl): + (BatteryClientEfl::didChangeBatteryStatus): + * WebCoreSupport/BatteryClientEfl.h: + (BatteryClientEfl): + * ewk/ewk_view.cpp: + (_ewk_view_priv_new): + +2012-07-15 Kihong Kwon <kihong.kwon@samsung.com> + + [EFL] Add a API for getting security origin string + https://bugs.webkit.org/show_bug.cgi?id=90936 + + Reviewed by Ryosuke Niwa. + + Support to change from Ewk_Security_Origin to string on the API level. + Add ewk_security_origin_string_get for getting security origin string. + + * ewk/ewk_security_origin.cpp: + (_Ewk_Security_Origin): + (ewk_security_origin_string_get): + (ewk_security_origin_free): + (ewk_security_origin_new): + * ewk/ewk_security_origin.h: + +2012-07-15 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + [EFL] Move files guarded by #ifdef to existing file list. + https://bugs.webkit.org/show_bug.cgi?id=91336 + + Reviewed by Ryosuke Niwa. + + Some EFL files are already guared by #ifdef. So, cmake files doesn't need to guard + them again. In addition, some files are missing #ifdef guard its header files. + + * WebCoreSupport/DeviceMotionClientEfl.h: + * WebCoreSupport/InspectorClientEfl.h: + * WebCoreSupport/NetworkInfoClientEfl.h: + * WebCoreSupport/VibrationClientEfl.h: + 2012-07-13 Kihong Kwon <kihong.kwon@samsung.com> [EFL] Add const to the parameter of getters in ewk_security_origin diff --git a/Source/WebKit/efl/WebCoreSupport/BatteryClientEfl.cpp b/Source/WebKit/efl/WebCoreSupport/BatteryClientEfl.cpp index e61da11f3..9de607af5 100644 --- a/Source/WebKit/efl/WebCoreSupport/BatteryClientEfl.cpp +++ b/Source/WebKit/efl/WebCoreSupport/BatteryClientEfl.cpp @@ -24,18 +24,14 @@ #if ENABLE(BATTERY_STATUS) #include "BatteryController.h" +#include "ewk_view_private.h" -BatteryClientEfl::BatteryClientEfl() - : m_controller(0) +BatteryClientEfl::BatteryClientEfl(Evas_Object* view) + : m_view(view) , m_provider(this) { } -void BatteryClientEfl::setController(WebCore::BatteryController* controller) -{ - m_controller = controller; -} - void BatteryClientEfl::startUpdating() { m_provider.startUpdating(); @@ -53,8 +49,7 @@ void BatteryClientEfl::batteryControllerDestroyed() void BatteryClientEfl::didChangeBatteryStatus(const AtomicString& eventType, PassRefPtr<WebCore::BatteryStatus> status) { - ASSERT(m_controller); - m_controller->didChangeBatteryStatus(eventType, status); + WebCore::BatteryController::from(EWKPrivate::corePage(m_view))->didChangeBatteryStatus(eventType, status); } #endif // ENABLE(BATTERY_STATUS) diff --git a/Source/WebKit/efl/WebCoreSupport/BatteryClientEfl.h b/Source/WebKit/efl/WebCoreSupport/BatteryClientEfl.h index 4ba11e84c..f633aadf1 100644 --- a/Source/WebKit/efl/WebCoreSupport/BatteryClientEfl.h +++ b/Source/WebKit/efl/WebCoreSupport/BatteryClientEfl.h @@ -35,11 +35,10 @@ class BatteryController; class BatteryClientEfl : public WebCore::BatteryClient, public WebCore::BatteryProviderEflClient { public: - BatteryClientEfl(); + explicit BatteryClientEfl(Evas_Object* view); virtual ~BatteryClientEfl() { } // BatteryClient interface. - virtual void setController(WebCore::BatteryController*); virtual void startUpdating(); virtual void stopUpdating(); virtual void batteryControllerDestroyed(); @@ -48,7 +47,7 @@ private: // BatteryProviderEflClient interface. virtual void didChangeBatteryStatus(const AtomicString& eventType, PassRefPtr<WebCore::BatteryStatus>); - WebCore::BatteryController* m_controller; + Evas_Object* m_view; WebCore::BatteryProviderEfl m_provider; }; diff --git a/Source/WebKit/efl/WebCoreSupport/ChromeClientEfl.cpp b/Source/WebKit/efl/WebCoreSupport/ChromeClientEfl.cpp index 703fa88ec..6a859053e 100644 --- a/Source/WebKit/efl/WebCoreSupport/ChromeClientEfl.cpp +++ b/Source/WebKit/efl/WebCoreSupport/ChromeClientEfl.cpp @@ -650,54 +650,4 @@ void ChromeClientEfl::exitFullScreenForElement(WebCore::Element*) } #endif -#if ENABLE(REGISTER_PROTOCOL_HANDLER) || ENABLE(CUSTOM_SCHEME_HANDLER) -static Ewk_Custom_Handler_Data* customHandlerDataCreate(Evas_Object* ewkView, const char* scheme, const char* baseURL, const char* url) -{ - Ewk_Custom_Handler_Data* data = new Ewk_Custom_Handler_Data; - data->ewkView = ewkView; - data->scheme = eina_stringshare_add(scheme); - data->base_url = eina_stringshare_add(baseURL); - data->url = eina_stringshare_add(url); - return data; -} - -static void customHandlerDataDelete(Ewk_Custom_Handler_Data* data) -{ - eina_stringshare_del(data->scheme); - eina_stringshare_del(data->base_url); - eina_stringshare_del(data->url); - delete data; -} - -#if ENABLE(REGISTER_PROTOCOL_HANDLER) -void ChromeClientEfl::registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title) -{ - Ewk_Custom_Handler_Data* data = customHandlerDataCreate(m_view, scheme.utf8().data(), baseURL.utf8().data(), url.utf8().data()); - data->title = eina_stringshare_add(title.utf8().data()); - ewk_custom_handler_register_protocol_handler(data); - eina_stringshare_del(data->title); - customHandlerDataDelete(data); -} -#endif - -#if ENABLE(CUSTOM_SCHEME_HANDLER) -ChromeClient::CustomHandlersState ChromeClientEfl::isProtocolHandlerRegistered(const String& scheme, const String& baseURL, const String& url) -{ - Ewk_Custom_Handler_Data* data = customHandlerDataCreate(m_view, scheme.utf8().data(), baseURL.utf8().data(), url.utf8().data()); - ChromeClient::CustomHandlersState result = static_cast<CustomHandlersState>(ewk_custom_handler_register_protocol_handler(data)); - customHandlerDataDelete(data); - - return result; -} - -void ChromeClientEfl::unregisterProtocolHandler(const String& scheme, const String& baseURL, const String& url) -{ - Ewk_Custom_Handler_Data* data = customHandlerDataCreate(m_view, scheme.utf8().data(), baseURL.utf8().data(), url.utf8().data()); - ewk_custom_handler_register_protocol_handler(data); - customHandlerDataDelete(data); -} -#endif - -#endif // ENABLE(REGISTER_PROTOCOL_HANDLER) || ENABLE(CUSTOM_SCHEME_HANDLER) - } diff --git a/Source/WebKit/efl/WebCoreSupport/ChromeClientEfl.h b/Source/WebKit/efl/WebCoreSupport/ChromeClientEfl.h index a5ce3149a..81b5dae63 100644 --- a/Source/WebKit/efl/WebCoreSupport/ChromeClientEfl.h +++ b/Source/WebKit/efl/WebCoreSupport/ChromeClientEfl.h @@ -181,15 +181,6 @@ public: virtual void numWheelEventHandlersChanged(unsigned) { } virtual void numTouchEventHandlersChanged(unsigned) { } -#if ENABLE(REGISTER_PROTOCOL_HANDLER) - virtual void registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title); -#endif - -#if ENABLE(CUSTOM_SCHEME_HANDLER) - virtual CustomHandlersState isProtocolHandlerRegistered(const String& scheme, const String& baseURL, const String& url); - virtual void unregisterProtocolHandler(const String& scheme, const String& baseURL, const String& url); -#endif - Evas_Object* m_view; KURL m_hoveredLinkURL; #if ENABLE(FULLSCREEN_API) diff --git a/Source/WebKit/efl/WebCoreSupport/DeviceMotionClientEfl.h b/Source/WebKit/efl/WebCoreSupport/DeviceMotionClientEfl.h index 2997f322e..103dbbdcf 100644 --- a/Source/WebKit/efl/WebCoreSupport/DeviceMotionClientEfl.h +++ b/Source/WebKit/efl/WebCoreSupport/DeviceMotionClientEfl.h @@ -20,6 +20,8 @@ #ifndef DeviceMotionClientEfl_h #define DeviceMotionClientEfl_h +#if ENABLE(DEVICE_ORIENTATION) + #include "DeviceMotionClient.h" #include "DeviceMotionData.h" @@ -42,4 +44,5 @@ private: } // namespece WebCore +#endif #endif // DeviceMotionClientEfl_h diff --git a/Source/WebKit/efl/WebCoreSupport/InspectorClientEfl.cpp b/Source/WebKit/efl/WebCoreSupport/InspectorClientEfl.cpp index a0f1aacfc..bdc96e18d 100644 --- a/Source/WebKit/efl/WebCoreSupport/InspectorClientEfl.cpp +++ b/Source/WebKit/efl/WebCoreSupport/InspectorClientEfl.cpp @@ -72,13 +72,13 @@ void InspectorClientEfl::inspectorDestroyed() delete this; } -void InspectorClientEfl::openInspectorFrontend(InspectorController*) +InspectorFrontendChannel* InspectorClientEfl::openInspectorFrontend(InspectorController*) { evas_object_smart_callback_call(m_inspectedView, "inspector,view,create", 0); Evas_Object* inspectorView = ewk_view_web_inspector_view_get(m_inspectedView); if (!inspectorView) - return; + return 0; m_inspectorView = inspectorView; @@ -90,6 +90,8 @@ void InspectorClientEfl::openInspectorFrontend(InspectorController*) InspectorController* controller = EWKPrivate::corePage(m_inspectorView)->inspectorController(); controller->setInspectorFrontendClient(frontendClient.release()); + + return this; } void InspectorClientEfl::closeInspectorFrontend() diff --git a/Source/WebKit/efl/WebCoreSupport/InspectorClientEfl.h b/Source/WebKit/efl/WebCoreSupport/InspectorClientEfl.h index 6b71c4dc5..18820c5a1 100644 --- a/Source/WebKit/efl/WebCoreSupport/InspectorClientEfl.h +++ b/Source/WebKit/efl/WebCoreSupport/InspectorClientEfl.h @@ -32,7 +32,10 @@ #ifndef InspectorClientEfl_h #define InspectorClientEfl_h +#if ENABLE(INSPECTOR) + #include "InspectorClient.h" +#include "InspectorFrontendChannel.h" #include "InspectorFrontendClientLocal.h" #include <Evas.h> #include <wtf/Forward.h> @@ -41,14 +44,14 @@ namespace WebCore { class InspectorFrontendClientEfl; class Page; -class InspectorClientEfl : public InspectorClient { +class InspectorClientEfl : public InspectorClient, public InspectorFrontendChannel { public: explicit InspectorClientEfl(Evas_Object*); ~InspectorClientEfl(); virtual void inspectorDestroyed(); - virtual void openInspectorFrontend(InspectorController*); + virtual InspectorFrontendChannel* openInspectorFrontend(InspectorController*); virtual void closeInspectorFrontend(); virtual void bringFrontendToFront(); @@ -95,4 +98,5 @@ private: }; } +#endif #endif // InspectorClientEfl_h diff --git a/Source/WebKit/efl/WebCoreSupport/NetworkInfoClientEfl.h b/Source/WebKit/efl/WebCoreSupport/NetworkInfoClientEfl.h index 838f34b04..20e8ab756 100644 --- a/Source/WebKit/efl/WebCoreSupport/NetworkInfoClientEfl.h +++ b/Source/WebKit/efl/WebCoreSupport/NetworkInfoClientEfl.h @@ -29,6 +29,8 @@ #ifndef NetworkInfoClientEfl_h #define NetworkInfoClientEfl_h +#if ENABLE(NETWORK_INFO) + #include "NetworkInfoClient.h" #include "NetworkInfoController.h" @@ -51,4 +53,5 @@ private: }; } +#endif #endif // NetworkInfoClientEfl_h diff --git a/Source/WebKit/efl/WebCoreSupport/RegisterProtocolHandlerClientEfl.cpp b/Source/WebKit/efl/WebCoreSupport/RegisterProtocolHandlerClientEfl.cpp new file mode 100644 index 000000000..5127e72bf --- /dev/null +++ b/Source/WebKit/efl/WebCoreSupport/RegisterProtocolHandlerClientEfl.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "RegisterProtocolHandlerClientEfl.h" + +#if ENABLE(REGISTER_PROTOCOL_HANDLER) || ENABLE(CUSTOM_SCHEME_HANDLER) + +#include "ewk_custom_handler_private.h" +#include <wtf/text/CString.h> + +namespace WebCore { + +static Ewk_Custom_Handler_Data* customHandlerDataCreate(Evas_Object* ewkView, const char* scheme, const char* baseURL, const char* url) +{ + Ewk_Custom_Handler_Data* data = new Ewk_Custom_Handler_Data; + data->ewkView = ewkView; + data->scheme = eina_stringshare_add(scheme); + data->base_url = eina_stringshare_add(baseURL); + data->url = eina_stringshare_add(url); + return data; +} + +static void customHandlerDataDelete(Ewk_Custom_Handler_Data* data) +{ + eina_stringshare_del(data->scheme); + eina_stringshare_del(data->base_url); + eina_stringshare_del(data->url); + delete data; +} + +RegisterProtocolHandlerClientEfl::RegisterProtocolHandlerClientEfl(Evas_Object* view) + : m_view(view) +{ +} + +#if ENABLE(REGISTER_PROTOCOL_HANDLER) +void RegisterProtocolHandlerClientEfl::registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title) +{ + Ewk_Custom_Handler_Data* data = customHandlerDataCreate(m_view, scheme.utf8().data(), baseURL.utf8().data(), url.utf8().data()); + data->title = eina_stringshare_add(title.utf8().data()); + ewk_custom_handler_register_protocol_handler(data); + eina_stringshare_del(data->title); + customHandlerDataDelete(data); +} +#endif + +#if ENABLE(CUSTOM_SCHEME_HANDLER) +RegisterProtocolHandlerClient::CustomHandlersState RegisterProtocolHandlerClientEfl::isProtocolHandlerRegistered(const String& scheme, const String& baseURL, const String& url) +{ + Ewk_Custom_Handler_Data* data = customHandlerDataCreate(m_view, scheme.utf8().data(), baseURL.utf8().data(), url.utf8().data()); + RegisterProtocolHandlerClient::CustomHandlersState result = static_cast<CustomHandlersState>(ewk_custom_handler_register_protocol_handler(data)); + customHandlerDataDelete(data); + + return result; +} + +void RegisterProtocolHandlerClientEfl::unregisterProtocolHandler(const String& scheme, const String& baseURL, const String& url) +{ + Ewk_Custom_Handler_Data* data = customHandlerDataCreate(m_view, scheme.utf8().data(), baseURL.utf8().data(), url.utf8().data()); + ewk_custom_handler_register_protocol_handler(data); + customHandlerDataDelete(data); +} +#endif + +#endif // ENABLE(REGISTER_PROTOCOL_HANDLER) || ENABLE(CUSTOM_SCHEME_HANDLER) +} diff --git a/Source/WebKit/efl/WebCoreSupport/RegisterProtocolHandlerClientEfl.h b/Source/WebKit/efl/WebCoreSupport/RegisterProtocolHandlerClientEfl.h new file mode 100644 index 000000000..f83723f4d --- /dev/null +++ b/Source/WebKit/efl/WebCoreSupport/RegisterProtocolHandlerClientEfl.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef RegisterProtocolHandlerClientEfl_h +#define RegisterProtocolHandlerClientEfl_h + +#if ENABLE(REGISTER_PROTOCOL_HANDLER) || ENABLE(CUSTOM_SCHEME_HANDLER) +#include "RegisterProtocolHandlerClient.h" + +namespace WebCore { +class RegisterProtocolHandlerClientEfl : public WebCore::RegisterProtocolHandlerClient { +public: + explicit RegisterProtocolHandlerClientEfl(Evas_Object* view); + ~RegisterProtocolHandlerClientEfl() { } + +#if ENABLE(REGISTER_PROTOCOL_HANDLER) + virtual void registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title); +#endif + +#if ENABLE(CUSTOM_SCHEME_HANDLER) + virtual CustomHandlersState isProtocolHandlerRegistered(const String& scheme, const String& baseURL, const String& url); + virtual void unregisterProtocolHandler(const String& scheme, const String& baseURL, const String& url); +#endif + +private: + Evas_Object* m_view; +}; +} + +#endif +#endif // RegisterProtocolHandlerClientEfl_h diff --git a/Source/WebKit/efl/WebCoreSupport/VibrationClientEfl.h b/Source/WebKit/efl/WebCoreSupport/VibrationClientEfl.h index 7d2f8fd8f..d342fdcdb 100644 --- a/Source/WebKit/efl/WebCoreSupport/VibrationClientEfl.h +++ b/Source/WebKit/efl/WebCoreSupport/VibrationClientEfl.h @@ -20,6 +20,8 @@ #ifndef VibrationClientEfl_h #define VibrationClientEfl_h +#if ENABLE(VIBRATION) + #include "VibrationClient.h" #include <Evas.h> @@ -41,5 +43,6 @@ private: } // namespace WebCore +#endif #endif // VibrationClientEfl_h diff --git a/Source/WebKit/efl/ewk/ewk_contextmenu.h b/Source/WebKit/efl/ewk/ewk_contextmenu.h index 2ed473898..af6d4a8b7 100644 --- a/Source/WebKit/efl/ewk/ewk_contextmenu.h +++ b/Source/WebKit/efl/ewk/ewk_contextmenu.h @@ -163,7 +163,7 @@ EAPI void ewk_context_menu_ref(Ewk_Context_Menu *menu); /** * Decreases the reference count of the given object, possibly freeing it. * - * When the reference count it's reached 0, the menu with all items are freed. + * When the reference count reaches 0, the menu with all its items are freed. * * @param menu the context menu object to decrease the reference count */ @@ -183,7 +183,7 @@ EAPI Eina_Bool ewk_context_menu_destroy(Ewk_Context_Menu *menu * Gets the list of items. * * @param o the context menu object to get list of the items - * @return the list of the items on success or @c 0 on failure + * @return the list of the items on success or @c NULL on failure */ EAPI const Eina_List *ewk_context_menu_item_list_get(const Ewk_Context_Menu *o); @@ -196,7 +196,7 @@ EAPI const Eina_List *ewk_context_menu_item_list_get(const Ewk_Contex * @param title specifies a title of the item * @param checked @c EINA_TRUE if the item should be toggled or @c EINA_FALSE if not * @param enabled @c EINA_TRUE to enable the item or @c EINA_FALSE to disable - * @return the pointer to the new item on success or @c 0 on failure + * @return the pointer to the new item on success or @c NULL on failure * * @note The return value @b should @b be freed after use. */ @@ -267,7 +267,7 @@ EAPI Eina_Bool ewk_context_menu_item_action_set(Ewk_Context_Me * Gets a title of the item. * * @param o the item to get the title - * @return a title of the item on success, or @c 0 on failure + * @return a title of the item on success, or @c NULL on failure * * @see ewk_context_menu_item_title_set */ @@ -278,7 +278,7 @@ EAPI const char *ewk_context_menu_item_title_get(const Ewk_Conte * * @param o the item to set the title * @param title a new title for the item object - * @return a new title of the item on success or @c 0 on failure + * @return a new title of the item on success or @c NULL on failure * * @see ewk_context_menu_item_title_get */ diff --git a/Source/WebKit/efl/ewk/ewk_cookies.h b/Source/WebKit/efl/ewk/ewk_cookies.h index 2af57a0eb..939ed3da1 100644 --- a/Source/WebKit/efl/ewk/ewk_cookies.h +++ b/Source/WebKit/efl/ewk/ewk_cookies.h @@ -50,7 +50,7 @@ struct _Ewk_Cookie { char *value; /// the "domain" attribute, or else the hostname that the cookie came from char *domain; - /// the "path" attribute, or @c 0 + /// the "path" attribute, or @c NULL char *path; /// the cookie expiration time, or @c 0 for a session cookie time_t expires; @@ -83,7 +83,7 @@ typedef enum _Ewk_Cookie_Policy Ewk_Cookie_Policy; /** * Sets the path where the cookies are going to be stored. * - * @param filename path to the cookies.txt file, use @c 0 for keep + * @param filename path to the cookies.txt file, use @c NULL for keep * cookies just in memory. * * @return @c EINA_FALSE if it wasn't possible to create the cookie jar, diff --git a/Source/WebKit/efl/ewk/ewk_frame.cpp b/Source/WebKit/efl/ewk/ewk_frame.cpp index 67a9bc82c..6a4b1a3f2 100644 --- a/Source/WebKit/efl/ewk/ewk_frame.cpp +++ b/Source/WebKit/efl/ewk/ewk_frame.cpp @@ -1654,8 +1654,6 @@ void ewk_frame_view_create_for_view(Evas_Object* ewkFrame, Evas_Object* view) if (!smartData->frame->view()) return; - const char* theme = ewk_view_theme_get(view); - smartData->frame->view()->setEdjeTheme(theme); smartData->frame->view()->setEvasObject(ewkFrame); ewk_frame_mixed_content_displayed_set(ewkFrame, false); diff --git a/Source/WebKit/efl/ewk/ewk_frame.h b/Source/WebKit/efl/ewk/ewk_frame.h index 987a4b069..4498a4363 100644 --- a/Source/WebKit/efl/ewk/ewk_frame.h +++ b/Source/WebKit/efl/ewk/ewk_frame.h @@ -293,7 +293,7 @@ typedef enum { * * @param o frame object to get view object * - * @return view object or @c 0 on failure + * @return view object or @c NULL on failure */ EAPI Evas_Object *ewk_frame_view_get(const Evas_Object *o); @@ -321,7 +321,7 @@ EAPI Ewk_Security_Origin *ewk_frame_security_origin_get(const Evas_Object *o); * * @param o frame object to create the iterator * - * @return a newly allocated iterator on sucess, or @c 0 if not possible to + * @return a newly allocated iterator on sucess, or @c NULL if not possible to * create the iterator */ EAPI Eina_Iterator *ewk_frame_children_iterator_new(Evas_Object *o); @@ -343,7 +343,7 @@ EAPI Eina_Iterator *ewk_frame_children_iterator_new(Evas_Object *o); * @param o frame object to find a child frame * @param name child frame name * - * @return child frame of the given frame, or @c 0 if the the child wasn't found + * @return child frame of the given frame, or @c NULL if the the child wasn't found */ EAPI Evas_Object *ewk_frame_child_find(Evas_Object *o, const char *name); @@ -365,7 +365,7 @@ EAPI Eina_Bool ewk_frame_uri_set(Evas_Object *o, const char *uri); * * @param o frame object to get uri * - * @return frame uri on success or @c 0 on failure + * @return frame uri on success or @c NULL on failure */ EAPI const char *ewk_frame_uri_get(const Evas_Object *o); @@ -377,7 +377,7 @@ EAPI const char *ewk_frame_uri_get(const Evas_Object *o); * * @param o frame object to get title * - * @return frame title on success or @c 0 on failure + * @return frame title on success or @c NULL on failure */ EAPI const Ewk_Text_With_Direction *ewk_frame_title_get(const Evas_Object *o); @@ -389,7 +389,7 @@ EAPI const Ewk_Text_With_Direction *ewk_frame_title_get(const Evas_Object *o); * * @param o frame object to get name * - * @return frame name on success or @c 0 on failure + * @return frame name on success or @c NULL on failure */ EAPI const char *ewk_frame_name_get(const Evas_Object *o); @@ -397,8 +397,8 @@ EAPI const char *ewk_frame_name_get(const Evas_Object *o); * Gets last known contents size. * * @param o frame object to get contents size - * @param w pointer to store contents size width, may be @c 0 - * @param h pointer to store contents size height, may be @c 0 + * @param w pointer to store contents size width, may be @c NULL + * @param h pointer to store contents size height, may be @c NULL * * @return @c EINA_TRUE on success or @c EINA_FALSE on failure and * @a w and @a h will be zeroed @@ -412,9 +412,9 @@ EAPI Eina_Bool ewk_frame_contents_size_get(const Evas_Object *o, Evas_Coord * * @param contents what to load into frame * @param contents_size size of @a contents (in bytes), * if @c 0 is given, length of @a contents is used - * @param mime_type type of @a contents data, if @c 0 is given "text/html" is assumed - * @param encoding encoding for @a contents data, if @c 0 is given "UTF-8" is assumed - * @param base_uri base uri to use for relative resources, may be @c 0, + * @param mime_type type of @a contents data, if @c NULL is given "text/html" is assumed + * @param encoding encoding for @a contents data, if @c NULL is given "UTF-8" is assumed + * @param base_uri base uri to use for relative resources, may be @c NULL, * if provided @b must be an absolute uri * * @return @c EINA_TRUE on successful request, @c EINA_FALSE on errors @@ -429,15 +429,15 @@ EAPI Eina_Bool ewk_frame_contents_set(Evas_Object *o, const char *contents, s * difference is that back-forward navigation list is not changed. * * @param o frame object to load alternative content - * @param contents what to load into frame, must @b not be @c 0 + * @param contents what to load into frame, must @b not be @c NULL * @param contents_size size of @a contents (in bytes), * if @c 0 is given, length of @a contents is used - * @param mime_type type of @a contents data, if @c 0 is given "text/html" is assumed - * @param encoding encoding used for @a contents data, if @c 0 is given "UTF-8" is assumed - * @param base_uri base URI to use for relative resources, may be @c 0, + * @param mime_type type of @a contents data, if @c NULL is given "text/html" is assumed + * @param encoding encoding used for @a contents data, if @c NULL is given "UTF-8" is assumed + * @param base_uri base URI to use for relative resources, may be @c NULL, * if provided must be an absolute uri * @param unreachable_uri the URI that failed to load and is getting the - * alternative representation, must @b not be @c 0 + * alternative representation, must @b not be @c NULL * * @return @c EINA_TRUE on successful request, @c EINA_FALSE on errors */ @@ -451,7 +451,7 @@ EAPI Eina_Bool ewk_frame_contents_alternate_set(Evas_Object *o, const char *c * @param o frame object to execute script * @param script Java Script to execute * - * @return newly allocated string for result or @c 0 if the result cannot be converted to string or failure + * @return newly allocated string for result or @c NULL if the result cannot be converted to string or failure */ EAPI char *ewk_frame_script_execute(Evas_Object *o, const char *script); @@ -481,7 +481,7 @@ EAPI Eina_Bool ewk_frame_editable_set(Evas_Object *o, Eina_Bool editable); * * @param o the frame object to get selected text * - * @return a newly allocated string or @c 0 if nothing is selected or on failure + * @return a newly allocated string or @c NULL if nothing is selected or on failure */ EAPI char *ewk_frame_selection_get(const Evas_Object *o); @@ -545,8 +545,8 @@ EAPI Eina_Bool ewk_frame_text_matches_highlight_get(const Evas_Object *o); * * @param o frame object where matches are marked * @param n index of element - * @param x the pointer to store the horizontal position of @a n matched text, may be @c 0 - * @param y the pointer to store the vertical position of @a n matched text, may be @c 0 + * @param x the pointer to store the horizontal position of @a n matched text, may be @c NULL + * @param y the pointer to store the vertical position of @a n matched text, may be @c NULL * * @return @c EINA_TRUE on success, @c EINA_FALSE when no matches were found or * @a n is bigger than search results or on failure @@ -710,7 +710,7 @@ EAPI void ewk_frame_hit_test_free(Ewk_Hit_Test *hit_test); * @param x the horizontal position to query * @param y the vertical position to query * - * @return a newly allocated hit test on success, @c 0 otherwise + * @return a newly allocated hit test on success, @c NULL otherwise */ EAPI Ewk_Hit_Test *ewk_frame_hit_test_new(const Evas_Object *o, int x, int y); @@ -758,9 +758,9 @@ EAPI Eina_Bool ewk_frame_scroll_set(Evas_Object *o, int x, int y); * * @param o frame object to get scroll size * @param w the pointer to store the horizontal size that is possible to scroll, - * may be @c 0 + * may be @c NULL * @param h the pointer to store the vertical size that is possible to scroll, - * may be @c 0 + * may be @c NULL * * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise and * values are zeroed @@ -771,8 +771,8 @@ EAPI Eina_Bool ewk_frame_scroll_size_get(const Evas_Object *o, int *w, int *h * Gets the current scroll position of given frame. * * @param o frame object to get the current scroll position - * @param x the pointer to store the horizontal position, may be @c 0 - * @param y the pointer to store the vertical position. may be @c 0 + * @param x the pointer to store the horizontal position, may be @c NULL + * @param y the pointer to store the vertical position. may be @c NULL * * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise and * values are zeroed. @@ -784,10 +784,10 @@ EAPI Eina_Bool ewk_frame_scroll_pos_get(const Evas_Object *o, int *x, int *y) * * @param o frame object to query visible content geometry * @param include_scrollbars whenever to include scrollbars size - * @param x the pointer to store the horizontal position, may be @c 0 - * @param y the pointer to store the vertical position, may be @c 0 - * @param w the pointer to store width, may be @c 0 - * @param h the pointer to store height, may be @c 0 + * @param x the pointer to store the horizontal position, may be @c NULL + * @param y the pointer to store the vertical position, may be @c NULL + * @param w the pointer to store width, may be @c NULL + * @param h the pointer to store height, may be @c NULL * * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise and * values are zeroed @@ -842,10 +842,10 @@ EAPI Eina_Bool ewk_frame_feed_focus_out(Evas_Object *o); * document. * * @param o frame object containing the focused element - * @param x pointer where to store the X value of the geometry, may be @c 0 - * @param x pointer where to store the Y value of the geometry, may be @c 0 - * @param x pointer where to store width of the geometry, may be @c 0 - * @param x pointer where to store height of the geometry, may be @c 0 + * @param x pointer where to store the X value of the geometry, may be @c NULL + * @param x pointer where to store the Y value of the geometry, may be @c NULL + * @param x pointer where to store width of the geometry, may be @c NULL + * @param x pointer where to store height of the geometry, may be @c NULL * * @return @c EINA_TRUE if the frame contains the currently focused element and * its geometry was correctly fetched, @c EINA_FALSE in any other case @@ -939,7 +939,7 @@ EAPI Ewk_Text_Selection_Type ewk_frame_text_selection_type_get(const Evas_Object * * @param o frame smart object to get the frame source * @param frame_source a pointer to store the source of frame, - * must @b not be @c 0, this value @b should be freed after use + * must @b not be @c NULL, this value @b should be freed after use * * @return @c length of @a frame_source on success, or @c -1 on failure * @@ -955,7 +955,7 @@ EAPI ssize_t ewk_frame_source_get(const Evas_Object *o, char **frame_source); * replace them to the local paths. Values are not duplicated and they are decoded. * * @param o frame smart object to get the resources list - * @return @c Eina_List with location of resources on success, or @c 0 on failure, + * @return @c Eina_List with location of resources on success, or @c NULL on failure, * the Eina_List should be freed after use * * @see ewk_frame_source_get() @@ -971,7 +971,7 @@ EAPI Eina_List *ewk_frame_resources_location_get(const Evas_Object *o); * @param ewkFrame Frame object whose contents to retrieve. * * @return A newly allocated string (which must be freed by the caller with @c free()) - * or @c 0 in case of failure. + * or @c NULL in case of failure. */ EAPI char *ewk_frame_plain_text_get(const Evas_Object *o); diff --git a/Source/WebKit/efl/ewk/ewk_intent.h b/Source/WebKit/efl/ewk/ewk_intent.h index 143deaa0b..f49a76dc4 100644 --- a/Source/WebKit/efl/ewk/ewk_intent.h +++ b/Source/WebKit/efl/ewk/ewk_intent.h @@ -76,7 +76,7 @@ EAPI const char *ewk_intent_service_get(const Ewk_Intent *intent); * * @param intent intent item to query. * - * @return @c Eina_List with suggested service URLs on success, or @c 0 on failure, + * @return @c Eina_List with suggested service URLs on success, or @c NULL on failure, * the Eina_List and its items should be freed after use. Use free() to free the * items. */ @@ -97,7 +97,7 @@ EAPI char *ewk_intent_extra_get(const Ewk_Intent *intent, const char *key); * * @param intent intent item to query. * - * @return @c Eina_List with names of extra metadata on success, or @c 0 on failure, + * @return @c Eina_List with names of extra metadata on success, or @c NULL on failure, * the Eina_List and its items should be freed after use. Use free() to free the * items. */ diff --git a/Source/WebKit/efl/ewk/ewk_intent_request.h b/Source/WebKit/efl/ewk/ewk_intent_request.h index 22c71d6b0..29e8d32c3 100644 --- a/Source/WebKit/efl/ewk/ewk_intent_request.h +++ b/Source/WebKit/efl/ewk/ewk_intent_request.h @@ -41,7 +41,7 @@ EAPI void ewk_intent_request_ref(Ewk_Intent_Request *request); /** * Decreases the reference count of the given object, possibly freeing it. * - * When the reference count it's reached 0, the intent request is freed. + * When the reference count reaches 0, the intent request is freed. * * @param request the intent request object to decrease the reference count */ diff --git a/Source/WebKit/efl/ewk/ewk_network.h b/Source/WebKit/efl/ewk/ewk_network.h index dbec81584..d226f23fd 100644 --- a/Source/WebKit/efl/ewk/ewk_network.h +++ b/Source/WebKit/efl/ewk/ewk_network.h @@ -49,7 +49,7 @@ EAPI void ewk_network_proxy_uri_set(const char *proxy); * * The returned string should be freed by eina_stringshare_del() after use. * - * @return current proxy URI or @c 0 if it's not set + * @return current proxy URI or @c NULL if it's not set * * @note If the libsoup backend is being used, this function has effect on * the @b default SoupSession, returned by ewk_network_default_soup_session_get(). diff --git a/Source/WebKit/efl/ewk/ewk_security_origin.cpp b/Source/WebKit/efl/ewk/ewk_security_origin.cpp index 076158663..8b87bc3bf 100644 --- a/Source/WebKit/efl/ewk/ewk_security_origin.cpp +++ b/Source/WebKit/efl/ewk/ewk_security_origin.cpp @@ -37,6 +37,7 @@ struct _Ewk_Security_Origin { RefPtr<WebCore::SecurityOrigin> securityOrigin; const char* protocol; const char* host; + const char* originString; }; const char* ewk_security_origin_protocol_get(const Ewk_Security_Origin* origin) @@ -51,6 +52,12 @@ const char* ewk_security_origin_host_get(const Ewk_Security_Origin* origin) return origin->host; } +const char* ewk_security_origin_string_get(const Ewk_Security_Origin* origin) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(origin, 0); + return origin->originString; +} + uint32_t ewk_security_origin_port_get(const Ewk_Security_Origin* origin) { return origin->securityOrigin->port(); @@ -115,6 +122,7 @@ void ewk_security_origin_free(Ewk_Security_Origin* origin) origin->securityOrigin = 0; eina_stringshare_del(origin->host); eina_stringshare_del(origin->protocol); + eina_stringshare_del(origin->originString); delete origin; } @@ -140,6 +148,7 @@ Ewk_Security_Origin* ewk_security_origin_new(WebCore::SecurityOrigin* coreOrigin origin->securityOrigin = coreOrigin; origin->protocol = eina_stringshare_add(coreOrigin->protocol().utf8().data()); origin->host = eina_stringshare_add(coreOrigin->host().utf8().data()); + origin->originString = eina_stringshare_add(origin->securityOrigin->toString().utf8().data()); return origin; } diff --git a/Source/WebKit/efl/ewk/ewk_security_origin.h b/Source/WebKit/efl/ewk/ewk_security_origin.h index 2d9ea4675..0fddcc0ff 100644 --- a/Source/WebKit/efl/ewk/ewk_security_origin.h +++ b/Source/WebKit/efl/ewk/ewk_security_origin.h @@ -49,7 +49,7 @@ typedef struct _Ewk_Security_Origin Ewk_Security_Origin; * It returns a internal string which should not * be modified. The string is guaranteed to be stringshared. * - * @return the protocol scheme or @c 0 if there is not a protocol scheme + * @return the protocol scheme or @c NULL if there is not a protocol scheme */ EAPI const char *ewk_security_origin_protocol_get(const Ewk_Security_Origin *o); @@ -61,11 +61,22 @@ EAPI const char *ewk_security_origin_protocol_get(const Ewk_Security_Or * * @param o security origin object * - * @return the host domain or @c 0 if there is not a host scheme + * @return the host domain or @c NULL if there is not a host scheme */ EAPI const char *ewk_security_origin_host_get(const Ewk_Security_Origin *o); /** + * Convert this Ewk_Security_Origin into a string. + * The string representation of a security origin is similar to a URL, except it lacks a path component. + * The string representation does not encode the value of the security origin's domain property. + * + * @param o security origin object + * + * @return the string representation of security origin or @c NULL if there is not a proper security origin scheme + */ +EAPI const char *ewk_security_origin_string_get(const Ewk_Security_Origin *o); + +/** * Returns the port of the security origin. * * @param o security origin object @@ -131,7 +142,7 @@ EAPI void ewk_security_origin_application_cache_clear(const Ewk_ * use ewk_web_database_list_free() as convenience. * * This function won't work if Web SQL Database was not enabled when - * building WebKit and will just return 0. + * building WebKit and will just return @c NULL. * * @param o security origin object * @@ -158,7 +169,6 @@ EAPI void ewk_security_origin_free(Ewk_Security_Origin *o); */ EAPI Ewk_Security_Origin *ewk_security_origin_new_from_string(const char *url); - #ifdef __cplusplus } #endif diff --git a/Source/WebKit/efl/ewk/ewk_settings.h b/Source/WebKit/efl/ewk/ewk_settings.h index 2bd7cc0a2..fb79279f0 100644 --- a/Source/WebKit/efl/ewk/ewk_settings.h +++ b/Source/WebKit/efl/ewk/ewk_settings.h @@ -119,7 +119,7 @@ EAPI void ewk_settings_local_storage_database_origin_clear(const char *url); * save yourself some cpu cycles and use eina_stringshare_ref() * instead of eina_stringshare_add() or strdup(). * - * @return database path or @c 0 if none or web database is not supported + * @return database path or @c NULL if none or web database is not supported */ EAPI const char *ewk_settings_web_database_path_get(void); @@ -130,7 +130,7 @@ EAPI const char *ewk_settings_web_database_path_get(void); * database is already open, this function returns @c EINA_FALSE. * * @param directory where to store icon database, must be - * write-able, if @c 0 is given, then database is closed + * write-able, if @c NULL is given, then database is closed * * @return @c EINA_TRUE on success, @c EINA_FALSE on errors */ @@ -143,7 +143,7 @@ EAPI Eina_Bool ewk_settings_icon_database_path_set(const char *path); * save yourself some cpu cycles and use eina_stringshare_ref() * instead of eina_stringshare_add() or strdup(). * - * @return database path or @c 0 if none is set + * @return database path or @c NULL if none is set */ EAPI const char *ewk_settings_icon_database_path_get(void); @@ -166,7 +166,7 @@ EAPI Eina_Bool ewk_settings_icon_database_clear(void); * * @param url which url to query icon * - * @return cairo surface if any, or @c 0 on failure + * @return cairo surface if any, or @c NULL on failure */ EAPI cairo_surface_t *ewk_settings_icon_database_icon_surface_get(const char *url); @@ -186,7 +186,7 @@ EAPI cairo_surface_t *ewk_settings_icon_database_icon_surface_get(const char *ur * @param url which url to query icon * @param canvas evas instance where to add resulting object * - * @return newly allocated Evas_Object instance or @c 0 on + * @return newly allocated Evas_Object instance or @c NULL on * errors. Delete the object with evas_object_del(). */ EAPI Evas_Object *ewk_settings_icon_database_icon_object_get(const char *url, Evas *canvas); diff --git a/Source/WebKit/efl/ewk/ewk_view.cpp b/Source/WebKit/efl/ewk/ewk_view.cpp index 1ae83fc9d..f0859dfee 100644 --- a/Source/WebKit/efl/ewk/ewk_view.cpp +++ b/Source/WebKit/efl/ewk/ewk_view.cpp @@ -53,7 +53,7 @@ #include "PopupMenuClient.h" #include "ProgressTracker.h" #include "RefPtrCairo.h" -#include "RenderTheme.h" +#include "RenderThemeEfl.h" #include "ResourceHandle.h" #include "Settings.h" #include "c_instance.h" @@ -103,6 +103,10 @@ #include "ColorChooserClient.h" #endif +#if ENABLE(REGISTER_PROTOCOL_HANDLER) || ENABLE(CUSTOM_SCHEME_HANDLER) +#include "RegisterProtocolHandlerClientEfl.h" +#endif + static const float zoomMinimum = 0.05; static const float zoomMaximum = 4.0; @@ -754,7 +758,11 @@ static Ewk_View_Private_Data* _ewk_view_priv_new(Ewk_View_Smart_Data* smartData) #endif #if ENABLE(BATTERY_STATUS) - WebCore::provideBatteryTo(priv->page.get(), new BatteryClientEfl); + WebCore::provideBatteryTo(priv->page.get(), new BatteryClientEfl(smartData->self)); +#endif + +#if ENABLE(REGISTER_PROTOCOL_HANDLER) || ENABLE(CUSTOM_SCHEME_HANDLER) + WebCore::provideRegisterProtocolHandlerTo(priv->page.get(), new WebCore::RegisterProtocolHandlerClientEfl(smartData->self)); #endif priv->pageSettings = priv->page->settings(); @@ -1376,12 +1384,8 @@ void ewk_view_theme_set(Evas_Object* ewkView, const char* path) if (!eina_stringshare_replace(&priv->settings.theme, path)) return; - WebCore::FrameView* view = priv->mainFrame->view(); - if (view) { - view->setEdjeTheme(WTF::String(path)); - priv->page->theme()->themeChanged(); - } - + WebCore::RenderThemeEfl* theme = static_cast<WebCore::RenderThemeEfl*>(priv->page->theme()); + theme->setThemePath(path); } const char* ewk_view_theme_get(const Evas_Object* ewkView) diff --git a/Source/WebKit/efl/ewk/ewk_view.h b/Source/WebKit/efl/ewk/ewk_view.h index d5feb36b3..55ed3ee86 100644 --- a/Source/WebKit/efl/ewk/ewk_view.h +++ b/Source/WebKit/efl/ewk/ewk_view.h @@ -584,7 +584,7 @@ EAPI void ewk_tile_unused_cache_auto_flush(Ewk_Tile_Unused_Cache *tuc); * * @param api class definition to set, all members with the * exception of @a Evas_Smart_Class->data may be overridden, must - * @b not be @c 0 + * @b not be @c NULL * * @note @a Evas_Smart_Class->data is used to implement type checking and * is not supposed to be changed/overridden. If you need extra @@ -605,7 +605,7 @@ EAPI Eina_Bool ewk_view_base_smart_set(Ewk_View_Smart_Class *api); * * @param api class definition to set, all members with the * exception of @a Evas_Smart_Class->data may be overridden, must - * @b not be @c 0 + * @b not be @c NULL * * @note @a Evas_Smart_Class->data is used to implement type checking and * is not supposed to be changed/overridden. If you need extra @@ -625,7 +625,7 @@ EAPI Eina_Bool ewk_view_single_smart_set(Ewk_View_Smart_Class *api); * * @param api class definition to set, all members with the * exception of @a Evas_Smart_Class->data may be overridden, must - * @b not be @c 0 + * @b not be @c NULL * * @note @a Evas_Smart_Class->data is used to implement type checking and * is not supposed to be changed/overridden. If you need extra @@ -651,7 +651,7 @@ EAPI Eina_Bool ewk_view_tiled_smart_set(Ewk_View_Smart_Class *api); * * @param e canvas object where to create the view object * - * @return view object on success or @c 0 on failure + * @return view object on success or @c NULL on failure * * @see ewk_view_uri_set() */ @@ -669,7 +669,7 @@ EAPI Evas_Object *ewk_view_single_add(Evas *e); * * @param e canvas object where to create the view object * - * @return the view object on success or @c 0 on failure + * @return the view object on success or @c NULL on failure * * @see ewk_view_uri_set() */ @@ -680,7 +680,7 @@ EAPI Evas_Object *ewk_view_tiled_add(Evas *e); * * @param o the view object to get the cache object * - * @return the cache object of unused tiles or @c 0 on failure + * @return the cache object of unused tiles or @c NULL on failure */ EAPI Ewk_Tile_Unused_Cache *ewk_view_tiled_unused_cache_get(const Evas_Object *o); @@ -691,7 +691,7 @@ EAPI Ewk_Tile_Unused_Cache *ewk_view_tiled_unused_cache_get(const Evas_Object *o * The tiles from one view will not be used by the other! * This is just to limit the group with amount of unused memory. * - * @note If @c 0 is provided as a @a cache, then a new one is created. + * @note If @c NULL is provided as a @a cache, then a new one is created. * * @param o the view object to set the cache object * @param the cache object of unused tiles @@ -719,9 +719,9 @@ EAPI void ewk_view_fixed_layout_size_set(Evas_Object *o, Evas_Coord w, E * Gets fixed layout size. * * @param o view object to get fixed layout size - * @param w the pointer to store fixed width, returns @c 0 on failure or if there is no + * @param w the pointer to store fixed width, returns @c NULL on failure or if there is no * fixed layout in use - * @param h the pointer to store fixed height, returns @c 0 on failure or if there is no + * @param h the pointer to store fixed height, returns @c NULL on failure or if there is no * fixed layout in use */ EAPI void ewk_view_fixed_layout_size_get(const Evas_Object *o, Evas_Coord *w, Evas_Coord *h); @@ -734,7 +734,7 @@ EAPI void ewk_view_fixed_layout_size_get(const Evas_Object *o, Evas_Coor * use this one. * * @param o view object to change theme - * @param path theme path, may be @c 0 to reset to the default theme + * @param path theme path, may be @c NULL to reset to the default theme */ EAPI void ewk_view_theme_set(Evas_Object *o, const char *path); @@ -745,7 +745,7 @@ EAPI void ewk_view_theme_set(Evas_Object *o, const char *path); * * @param o view object to get theme path * - * @return the theme path, may be @c 0 if not set + * @return the theme path, may be @c NULL if not set */ EAPI const char *ewk_view_theme_get(const Evas_Object *o); @@ -754,7 +754,7 @@ EAPI const char *ewk_view_theme_get(const Evas_Object *o); * * @param o view object to get main frame * - * @return frame smart object or @c 0 if none yet + * @return frame smart object or @c NULL if none yet */ EAPI Evas_Object *ewk_view_frame_main_get(const Evas_Object *o); @@ -763,7 +763,7 @@ EAPI Evas_Object *ewk_view_frame_main_get(const Evas_Object *o); * * @param o view object to get focused frame * - * @return frame smart object or @c 0 if none yet + * @return frame smart object or @c NULL if none yet */ EAPI Evas_Object *ewk_view_frame_focused_get(const Evas_Object *o); @@ -785,7 +785,7 @@ EAPI Eina_Bool ewk_view_uri_set(Evas_Object *o, const char *uri); * * @param o view object to get current uri. * - * @return current uri on success or @c 0 on failure + * @return current uri on success or @c NULL on failure */ EAPI const char *ewk_view_uri_get(const Evas_Object *o); @@ -797,7 +797,7 @@ EAPI const char *ewk_view_uri_get(const Evas_Object *o); * * @param o view object to get current title * - * @return current title on success or @c 0 on failure + * @return current title on success or @c NULL on failure */ EAPI const Ewk_Text_With_Direction *ewk_view_title_get(const Evas_Object *o); @@ -862,7 +862,7 @@ EAPI void ewk_view_bg_color_get(const Evas_Object *o, int *r, int *g, in * * @param o view object to get selected text * - * @return a newly allocated string or @c 0 if nothing is selected or on failure + * @return a newly allocated string or @c NULL if nothing is selected or on failure */ EAPI char *ewk_view_selection_get(const Evas_Object *o); @@ -1141,7 +1141,7 @@ EAPI Eina_Bool ewk_view_history_enable_set(Evas_Object *o, Eina_Bool enable); * @param o view object to get navigation history * * @return the history instance handle associated with this - * view on succes or @c 0 on failure (including when the history + * view on succes or @c NULL on failure (including when the history * navigation is not enabled with ewk_view_history_enable_set()) * * @see ewk_view_history_enable_set() @@ -1847,7 +1847,7 @@ EAPI Eina_Bool ewk_view_setting_caret_browsing_set(Evas_Object *o, Eina_Bool * @param o view object to get the current encoding * * @return @c eina_strinshare containing the current encoding, or - * @c 0 if it's not set + * @c NULL if it's not set */ EAPI const char *ewk_view_setting_encoding_custom_get(const Evas_Object *o); @@ -1855,7 +1855,7 @@ EAPI const char *ewk_view_setting_encoding_custom_get(const Evas_Object *o); * Sets the encoding and reloads the page. * * @param o view to set the encoding - * @param encoding the new encoding to set or @c 0 to restore the default one + * @param encoding the new encoding to set or @c NULL to restore the default one * * @return @c EINA_TRUE on success @c EINA_FALSE otherwise */ @@ -1867,7 +1867,7 @@ EAPI Eina_Bool ewk_view_setting_encoding_custom_set(Evas_Object *o, const cha * @param o view object to get the default encoding * * @return @c eina_strinshare containing the default encoding, or - * @c 0 if it's not set + * @c NULL if it's not set */ EAPI const char *ewk_view_setting_encoding_default_get(const Evas_Object *o); @@ -2037,7 +2037,7 @@ EAPI Eina_Bool ewk_view_setting_local_storage_set(Evas_Object *o, Eina_Bool e * @param o view object to get the database path to the local storage feature * * @return @c eina_stringshare containing the database path to the local storage feature, or - * @c 0 if it's not set + * @c NULL if it's not set * * @sa ewk_view_setting_local_storage_database_path_set */ @@ -2232,7 +2232,7 @@ EAPI Eina_Bool ewk_view_setting_enable_hyperlink_auditing_set(Evas_Object *o, Ei * * @param o view object to get the internal data * - * @return the internal data of @a o, or @c 0 on failure + * @return the internal data of @a o, or @c NULL on failure */ EAPI Ewk_View_Smart_Data *ewk_view_smart_data_get(const Evas_Object *o); @@ -2305,7 +2305,7 @@ EAPI Eina_Bool ewk_view_paint_contents(Ewk_View_Private_Data *priv, cairo_t *cr, /** * Gets the attributes of the viewport meta tag. * - * Properties are returned in the respective pointers. Passing @c 0 to any of + * Properties are returned in the respective pointers. Passing @c NULL to any of * these pointers will make that property to not be returned. * * @param o view object to get the viewport attributes @@ -2681,7 +2681,7 @@ EAPI void ewk_view_web_inspector_close(const Evas_Object *o); * * @param o The view that is inspected. * - * @return view object on success or @c 0 on failure + * @return view object on success or @c NULL on failure */ EAPI Evas_Object* ewk_view_web_inspector_view_get(const Evas_Object *o); diff --git a/Source/WebKit/efl/ewk/ewk_window_features.h b/Source/WebKit/efl/ewk/ewk_window_features.h index a9013959e..d67a45e29 100644 --- a/Source/WebKit/efl/ewk/ewk_window_features.h +++ b/Source/WebKit/efl/ewk/ewk_window_features.h @@ -38,7 +38,7 @@ typedef struct _Ewk_Window_Features Ewk_Window_Features; /** * Decreases the referece count of an Ewk_Window_Features, possibly freeing it. * - * When the reference count of the object reaches 0, the one is freed. + * When the reference count of the object reaches 0, it is freed. * * @param window_features the object to decrease reference count */ @@ -54,8 +54,8 @@ EAPI void ewk_window_features_ref(Ewk_Window_Features *window_features); /** * Gets boolean properties of an Ewk_Window_Features. * - * Properties are returned in the respective pointers. Passing @c 0 to any of - * these pointers will make that property to not be returned. + * Properties are returned in the respective pointers. Passing @c NULL to any of + * these pointers will cause that property to not be returned. * * @param window_features the object to get boolean properties * @param toolbar_visible the pointer to store if toolbar is visible @@ -72,11 +72,11 @@ EAPI void ewk_window_features_bool_property_get(const Ewk_Window_Feature /** * Gets int properties of an Ewk_Window_Features. * - * Properties are returned in the respective pointers. Passing @c 0 to any of - * these pointers will make that property to not be returned. + * Properties are returned in the respective pointers. Passing @c NULL to any of + * these pointers will cause that property to not be returned. * * Make sure to check if the value returned is less than 0 before using it, since in - * that case it means that property was not set in winwdow_features object. + * that case it means that property was not set in window_features object. * * @param window_features the window's features * @param x the pointer to store x position diff --git a/Source/WebKit/gtk/ChangeLog b/Source/WebKit/gtk/ChangeLog index 95fa53e62..be5485d56 100644 --- a/Source/WebKit/gtk/ChangeLog +++ b/Source/WebKit/gtk/ChangeLog @@ -1,3 +1,54 @@ +2012-07-17 Vivek Galatage <vivekgalatage@gmail.com> + + Web Inspector: refactor InspectorController::connectFrontend() to accept InspectorFrontendChannel. + https://bugs.webkit.org/show_bug.cgi?id=91196 + + Reviewed by Pavel Feldman. + + Refactoring InspectorClients. InspectorClient::openInspectorFrontend + now returning the InspectorFrontendChannel. + + * WebCoreSupport/InspectorClientGtk.cpp: + (WebKit::InspectorClient::openInspectorFrontend): + * WebCoreSupport/InspectorClientGtk.h: + (InspectorClient): + +2012-07-16 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Add RegisterProtocolHandlerClient to the Modules/protocolhandler + https://bugs.webkit.org/show_bug.cgi?id=90940 + + Reviewed by Hajime Morita. + + As a step to let protocol handler be moved to the modules, RegisterProtocolHandlerClient needs + to be added to the Modules/protocolhandler. Because ChromeClient has some virtual functions for + protocol handlers, virtual functions should be moved to RegisterProtocolHandlerClient. + + In order to support this, RegisterProtocolHandlerClientGtk class is added and webview registers + RegisterProtocolHandlerClientGtk. In addition, existing concrete functions in ChromeClientGtk are moved + to RegisterProtocolHandlerClientGtk. + + * GNUmakefile.am: + * WebCoreSupport/ChromeClientGtk.cpp: + * WebCoreSupport/ChromeClientGtk.h: + (ChromeClient): + * WebCoreSupport/RegisterProtocolHandlerClientGtk.cpp: Added. + (WebKit): + (WebKit::RegisterProtocolHandlerClient::RegisterProtocolHandlerClient): + (WebKit::RegisterProtocolHandlerClient::registerProtocolHandler): + * WebCoreSupport/RegisterProtocolHandlerClientGtk.h: Added. + (WebKit): + (RegisterProtocolHandlerClient): + (WebKit::RegisterProtocolHandlerClient::~RegisterProtocolHandlerClient): + * webkit/webkitwebview.cpp: + (webkit_web_view_init): + +2012-07-16 Carlos Garcia Campos <cgarcia@igalia.com> + + Unreviewed. Update NEWS and configure.ac for 1.9.5 release + + * NEWS: Added release notes for 1.9.5. + 2012-07-10 Adam Barth <abarth@webkit.org> WebCore::Settings for Hixie76 WebSocket protocol doesn't do anything and should be removed diff --git a/Source/WebKit/gtk/GNUmakefile.am b/Source/WebKit/gtk/GNUmakefile.am index db3afada4..215576e51 100644 --- a/Source/WebKit/gtk/GNUmakefile.am +++ b/Source/WebKit/gtk/GNUmakefile.am @@ -213,6 +213,8 @@ webkitgtk_sources += \ Source/WebKit/gtk/WebCoreSupport/PasteboardHelperGtk.h \ Source/WebKit/gtk/WebCoreSupport/PlatformStrategiesGtk.h \ Source/WebKit/gtk/WebCoreSupport/PlatformStrategiesGtk.cpp \ + Source/WebKit/gtk/WebCoreSupport/RegisterProtocolHandlerClientGtk.h \ + Source/WebKit/gtk/WebCoreSupport/RegisterProtocolHandlerClientGtk.cpp \ Source/WebKit/gtk/WebCoreSupport/UserMediaClientGtk.cpp \ Source/WebKit/gtk/WebCoreSupport/UserMediaClientGtk.h \ Source/WebKit/gtk/WebCoreSupport/WebViewInputMethodFilter.cpp \ diff --git a/Source/WebKit/gtk/NEWS b/Source/WebKit/gtk/NEWS index 046cdf51e..5e7449c64 100644 --- a/Source/WebKit/gtk/NEWS +++ b/Source/WebKit/gtk/NEWS @@ -1,4 +1,34 @@ ================= +WebKitGTK+ 1.9.5 +================= + +What's new in WebKitGTK+ 1.9.5? + + - Add API to get HTTPS status to WebKit2 GTK+. + - Add API to clear the cache to WebKit2 GTK+. + - Add webkit_cookie_manager_set_persistent_storage() to WebKit2 GTK+ + API. + - Improve performance of searching in WebKit2. + - Implement disk cache in WebKit2. + - Add site specific quirks setting to WebKit2 GTK+ API. + - Add a setting to enable/disable page cache to WebKit2 GTK+ API. + - Add WebKitWebView::context-menu-dismissed signal to WebKit2 GTK+ + API. + - Add webkit_web_frame_get_dom_document() to WebKit GTK+ API. + - Use soup_cookie_jar_is_persistent() to set whether cookie is a + session one or not. + - Fix recognition of contractions (apostrophes) in spell checker. + - Fix a crash when showing the context menu in the Web Inspector. + - WebKitWebView::mouse-target-changed is not emitted when moved + to/from editable content. + - Fix inspector detach when inspector was attached by the client in + WebKit2. + - Don't show accel labels in WebKit2 context menu items. + - Cache the video dimensions to not query the video-sink sink-pad + caps every time. + - Fix several memory leaks. + +================= WebKitGTK+ 1.9.4 ================= diff --git a/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp b/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp index 91a21e819..41c840924 100644 --- a/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp +++ b/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp @@ -386,13 +386,6 @@ IntRect ChromeClient::windowResizerRect() const return IntRect(); } -#if ENABLE(REGISTER_PROTOCOL_HANDLER) -void ChromeClient::registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title) -{ - notImplemented(); -} -#endif - static gboolean repaintEverythingSoonTimeout(ChromeClient* client) { client->paint(0); diff --git a/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h b/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h index aa044b7bc..d58ffc1c4 100644 --- a/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h +++ b/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h @@ -99,9 +99,6 @@ namespace WebKit { virtual KeyboardUIMode keyboardUIMode(); virtual IntRect windowResizerRect() const; -#if ENABLE(REGISTER_PROTOCOL_HANDLER) - virtual void registerProtocolHandler(const WTF::String&, const WTF::String&, const WTF::String&, const WTF::String&); -#endif virtual void invalidateRootView(const IntRect&, bool); virtual void invalidateContentsAndRootView(const IntRect&, bool); virtual void invalidateContentsForSlowScroll(const IntRect&, bool); diff --git a/Source/WebKit/gtk/WebCoreSupport/InspectorClientGtk.cpp b/Source/WebKit/gtk/WebCoreSupport/InspectorClientGtk.cpp index c1dd9b911..ed776b026 100644 --- a/Source/WebKit/gtk/WebCoreSupport/InspectorClientGtk.cpp +++ b/Source/WebKit/gtk/WebCoreSupport/InspectorClientGtk.cpp @@ -83,7 +83,7 @@ void InspectorClient::inspectorDestroyed() delete this; } -void InspectorClient::openInspectorFrontend(InspectorController* controller) +InspectorFrontendChannel* InspectorClient::openInspectorFrontend(InspectorController* controller) { // This g_object_get will ref the inspector. We're not doing an // unref if this method succeeds because the inspector object must @@ -99,7 +99,7 @@ void InspectorClient::openInspectorFrontend(InspectorController* controller) if (!inspectorWebView) { g_object_unref(webInspector); - return; + return 0; } webkit_web_inspector_set_web_view(webInspector, inspectorWebView); @@ -117,6 +117,8 @@ void InspectorClient::openInspectorFrontend(InspectorController* controller) // The inspector must be in it's own PageGroup to avoid deadlock while debugging. m_frontendPage->setGroupName(""); + + return this; } void InspectorClient::closeInspectorFrontend() diff --git a/Source/WebKit/gtk/WebCoreSupport/InspectorClientGtk.h b/Source/WebKit/gtk/WebCoreSupport/InspectorClientGtk.h index 63fc42012..74ec18e31 100644 --- a/Source/WebKit/gtk/WebCoreSupport/InspectorClientGtk.h +++ b/Source/WebKit/gtk/WebCoreSupport/InspectorClientGtk.h @@ -30,6 +30,7 @@ #define InspectorClientGtk_h #include "InspectorClient.h" +#include "InspectorFrontendChannel.h" #include "InspectorFrontendClientLocal.h" #include "webkitwebview.h" #include "webkitwebinspector.h" @@ -45,7 +46,7 @@ namespace WebKit { class InspectorFrontendClient; - class InspectorClient : public WebCore::InspectorClient { + class InspectorClient : public WebCore::InspectorClient, public WebCore::InspectorFrontendChannel { public: InspectorClient(WebKitWebView* webView); ~InspectorClient(); @@ -54,7 +55,7 @@ namespace WebKit { virtual void inspectorDestroyed(); - virtual void openInspectorFrontend(WebCore::InspectorController*); + virtual WebCore::InspectorFrontendChannel* openInspectorFrontend(WebCore::InspectorController*); virtual void closeInspectorFrontend(); virtual void bringFrontendToFront(); diff --git a/Source/WebKit/gtk/WebCoreSupport/RegisterProtocolHandlerClientGtk.cpp b/Source/WebKit/gtk/WebCoreSupport/RegisterProtocolHandlerClientGtk.cpp new file mode 100644 index 000000000..56d1b773e --- /dev/null +++ b/Source/WebKit/gtk/WebCoreSupport/RegisterProtocolHandlerClientGtk.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "RegisterProtocolHandlerClientGtk.h" + +#if ENABLE(REGISTER_PROTOCOL_HANDLER) + +#include "NotImplemented.h" +#include <wtf/text/CString.h> + +namespace WebKit { + +RegisterProtocolHandlerClient::RegisterProtocolHandlerClient() +{ +} + +void RegisterProtocolHandlerClient::registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title) +{ + notImplemented(); +} + +} +#endif // ENABLE(REGISTER_PROTOCOL_HANDLER) diff --git a/Source/WebKit/gtk/WebCoreSupport/RegisterProtocolHandlerClientGtk.h b/Source/WebKit/gtk/WebCoreSupport/RegisterProtocolHandlerClientGtk.h new file mode 100644 index 000000000..938fbc671 --- /dev/null +++ b/Source/WebKit/gtk/WebCoreSupport/RegisterProtocolHandlerClientGtk.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RegisterProtocolHandlerClientGtk_h +#define RegisterProtocolHandlerClientGtk_h + +#if ENABLE(REGISTER_PROTOCOL_HANDLER) +#include "RegisterProtocolHandlerClient.h" + +namespace WebKit { + +class RegisterProtocolHandlerClient : public WebCore::RegisterProtocolHandlerClient { +public: + RegisterProtocolHandlerClient(); + ~RegisterProtocolHandlerClient() { } + + virtual void registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title); +}; + +} + +#endif +#endif // RegisterProtocolHandlerClientGtk_h diff --git a/Source/WebKit/gtk/webkit/webkitwebview.cpp b/Source/WebKit/gtk/webkit/webkitwebview.cpp index 3344bf84b..810eec9c6 100644 --- a/Source/WebKit/gtk/webkit/webkitwebview.cpp +++ b/Source/WebKit/gtk/webkit/webkitwebview.cpp @@ -118,6 +118,10 @@ #include "DeviceOrientationClientGtk.h" #endif +#if ENABLE(REGISTER_PROTOCOL_HANDLER) +#include "RegisterProtocolHandlerClientGtk.h" +#endif + /** * SECTION:webkitwebview * @short_description: The central class of the WebKitGTK+ API @@ -3630,6 +3634,10 @@ static void webkit_web_view_init(WebKitWebView* webView) WebCore::provideUserMediaTo(priv->corePage, priv->userMediaClient.get()); #endif +#if ENABLE(REGISTER_PROTOCOL_HANDLER) + WebCore::provideRegisterProtocolHandlerTo(priv->corePage, new WebKit::RegisterProtocolHandlerClient); +#endif + if (DumpRenderTreeSupportGtk::dumpRenderTreeModeEnabled()) { // Set some testing-specific settings priv->corePage->settings()->setInteractiveFormValidationEnabled(true); diff --git a/Source/WebKit/mac/ChangeLog b/Source/WebKit/mac/ChangeLog index 25de1125e..b994b7000 100644 --- a/Source/WebKit/mac/ChangeLog +++ b/Source/WebKit/mac/ChangeLog @@ -1,3 +1,75 @@ +2012-07-17 Vivek Galatage <vivekgalatage@gmail.com> + + Web Inspector: refactor InspectorController::connectFrontend() to accept InspectorFrontendChannel. + https://bugs.webkit.org/show_bug.cgi?id=91196 + + Reviewed by Pavel Feldman. + + Refactoring InspectorClients. InspectorClient::openInspectorFrontend + now returning the InspectorFrontendChannel. + + * WebCoreSupport/WebInspectorClient.h: + (WebInspectorClient): + * WebCoreSupport/WebInspectorClient.mm: + (WebInspectorClient::openInspectorFrontend): + +2012-07-17 David Barr <davidbarr@chromium.org> + + Introduce ENABLE_CSS_IMAGE_ORIENTATION compile flag + https://bugs.webkit.org/show_bug.cgi?id=89055 + + Reviewed by Kent Tamura. + + The css3-images module is at candidate recommendation. + http://www.w3.org/TR/2012/CR-css3-images-20120417/#the-image-orientation + + Add a configuration option for CSS image-orientation support, disabling it by default. + + * Configurations/FeatureDefines.xcconfig: + +2012-07-15 Joseph Pecoraro <pecoraro@apple.com> + + Fix case sensitive build issue. + + Unreviewed build fix. + + * WebView/WebPreferences.mm: + +2012-07-15 Benjamin Poulain <benjamin@webkit.org> + + Make WebPreferencesPrivate a simple struct + https://bugs.webkit.org/show_bug.cgi?id=91330 + + Reviewed by Filip Pizlo. + + To avoid taking time creating a new Objective-C object for WebPreferencesPrivate, we can just make + it a simple struct. + + * WebView/WebPreferences.h: + * WebView/WebPreferences.mm: + (WebPreferencesPrivate): + (WebPreferencesPrivate::WebPreferencesPrivate): + Replace the Objective-C WebPreferencesPrivate by a struct. + Remove IBCreatorID from the object as it is unused. + Use RetainPtr for the Objective-C attribute to avoid tracking their memory manually. + + (-[WebPreferences initWithIdentifier:]): + Change the order of the initialization to avoid allocating anyting if a WebPreferences exists + for the identifier. + Both [NSObject init] and WebPreferencesPrivate allocation are moved after the fast path. + + (-[WebPreferences initWithCoder:]): + (-[WebPreferences encodeWithCoder:]): + (-[WebPreferences dealloc]): + (-[WebPreferences identifier]): + (-[WebPreferences _valueForKey:]): + (-[WebPreferences _setStringValue:forKey:]): + (-[WebPreferences _setIntegerValue:forKey:]): + (-[WebPreferences _setFloatValue:forKey:]): + (-[WebPreferences _setBoolValue:forKey:]): + (-[WebPreferences _setLongLongValue:forKey:]): + (-[WebPreferences _setUnsignedLongLongValue:forKey:]): + 2012-07-14 Benjamin Poulain <bpoulain@apple.com> [Mac] Do not try to update the cache model for every WebPreferences change diff --git a/Source/WebKit/mac/Configurations/FeatureDefines.xcconfig b/Source/WebKit/mac/Configurations/FeatureDefines.xcconfig index 7f95c3018..1fc82597c 100644 --- a/Source/WebKit/mac/Configurations/FeatureDefines.xcconfig +++ b/Source/WebKit/mac/Configurations/FeatureDefines.xcconfig @@ -42,6 +42,7 @@ ENABLE_CSS_BOX_DECORATION_BREAK = ENABLE_CSS_BOX_DECORATION_BREAK; ENABLE_CSS_EXCLUSIONS = ENABLE_CSS_EXCLUSIONS; ENABLE_CSS_FILTERS = ENABLE_CSS_FILTERS; ENABLE_CSS_SHADERS = ENABLE_CSS_SHADERS; +ENABLE_CSS_IMAGE_ORIENTATION = ; ENABLE_CSS_IMAGE_RESOLUTION = ; ENABLE_CSS_REGIONS = ENABLE_CSS_REGIONS; ENABLE_CSS_VARIABLES = ; @@ -134,4 +135,4 @@ ENABLE_WEB_TIMING = ; ENABLE_WORKERS = ENABLE_WORKERS; ENABLE_XSLT = ENABLE_XSLT; -FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS3_FLEXBOX) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_VARIABLES) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIALOG_ELEMENT) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LINK_PREFETCH) $(ENABLE_LINK_PRERENDER) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_TAG) $(ENABLE_MICRODATA) $(ENABLE_MUTATION_OBSERVERS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_TAG) $(ENABLE_QUOTA) $(ENABLE_REGISTER_PROTOCOL_HANDLER) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SVG) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TEXT_NOTIFICATIONS_ONLY) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_UNDO_MANAGER) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XSLT); +FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS3_FLEXBOX) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_VARIABLES) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIALOG_ELEMENT) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LINK_PREFETCH) $(ENABLE_LINK_PRERENDER) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_TAG) $(ENABLE_MICRODATA) $(ENABLE_MUTATION_OBSERVERS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_TAG) $(ENABLE_QUOTA) $(ENABLE_REGISTER_PROTOCOL_HANDLER) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SVG) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TEXT_NOTIFICATIONS_ONLY) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_UNDO_MANAGER) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XSLT); diff --git a/Source/WebKit/mac/Configurations/Version.xcconfig b/Source/WebKit/mac/Configurations/Version.xcconfig index 4404b895a..841345e10 100644 --- a/Source/WebKit/mac/Configurations/Version.xcconfig +++ b/Source/WebKit/mac/Configurations/Version.xcconfig @@ -22,7 +22,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. MAJOR_VERSION = 537; -MINOR_VERSION = 1; +MINOR_VERSION = 2; TINY_VERSION = 0; FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION); diff --git a/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.h b/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.h index b145dc4e4..9495958e9 100644 --- a/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.h +++ b/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.h @@ -27,6 +27,7 @@ */ #import <WebCore/InspectorClient.h> +#import <WebCore/InspectorFrontendChannel.h> #import <WebCore/InspectorFrontendClientLocal.h> #import <WebCore/PlatformString.h> @@ -54,13 +55,13 @@ class Page; class WebInspectorFrontendClient; -class WebInspectorClient : public WebCore::InspectorClient { +class WebInspectorClient : public WebCore::InspectorClient, public WebCore::InspectorFrontendChannel { public: WebInspectorClient(WebView *); virtual void inspectorDestroyed() OVERRIDE; - virtual void openInspectorFrontend(WebCore::InspectorController*) OVERRIDE; + virtual WebCore::InspectorFrontendChannel* openInspectorFrontend(WebCore::InspectorController*) OVERRIDE; virtual void closeInspectorFrontend() OVERRIDE; virtual void bringFrontendToFront() OVERRIDE; virtual void didResizeMainFrame(WebCore::Frame*) OVERRIDE; diff --git a/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.mm b/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.mm index bd7b600a9..fda659256 100644 --- a/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.mm +++ b/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.mm @@ -92,7 +92,7 @@ void WebInspectorClient::inspectorDestroyed() delete this; } -void WebInspectorClient::openInspectorFrontend(InspectorController* inspectorController) +InspectorFrontendChannel* WebInspectorClient::openInspectorFrontend(InspectorController* inspectorController) { RetainPtr<WebInspectorWindowController> windowController(AdoptNS, [[WebInspectorWindowController alloc] initWithInspectedWebView:m_webView]); [windowController.get() setInspectorClient:this]; @@ -103,6 +103,7 @@ void WebInspectorClient::openInspectorFrontend(InspectorController* inspectorCon RetainPtr<WebInspectorFrontend> webInspectorFrontend(AdoptNS, [[WebInspectorFrontend alloc] initWithFrontendClient:frontendClient.get()]); [[m_webView inspector] setFrontend:webInspectorFrontend.get()]; m_frontendPage->inspectorController()->setInspectorFrontendClient(frontendClient.release()); + return this; } void WebInspectorClient::closeInspectorFrontend() diff --git a/Source/WebKit/mac/WebView/WebPreferences.h b/Source/WebKit/mac/WebView/WebPreferences.h index 6e01709f0..932656b07 100644 --- a/Source/WebKit/mac/WebView/WebPreferences.h +++ b/Source/WebKit/mac/WebView/WebPreferences.h @@ -64,7 +64,7 @@ enum { }; typedef NSUInteger WebCacheModel; -@class WebPreferencesPrivate; +typedef struct WebPreferencesPrivate WebPreferencesPrivate; extern NSString *WebPreferencesChangedNotification; diff --git a/Source/WebKit/mac/WebView/WebPreferences.mm b/Source/WebKit/mac/WebView/WebPreferences.mm index 1defbf5ed..f209ed80d 100644 --- a/Source/WebKit/mac/WebView/WebPreferences.mm +++ b/Source/WebKit/mac/WebView/WebPreferences.mm @@ -41,6 +41,7 @@ #import <WebCore/ApplicationCacheStorage.h> #import <WebCore/CookieStorageCFNet.h> #import <WebCore/ResourceHandle.h> +#import <wtf/RetainPtr.h> using namespace WebCore; @@ -49,7 +50,7 @@ NSString *WebPreferencesRemovedNotification = @"WebPreferencesRemovedNotificatio NSString *WebPreferencesChangedInternalNotification = @"WebPreferencesChangedInternalNotification"; NSString *WebPreferencesCacheModelChangedInternalNotification = @"WebPreferencesCacheModelChangedInternalNotification"; -#define KEY(x) (_private->identifier ? [_private->identifier stringByAppendingString:(x)] : (x)) +#define KEY(x) (_private->identifier ? [_private->identifier.get() stringByAppendingString:(x)] : (x)) enum { WebPreferencesVersion = 1 }; @@ -142,28 +143,6 @@ static WebCacheModel cacheModelForMainBundle(void) return cacheModel; } -@interface WebPreferencesPrivate : NSObject -{ -@public - NSMutableDictionary *values; - NSString *identifier; - NSString *IBCreatorID; - BOOL autosaves; - BOOL automaticallyDetectsCacheModel; - unsigned numWebViews; -} -@end - -@implementation WebPreferencesPrivate -- (void)dealloc -{ - [values release]; - [identifier release]; - [IBCreatorID release]; - [super dealloc]; -} -@end - @interface WebPreferences () - (void)_postCacheModelChangedNotification; @end @@ -173,6 +152,23 @@ static WebCacheModel cacheModelForMainBundle(void) + (NSString *)_IBCreatorID; @end +struct WebPreferencesPrivate +{ +public: + WebPreferencesPrivate() + : autosaves(NO) + , automaticallyDetectsCacheModel(NO) + , numWebViews(0) + { + } + + RetainPtr<NSMutableDictionary> values; + RetainPtr<NSString> identifier; + BOOL autosaves; + BOOL automaticallyDetectsCacheModel; + unsigned numWebViews; +}; + @interface WebPreferences (WebForwardDeclarations) // This pseudo-category is needed so these methods can be used from within other category implementations // without being in the public header file. @@ -207,24 +203,22 @@ static WebCacheModel cacheModelForMainBundle(void) - (id)initWithIdentifier:(NSString *)anIdentifier { - self = [super init]; - if (!self) - return nil; - - _private = [[WebPreferencesPrivate alloc] init]; - _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain]; - WebPreferences *instance = [[self class] _getInstanceForIdentifier:anIdentifier]; - if (instance){ + if (instance) { [self release]; return [instance retain]; } - _private->values = [[NSMutableDictionary alloc] init]; - _private->identifier = [anIdentifier copy]; + self = [super init]; + if (!self) + return nil; + + _private = new WebPreferencesPrivate; + _private->values.adoptNS([[NSMutableDictionary alloc] init]); + _private->identifier.adoptNS([anIdentifier copy]); _private->automaticallyDetectsCacheModel = YES; - [[self class] _setInstance:self forIdentifier:_private->identifier]; + [[self class] _setInstance:self forIdentifier:_private->identifier.get()]; [self _postPreferencesChangedNotification]; [self _postCacheModelChangedNotification]; @@ -238,8 +232,7 @@ static WebCacheModel cacheModelForMainBundle(void) if (!self) return nil; - _private = [[WebPreferencesPrivate alloc] init]; - _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain]; + _private = new WebPreferencesPrivate; _private->automaticallyDetectsCacheModel = YES; @try { @@ -258,11 +251,11 @@ static WebCacheModel cacheModelForMainBundle(void) } if ([identifier isKindOfClass:[NSString class]]) - _private->identifier = [identifier copy]; + _private->identifier.adoptNS([identifier copy]); if ([values isKindOfClass:[NSDictionary class]]) - _private->values = [values mutableCopy]; // ensure dictionary is mutable + _private->values.adoptNS([values mutableCopy]); // ensure dictionary is mutable - LOG(Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values); + LOG(Encoding, "Identifier = %@, Values = %@\n", _private->identifier.get(), _private->values.get()); } @catch(id) { [self release]; return nil; @@ -270,12 +263,12 @@ static WebCacheModel cacheModelForMainBundle(void) // If we load a nib multiple times, or have instances in multiple // nibs with the same name, the first guy up wins. - WebPreferences *instance = [[self class] _getInstanceForIdentifier:_private->identifier]; + WebPreferences *instance = [[self class] _getInstanceForIdentifier:_private->identifier.get()]; if (instance) { [self release]; self = [instance retain]; } else { - [[self class] _setInstance:self forIdentifier:_private->identifier]; + [[self class] _setInstance:self forIdentifier:_private->identifier.get()]; } return self; @@ -284,15 +277,15 @@ static WebCacheModel cacheModelForMainBundle(void) - (void)encodeWithCoder:(NSCoder *)encoder { if ([encoder allowsKeyedCoding]){ - [encoder encodeObject:_private->identifier forKey:@"Identifier"]; - [encoder encodeObject:_private->values forKey:@"Values"]; - LOG (Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values); + [encoder encodeObject:_private->identifier.get() forKey:@"Identifier"]; + [encoder encodeObject:_private->values.get() forKey:@"Values"]; + LOG (Encoding, "Identifier = %@, Values = %@\n", _private->identifier.get(), _private->values.get()); } else { int version = WebPreferencesVersion; [encoder encodeValueOfObjCType:@encode(int) at:&version]; - [encoder encodeObject:_private->identifier]; - [encoder encodeObject:_private->values]; + [encoder encodeObject:_private->identifier.get()]; + [encoder encodeObject:_private->values.get()]; } } @@ -418,19 +411,19 @@ static WebCacheModel cacheModelForMainBundle(void) - (void)dealloc { - [_private release]; + delete _private; [super dealloc]; } - (NSString *)identifier { - return _private->identifier; + return _private->identifier.get(); } - (id)_valueForKey:(NSString *)key { NSString *_key = KEY(key); - id o = [_private->values objectForKey:_key]; + id o = [_private->values.get() objectForKey:_key]; if (o) return o; o = [[NSUserDefaults standardUserDefaults] objectForKey:_key]; @@ -450,7 +443,7 @@ static WebCacheModel cacheModelForMainBundle(void) if ([[self _stringValueForKey:key] isEqualToString:value]) return; NSString *_key = KEY(key); - [_private->values setObject:value forKey:_key]; + [_private->values.get() setObject:value forKey:_key]; if (_private->autosaves) [[NSUserDefaults standardUserDefaults] setObject:value forKey:_key]; [self _postPreferencesChangedNotification]; @@ -467,7 +460,7 @@ static WebCacheModel cacheModelForMainBundle(void) if ([self _integerValueForKey:key] == value) return; NSString *_key = KEY(key); - [_private->values _webkit_setInt:value forKey:_key]; + [_private->values.get() _webkit_setInt:value forKey:_key]; if (_private->autosaves) [[NSUserDefaults standardUserDefaults] setInteger:value forKey:_key]; [self _postPreferencesChangedNotification]; @@ -484,7 +477,7 @@ static WebCacheModel cacheModelForMainBundle(void) if ([self _floatValueForKey:key] == value) return; NSString *_key = KEY(key); - [_private->values _webkit_setFloat:value forKey:_key]; + [_private->values.get() _webkit_setFloat:value forKey:_key]; if (_private->autosaves) [[NSUserDefaults standardUserDefaults] setFloat:value forKey:_key]; [self _postPreferencesChangedNotification]; @@ -500,7 +493,7 @@ static WebCacheModel cacheModelForMainBundle(void) if ([self _boolValueForKey:key] == value) return; NSString *_key = KEY(key); - [_private->values _webkit_setBool:value forKey:_key]; + [_private->values.get() _webkit_setBool:value forKey:_key]; if (_private->autosaves) [[NSUserDefaults standardUserDefaults] setBool:value forKey:_key]; [self _postPreferencesChangedNotification]; @@ -517,7 +510,7 @@ static WebCacheModel cacheModelForMainBundle(void) if ([self _longLongValueForKey:key] == value) return; NSString *_key = KEY(key); - [_private->values _webkit_setLongLong:value forKey:_key]; + [_private->values.get() _webkit_setLongLong:value forKey:_key]; if (_private->autosaves) [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithLongLong:value] forKey:_key]; [self _postPreferencesChangedNotification]; @@ -534,7 +527,7 @@ static WebCacheModel cacheModelForMainBundle(void) if ([self _unsignedLongLongValueForKey:key] == value) return; NSString *_key = KEY(key); - [_private->values _webkit_setUnsignedLongLong:value forKey:_key]; + [_private->values.get() _webkit_setUnsignedLongLong:value forKey:_key]; if (_private->autosaves) [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithUnsignedLongLong:value] forKey:_key]; [self _postPreferencesChangedNotification]; diff --git a/Source/WebKit/qt/Api/qwebelement.cpp b/Source/WebKit/qt/Api/qwebelement.cpp index bdf204b14..50128cbe8 100644 --- a/Source/WebKit/qt/Api/qwebelement.cpp +++ b/Source/WebKit/qt/Api/qwebelement.cpp @@ -33,7 +33,6 @@ #include "HTMLElement.h" #include "StylePropertySet.h" #include "StyleRule.h" -#if USE(JSC) #include "Completion.h" #include "JSGlobalObject.h" #include "JSHTMLElement.h" @@ -41,11 +40,6 @@ #include "PropertyNameArray.h" #include <parser/SourceCode.h> #include "qt_runtime.h" -#elif USE(V8) -#include "V8DOMWindow.h" -#include "V8Binding.h" -#include "NotImplemented.h" -#endif #include "NodeList.h" #include "RenderImage.h" #include "ScriptState.h" @@ -54,10 +48,8 @@ #include "markup.h" #include "qwebframe.h" #include "qwebframe_p.h" -#if USE(JSC) #include "runtime_root.h" #include <JSDocument.h> -#endif #include <wtf/Vector.h> #include <wtf/text/CString.h> @@ -716,7 +708,6 @@ QWebFrame *QWebElement::webFrame() const return QWebFramePrivate::kit(frame); } -#if USE(JSC) static bool setupScriptContext(WebCore::Element* element, JSC::JSValue& thisValue, ScriptState*& state, ScriptController*& scriptController) { if (!element) @@ -744,27 +735,6 @@ static bool setupScriptContext(WebCore::Element* element, JSC::JSValue& thisValu return true; } -#elif USE(V8) -static bool setupScriptContext(WebCore::Element* element, v8::Handle<v8::Value>& thisValue, ScriptState*& state, ScriptController*& scriptController) -{ - if (!element) - return false; - - Document* document = element->document(); - if (!document) - return false; - - Frame* frame = document->frame(); - if (!frame) - return false; - - state = mainWorldScriptState(frame); - // Get V8 wrapper for DOM element - thisValue = toV8(frame->domWindow()); - return true; -} -#endif - /*! Executes \a scriptSource with this element as \c this object. @@ -775,16 +745,11 @@ QVariant QWebElement::evaluateJavaScript(const QString& scriptSource) return QVariant(); ScriptState* state = 0; -#if USE(JSC) JSC::JSValue thisValue; -#elif USE(V8) - v8::Handle<v8::Value> thisValue; -#endif ScriptController* scriptController = 0; if (!setupScriptContext(m_element, thisValue, state, scriptController)) return QVariant(); -#if USE(JSC) JSC::ScopeChainNode* scopeChain = state->dynamicGlobalObject()->globalScopeChain(); JSC::UString script(reinterpret_cast_ptr<const UChar*>(scriptSource.data()), scriptSource.length()); @@ -795,10 +760,6 @@ QVariant QWebElement::evaluateJavaScript(const QString& scriptSource) int distance = 0; return JSC::Bindings::convertValueToQVariant(state, evaluationResult, QMetaType::Void, &distance); -#elif USE(V8) - notImplemented(); - return QVariant(); -#endif } /*! @@ -2075,7 +2036,6 @@ QList<QWebElement> QWebElementCollection::toList() const element pointed to by the \a other iterator. */ -#if USE(JSC) QWebElement QtWebElementRuntime::create(Element* element) { return QWebElement(element); @@ -2111,7 +2071,6 @@ static JSC::JSValue convertWebElementVariantToJSValue(JSC::ExecState* exec, WebC { return WebCore::toJS(exec, globalObject, QtWebElementRuntime::get(variant.value<QWebElement>())); } -#endif void QtWebElementRuntime::initialize() { @@ -2119,8 +2078,6 @@ void QtWebElementRuntime::initialize() if (initialized) return; initialized = true; -#if USE(JSC) int id = qRegisterMetaType<QWebElement>(); JSC::Bindings::registerCustomType(id, convertJSValueToWebElementVariant, convertWebElementVariantToJSValue); -#endif } diff --git a/Source/WebKit/qt/Api/qwebframe.cpp b/Source/WebKit/qt/Api/qwebframe.cpp index ed1806fa0..dac4165e9 100644 --- a/Source/WebKit/qt/Api/qwebframe.cpp +++ b/Source/WebKit/qt/Api/qwebframe.cpp @@ -21,14 +21,9 @@ #include "config.h" #include "qwebframe.h" -#if USE(JSC) #include "APICast.h" #include "BridgeJSC.h" #include "CallFrame.h" -#elif USE(V8) -#include "V8Binding.h" -#include <QJSEngine> -#endif #include "Document.h" #include "DocumentLoader.h" #include "DragData.h" @@ -39,11 +34,7 @@ #include "FrameSelection.h" #include "FrameTree.h" #include "FrameView.h" -#if USE(JSC) #include "GCController.h" -#elif USE(V8) -#include "V8GCController.h" -#endif #include "GraphicsContext.h" #include "HTMLFormElement.h" #include "HTMLMetaElement.h" @@ -51,7 +42,6 @@ #include "HTTPParsers.h" #include "IconDatabase.h" #include "InspectorController.h" -#if USE(JSC) #include "JavaScript.h" #include "JSDOMBinding.h" #include "JSDOMWindowBase.h" @@ -59,20 +49,14 @@ #include "JSObject.h" #include "JSRetainPtr.h" #include "OpaqueJSString.h" -#elif USE(V8) -#include "V8DOMWrapper.h" -#include "V8DOMWindowShell.h" -#endif #include "NetworkingContext.h" #include "NodeList.h" #include "Page.h" #include "PlatformMouseEvent.h" #include "PlatformWheelEvent.h" #include "PrintContext.h" -#if USE(JSC) #include "PropertyDescriptor.h" #include "PutPropertySlot.h" -#endif #include "RenderLayer.h" #include "RenderTreeAsText.h" #include "RenderView.h" @@ -87,10 +71,8 @@ #include "TiledBackingStore.h" #include "htmlediting.h" #include "markup.h" -#if USE(JSC) #include "qt_instance.h" #include "qt_runtime.h" -#endif #include "qwebelement.h" #include "qwebframe_p.h" #include "qwebpage.h" @@ -99,10 +81,8 @@ #include "qwebsecurityorigin_p.h" #include "qwebscriptworld.h" #include "qwebscriptworld_p.h" -#if USE(JSC) #include "runtime_object.h" #include "runtime_root.h" -#endif #if USE(TEXTURE_MAPPER) #include "texmap/TextureMapper.h" #include "texmap/TextureMapperLayer.h" @@ -512,14 +492,11 @@ void QWebFramePrivate::_q_orientationChanged() void QWebFramePrivate::didClearWindowObject() { -#if USE(JSC) if (page->settings()->testAttribute(QWebSettings::JavascriptEnabled)) addQtSenderToGlobalObject(); -#endif emit q->javaScriptWindowObjectCleared(); } -#if USE(JSC) static JSValueRef qtSenderCallback(JSContextRef context, JSObjectRef, JSObjectRef, size_t, const JSValueRef[], JSValueRef*) { QObject* sender = JSC::Bindings::QtInstance::qtSenderStack()->top(); @@ -553,7 +530,6 @@ void QWebFramePrivate::addQtSenderToGlobalObject() descriptor.setConfigurable(false); window->methodTable()->defineOwnProperty(window, exec, propertyName.get()->identifier(&exec->globalData()), descriptor, false); } -#endif /*! \class QWebFrame @@ -682,7 +658,6 @@ void QWebFrame::addToJavaScriptWindowObject(const QString &name, QObject *object { if (!page()->settings()->testAttribute(QWebSettings::JavascriptEnabled)) return; -#if USE(JSC) JSC::Bindings::QtInstance::ValueOwnership valueOwnership = static_cast<JSC::Bindings::QtInstance::ValueOwnership>(ownership); JSDOMWindow* window = toJSDOMWindow(d->frame, mainThreadNormalWorld()); JSC::Bindings::RootObject* root; @@ -708,13 +683,6 @@ void QWebFrame::addToJavaScriptWindowObject(const QString &name, QObject *object JSC::PutPropertySlot slot; window->methodTable()->put(window, exec, JSC::Identifier(&exec->globalData(), reinterpret_cast_ptr<const UChar*>(name.constData()), name.length()), runtimeObject, slot); -#elif USE(V8) - QJSEngine* engine = d->frame->script()->qtScriptEngine(); - if (!engine) - return; - QJSValue v = engine->newQObject(object); // FIXME: Ownership not propagated yet. - engine->globalObject().property(QLatin1String("window")).setProperty(name, v); -#endif } /*! @@ -1604,17 +1572,10 @@ QVariant QWebFrame::evaluateJavaScript(const QString& scriptSource) ScriptController *proxy = d->frame->script(); QVariant rc; if (proxy) { -#if USE(JSC) int distance = 0; JSC::JSValue v = d->frame->script()->executeScript(ScriptSourceCode(scriptSource)).jsValue(); rc = JSC::Bindings::convertValueToQVariant(proxy->globalObject(mainThreadNormalWorld())->globalExec(), v, QMetaType::Void, &distance); -#elif USE(V8) - QJSEngine* engine = d->frame->script()->qtScriptEngine(); - if (!engine) - return rc; - rc = engine->evaluate(scriptSource).toVariant(); -#endif } return rc; } @@ -1773,9 +1734,9 @@ QWebHitTestResultPrivate::QWebHitTestResultPrivate(const WebCore::HitTestResult boundingRect = innerNonSharedNode ? innerNonSharedNode->renderer()->absoluteBoundingBoxRect() : IntRect(); WebCore::Image *img = hitTest.image(); if (img) { - QPixmap *pix = img->nativeImageForCurrentFrame(); + QImage *pix = img->nativeImageForCurrentFrame(); if (pix) - pixmap = *pix; + pixmap = QPixmap::fromImage(*pix); } WebCore::Frame *wframe = hitTest.targetFrame(); if (wframe) diff --git a/Source/WebKit/qt/Api/qwebhistory.cpp b/Source/WebKit/qt/Api/qwebhistory.cpp index 15d4ad8af..712c28f88 100644 --- a/Source/WebKit/qt/Api/qwebhistory.cpp +++ b/Source/WebKit/qt/Api/qwebhistory.cpp @@ -158,7 +158,7 @@ QDateTime QWebHistoryItem::lastVisited() const QIcon QWebHistoryItem::icon() const { if (d->item) - return *WebCore::iconDatabase().synchronousNativeIconForPageURL(d->item->url(), WebCore::IntSize(16, 16)); + return QPixmap::fromImage(*WebCore::iconDatabase().synchronousNativeIconForPageURL(d->item->url(), WebCore::IntSize(16, 16))); return QIcon(); } diff --git a/Source/WebKit/qt/Api/qwebsettings.cpp b/Source/WebKit/qt/Api/qwebsettings.cpp index 5358dd204..caf95058f 100644 --- a/Source/WebKit/qt/Api/qwebsettings.cpp +++ b/Source/WebKit/qt/Api/qwebsettings.cpp @@ -717,12 +717,12 @@ void QWebSettings::clearIconDatabase() QIcon QWebSettings::iconForUrl(const QUrl& url) { WebCore::initializeWebCoreQt(); - QPixmap* icon = WebCore::iconDatabase().synchronousNativeIconForPageURL(WebCore::KURL(url).string(), + QImage* icon = WebCore::iconDatabase().synchronousNativeIconForPageURL(WebCore::KURL(url).string(), WebCore::IntSize(16, 16)); if (!icon) - return QPixmap(); + return QIcon(); - return* icon; + return QPixmap::fromImage(*icon); } /* @@ -765,7 +765,7 @@ static const char* resourceNameForWebGraphic(QWebSettings::WebGraphic type) void QWebSettings::setWebGraphic(WebGraphic type, const QPixmap& graphic) { WebCore::initializeWebCoreQt(); - WebCore::Image::setPlatformResource(resourceNameForWebGraphic(type), graphic); + WebCore::Image::setPlatformResource(resourceNameForWebGraphic(type), graphic.toImage()); } /*! @@ -780,10 +780,10 @@ QPixmap QWebSettings::webGraphic(WebGraphic type) RefPtr<WebCore::Image> img = WebCore::Image::loadPlatformResource(resourceNameForWebGraphic(type)); if (!img) return QPixmap(); - QPixmap* pixmap = img->nativeImageForCurrentFrame(); - if (!pixmap) + QImage* image = img->nativeImageForCurrentFrame(); + if (!image) return QPixmap(); - return *pixmap; + return QPixmap::fromImage(*image); } /*! diff --git a/Source/WebKit/qt/Api/qwebview.cpp b/Source/WebKit/qt/Api/qwebview.cpp index 296661aa4..a6082cf63 100644 --- a/Source/WebKit/qt/Api/qwebview.cpp +++ b/Source/WebKit/qt/Api/qwebview.cpp @@ -33,6 +33,11 @@ #include "qprinter.h" #include "qdir.h" #include "qfile.h" +#ifndef QT_NO_ACCESSIBILITY +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +#include "qwebviewaccessible_p.h" +#endif +#endif class QWebViewPrivate { public: @@ -148,6 +153,23 @@ void QWebViewPrivate::_q_pageDestroyed() {Google Chat Example}, {Fancy Browser Example} */ +#ifndef QT_NO_ACCESSIBILITY +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +static QAccessibleInterface* accessibleInterfaceFactory(const QString& key, QObject* object) +{ + Q_UNUSED(key) + + if (QWebPage* page = qobject_cast<QWebPage*>(object)) + return new QWebPageAccessible(page); + if (QWebView* view = qobject_cast<QWebView*>(object)) + return new QWebViewAccessible(view); + if (QWebFrame* frame = qobject_cast<QWebFrame*>(object)) + return new QWebFrameAccessible(frame); + return 0; +} +#endif +#endif + /*! Constructs an empty QWebView with parent \a parent. @@ -167,6 +189,12 @@ QWebView::QWebView(QWidget *parent) setMouseTracking(true); setFocusPolicy(Qt::WheelFocus); + +#ifndef QT_NO_ACCESSIBILITY +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + QAccessible::installFactory(accessibleInterfaceFactory); +#endif +#endif } /*! diff --git a/Source/WebKit/qt/Api/qwebviewaccessible.cpp b/Source/WebKit/qt/Api/qwebviewaccessible.cpp new file mode 100644 index 000000000..7cae19a1a --- /dev/null +++ b/Source/WebKit/qt/Api/qwebviewaccessible.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) + + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "qwebviewaccessible_p.h" + +#include "qwebframe.h" +#include "qwebframe_p.h" +#include "qwebpage.h" +#include "qwebview.h" + +QWebFrameAccessible::QWebFrameAccessible(QWebFrame* frame) + : QAccessibleObject(frame) +{ +} + +QWebFrame* QWebFrameAccessible::frame() const +{ + return qobject_cast<QWebFrame*>(object()); +} + +QAccessibleInterface* QWebFrameAccessible::parent() const +{ + return QAccessible::queryAccessibleInterface(object()->parent()); +} + +QString QWebFrameAccessible::text(QAccessible::Text) const +{ + return QString(); +} + +int QWebFrameAccessible::childCount() const +{ + return 0; +} + +QAccessibleInterface* QWebFrameAccessible::child(int index) const +{ + return 0; +} + +int QWebFrameAccessible::indexOfChild(const QAccessibleInterface*) const +{ + return 0; +} + +QAccessible::State QWebFrameAccessible::state() const +{ + return QAccessible::State(); +} + +QAccessible::Role QWebFrameAccessible::role() const +{ + return QAccessible::Client; +} + +int QWebFrameAccessible::navigate(QAccessible::RelationFlag, int, QAccessibleInterface** target) const +{ + *target = 0; + return -1; +} + +QWebPageAccessible::QWebPageAccessible(QWebPage* page) + : QAccessibleObject(page) +{ +} + +QWebPage* QWebPageAccessible::page() const +{ + return qobject_cast<QWebPage*>(object()); +} + +QString QWebPageAccessible::text(QAccessible::Text t) const +{ + return QString(); +} + +QAccessibleInterface* QWebPageAccessible::parent() const +{ + return QAccessible::queryAccessibleInterface(object()->parent()); +} + +QAccessibleInterface* QWebPageAccessible::child(int index) const +{ + if (!index && page()->mainFrame()) + return new QWebFrameAccessible(page()->mainFrame()); + return 0; +} + +int QWebPageAccessible::childCount() const +{ + return page()->mainFrame() ? 1 : 0; +} + +int QWebPageAccessible::indexOfChild(const QAccessibleInterface*) const +{ + return 0; +} + +int QWebPageAccessible::navigate(QAccessible::RelationFlag, int, QAccessibleInterface** target) const +{ + *target = 0; + return -1; +} + +QAccessible::Role QWebPageAccessible::role() const +{ + return QAccessible::Client; +} + +QAccessible::State QWebPageAccessible::state() const +{ + return QAccessible::State(); +} + +QWebViewAccessible::QWebViewAccessible(QWebView* view) + : QAccessibleWidget(view, QAccessible::Document) +{ +} + +QWebView* QWebViewAccessible::view() const +{ + return qobject_cast<QWebView*>(object()); +} + +int QWebViewAccessible::childCount() const +{ + return view()->page() ? 1 : 0; +} + +QAccessibleInterface* QWebViewAccessible::child(int index) const +{ + if (!index && view()->page()) + return new QWebPageAccessible(view()->page()); + return 0; +} diff --git a/Source/WebKit/qt/Api/qwebviewaccessible_p.h b/Source/WebKit/qt/Api/qwebviewaccessible_p.h new file mode 100644 index 000000000..7cbf44870 --- /dev/null +++ b/Source/WebKit/qt/Api/qwebviewaccessible_p.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) + + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef qwebviewaccessible_p_h +#define qwebviewaccessible_p_h + +#include <qaccessible.h> +#include <qaccessibleobject.h> +#include <qaccessiblewidget.h> + +class QWebFrame; +class QWebPage; +class QWebView; + +/* + * Classes representing accessible objects for View, Frame and Page. + * + * Each of these just returns one child which lets the accessibility + * framwork navigate towards the actual contents in the frame. + */ + +class QWebFrameAccessible : public QAccessibleObject { +public: + QWebFrameAccessible(QWebFrame*); + + QWebFrame* frame() const; + + QAccessibleInterface* parent() const; + int childCount() const; + QAccessibleInterface* child(int index) const; + int indexOfChild(const QAccessibleInterface*) const; + int navigate(QAccessible::RelationFlag, int, QAccessibleInterface** target) const; + + QString text(QAccessible::Text) const; + QAccessible::Role role() const; + QAccessible::State state() const; +}; + +class QWebPageAccessible : public QAccessibleObject { +public: + QWebPageAccessible(QWebPage*); + + QWebPage* page() const; + + QAccessibleInterface* parent() const; + int childCount() const; + QAccessibleInterface* child(int index) const; + int indexOfChild(const QAccessibleInterface*) const; + int navigate(QAccessible::RelationFlag, int, QAccessibleInterface** target) const; + + QString text(QAccessible::Text) const; + QAccessible::Role role() const; + QAccessible::State state() const; +}; + +class QWebViewAccessible : public QAccessibleWidget { +public: + QWebViewAccessible(QWebView*); + + QWebView* view() const; + + int childCount() const; + QAccessibleInterface* child(int index) const; +}; + +#endif diff --git a/Source/WebKit/qt/ChangeLog b/Source/WebKit/qt/ChangeLog index 90d358893..dabbee48e 100644 --- a/Source/WebKit/qt/ChangeLog +++ b/Source/WebKit/qt/ChangeLog @@ -1,15 +1,221 @@ +2012-07-17 Gabor Ballabas <gaborb@inf.u-szeged.hu> + + [Qt][V8] Remove the V8 related codepaths and configuration + https://bugs.webkit.org/show_bug.cgi?id=90863 + + Reviewed by Simon Hausmann. + + * Api/qwebelement.cpp: + (setupScriptContext): + (QWebElement::evaluateJavaScript): + (convertWebElementVariantToJSValue): + (QtWebElementRuntime::initialize): + * Api/qwebframe.cpp: + (QWebFramePrivate::didClearWindowObject): + (QWebFramePrivate::addQtSenderToGlobalObject): + (QWebFrame::addToJavaScriptWindowObject): + (QWebFrame::evaluateJavaScript): + * WebCoreSupport/DumpRenderTreeSupportQt.cpp: + (convertNodeVariantToJSValue): + (QtDRTNodeRuntime::initialize): + (DumpRenderTreeSupportQt::javaScriptObjectsCount): + (DumpRenderTreeSupportQt::garbageCollectorCollect): + (DumpRenderTreeSupportQt::garbageCollectorCollectOnAlternateThread): + (DumpRenderTreeSupportQt::evaluateScriptInIsolatedWorld): + (DumpRenderTreeSupportQt::injectInternalsObject): + (DumpRenderTreeSupportQt::resetInternalsObject): + * WebCoreSupport/DumpRenderTreeSupportQt.h: + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::createDocumentLoader): + * WebCoreSupport/FrameLoaderClientQt.h: + (FrameLoaderClientQt): + * v8/ForwardingHeaders/v8-debug.h: Removed. + * v8/ForwardingHeaders/v8-preparser.h: Removed. + * v8/ForwardingHeaders/v8-profiler.h: Removed. + * v8/ForwardingHeaders/v8-testing.h: Removed. + * v8/ForwardingHeaders/v8.h: Removed. + * v8/ForwardingHeaders/v8stdint.h: Removed. + +2012-07-17 Vivek Galatage <vivekgalatage@gmail.com> + + Web Inspector: refactor InspectorController::connectFrontend() to accept InspectorFrontendChannel. + https://bugs.webkit.org/show_bug.cgi?id=91196 + + Reviewed by Pavel Feldman. + + Refactoring InspectorClients. InspectorClient::openInspectorFrontend + now returning the InspectorFrontendChannel. + + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore::InspectorClientQt::openInspectorFrontend): + (WebCore::InspectorClientQt::attachAndReplaceRemoteFrontend): + * WebCoreSupport/InspectorClientQt.h: + (InspectorClientQt): + +2012-07-17 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r122834. + http://trac.webkit.org/changeset/122834 + https://bugs.webkit.org/show_bug.cgi?id=91492 + + it broke the chromium (Requested by kkristof on #webkit). + + * Api/qwebelement.cpp: + (setupScriptContext): + (QWebElement::evaluateJavaScript): + (QtWebElementRuntime::initialize): + * Api/qwebframe.cpp: + (QWebFramePrivate::didClearWindowObject): + (QWebFrame::addToJavaScriptWindowObject): + (QWebFrame::evaluateJavaScript): + * WebCoreSupport/DumpRenderTreeSupportQt.cpp: + (QtDRTNodeRuntime::initialize): + (DumpRenderTreeSupportQt::javaScriptObjectsCount): + (DumpRenderTreeSupportQt::garbageCollectorCollect): + (DumpRenderTreeSupportQt::garbageCollectorCollectOnAlternateThread): + (DumpRenderTreeSupportQt::evaluateScriptInIsolatedWorld): + (DumpRenderTreeSupportQt::injectInternalsObject): + (DumpRenderTreeSupportQt::resetInternalsObject): + * WebCoreSupport/DumpRenderTreeSupportQt.h: + (Bindings): + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore): + (WebCore::FrameLoaderClientQt::didCreateScriptContext): + (WebCore::FrameLoaderClientQt::willReleaseScriptContext): + (WebCore::FrameLoaderClientQt::didCreateIsolatedScriptContext): + (WebCore::FrameLoaderClientQt::createDocumentLoader): + * WebCoreSupport/FrameLoaderClientQt.h: + (FrameLoaderClientQt): + (WebCore::FrameLoaderClientQt::allowScriptExtension): + * v8/ForwardingHeaders/v8-debug.h: Added. + * v8/ForwardingHeaders/v8-preparser.h: Added. + * v8/ForwardingHeaders/v8-profiler.h: Added. + * v8/ForwardingHeaders/v8-testing.h: Added. + * v8/ForwardingHeaders/v8.h: Added. + * v8/ForwardingHeaders/v8stdint.h: Added. + +2012-07-17 Gabor Ballabas <gaborb@inf.u-szeged.hu> + + [Qt][V8] Remove the V8 related codepaths and configuration + https://bugs.webkit.org/show_bug.cgi?id=90863 + + Reviewed by Simon Hausmann. + + * Api/qwebelement.cpp: + (setupScriptContext): + (QWebElement::evaluateJavaScript): + (convertWebElementVariantToJSValue): + (QtWebElementRuntime::initialize): + * Api/qwebframe.cpp: + (QWebFramePrivate::didClearWindowObject): + (QWebFramePrivate::addQtSenderToGlobalObject): + (QWebFrame::addToJavaScriptWindowObject): + (QWebFrame::evaluateJavaScript): + * WebCoreSupport/DumpRenderTreeSupportQt.cpp: + (convertNodeVariantToJSValue): + (QtDRTNodeRuntime::initialize): + (DumpRenderTreeSupportQt::javaScriptObjectsCount): + (DumpRenderTreeSupportQt::garbageCollectorCollect): + (DumpRenderTreeSupportQt::garbageCollectorCollectOnAlternateThread): + (DumpRenderTreeSupportQt::evaluateScriptInIsolatedWorld): + (DumpRenderTreeSupportQt::injectInternalsObject): + (DumpRenderTreeSupportQt::resetInternalsObject): + * WebCoreSupport/DumpRenderTreeSupportQt.h: + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::createDocumentLoader): + * WebCoreSupport/FrameLoaderClientQt.h: + (FrameLoaderClientQt): + * v8/ForwardingHeaders/v8-debug.h: Removed. + * v8/ForwardingHeaders/v8-preparser.h: Removed. + * v8/ForwardingHeaders/v8-profiler.h: Removed. + * v8/ForwardingHeaders/v8-testing.h: Removed. + * v8/ForwardingHeaders/v8.h: Removed. + * v8/ForwardingHeaders/v8stdint.h: Removed. + 2012-07-16 Simon Hausmann <simon.hausmann@nokia.com> [Qt] Fix inconsistent DLL linkage on Windows with WebKit1 https://bugs.webkit.org/show_bug.cgi?id=91375 - Reviewed by NOBODY (OOPS!). + Reviewed by Laszlo Gombos. Export QWebHistoryItemPrivate as required for tests. Unfortunately we cannot use Q_AUTOTEST_EXPORT outside of Qt. * Api/qwebhistory_p.h: +2012-07-16 Zoltan Horvath <zoltan@webkit.org> + + [Qt] Change NativeImagePtr from QPixmap* to QImage* + https://bugs.webkit.org/show_bug.cgi?id=88785 + + Reviewed by Simon Hausmann. + + Since we use raster engine there is no difference between QPixmap and QImage, so we are going + to use QImage everywhere where it is possible. This refactoring contains the change of the + NativeImagePtr typedef from QPixmap* to QImage* and covers the related modifications. + + Part of the change is similar to Viatcheslav Ostapenko's internal work. + + Covered by existing tests. + + * Api/qwebframe.cpp: + (QWebHitTestResultPrivate::QWebHitTestResultPrivate): + * Api/qwebhistory.cpp: + (QWebHistoryItem::icon): + * Api/qwebsettings.cpp: + (QWebSettings::iconForUrl): + (QWebSettings::setWebGraphic): + (QWebSettings::webGraphic): + * WebCoreSupport/DragClientQt.cpp: + (WebCore::DragClientQt::startDrag): + * WebCoreSupport/InitWebCoreQt.cpp: + (WebCore::initializeWebCoreQt): + +2012-07-16 Frederik Gladhorn <frederik.gladhorn@nokia.com> + + Accessible Widget for QWebView + https://bugs.webkit.org/show_bug.cgi?id=91073 + + Added classes that allow navigation to the web view widget. + This is the glue to later access webkit's accessible objects + though the Qt accessibility framework. + + Reviewed by Simon Hausmann. + + * Api/qwebview.cpp: + (QWebView::QWebView): + * Api/qwebviewaccessible.cpp: Added. + (accessibleInterfaceFactory): + (QWebFrameAccessible::QWebFrameAccessible): + (QWebFrameAccessible::frame): + (QWebFrameAccessible::parent): + (QWebFrameAccessible::text): + (QWebFrameAccessible::childCount): + (QWebFrameAccessible::child): + (QWebFrameAccessible::indexOfChild): + (QWebFrameAccessible::state): + (QWebFrameAccessible::role): + (QWebFrameAccessible::navigate): + (QWebPageAccessible::QWebPageAccessible): + (QWebPageAccessible::page): + (QWebPageAccessible::text): + (QWebPageAccessible::parent): + (QWebPageAccessible::child): + (QWebPageAccessible::childCount): + (QWebPageAccessible::indexOfChild): + (QWebPageAccessible::navigate): + (QWebPageAccessible::role): + (QWebPageAccessible::state): + (QWebViewAccessible::QWebViewAccessible): + (QWebViewAccessible::view): + (QWebViewAccessible::childCount): + (QWebViewAccessible::child): + * Api/qwebviewaccessible_p.h: Added. + (QWebFrameAccessible): + (QWebPageAccessible): + (QWebViewAccessible): + 2012-07-12 Huang Dongsung <luxtella@company100.net> [Qt] Increase the drawing performance by merging dirty rects. diff --git a/Source/WebKit/qt/WebCoreSupport/DragClientQt.cpp b/Source/WebKit/qt/WebCoreSupport/DragClientQt.cpp index cb6328340..8b648c19e 100644 --- a/Source/WebKit/qt/WebCoreSupport/DragClientQt.cpp +++ b/Source/WebKit/qt/WebCoreSupport/DragClientQt.cpp @@ -97,9 +97,9 @@ void DragClientQt::startDrag(DragImageRef dragImage, const IntPoint&, const IntP if (view) { QDrag* drag = new QDrag(view); if (dragImage) - drag->setPixmap(*dragImage); + drag->setPixmap(QPixmap::fromImage(*dragImage)); else if (clipboardData && clipboardData->hasImage()) - drag->setPixmap(qvariant_cast<QPixmap>(clipboardData->imageData())); + drag->setPixmap(QPixmap::fromImage(qvariant_cast<QImage>(clipboardData->imageData()))); DragOperation dragOperationMask = clipboard->sourceOperation(); drag->setMimeData(clipboardData); Qt::DropAction actualDropAction = drag->exec(dragOperationsToDropActions(dragOperationMask)); diff --git a/Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp b/Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp index 1492c395e..d6fa62722 100644 --- a/Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp +++ b/Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp @@ -23,9 +23,7 @@ #include "config.h" #include "DumpRenderTreeSupportQt.h" -#if USE(JSC) #include "APICast.h" -#endif #include "ApplicationCacheStorage.h" #include "CSSComputedStyleDeclaration.h" #include "ChromeClientQt.h" @@ -44,14 +42,9 @@ #include "Frame.h" #include "FrameLoaderClientQt.h" #include "FrameView.h" -#if USE(JSC) #include "GCController.h" #include "JSNode.h" #include "qt_runtime.h" -#elif USE(V8) -#include "V8GCController.h" -#include "V8Proxy.h" -#endif #include "GeolocationClient.h" #include "GeolocationClientMock.h" #include "GeolocationController.h" @@ -163,7 +156,6 @@ QDRTNode& QDRTNode::operator=(const QDRTNode& other) return *this; } -#if USE(JSC) QDRTNode QtDRTNodeRuntime::create(WebCore::Node* node) { return QDRTNode(node); @@ -185,7 +177,6 @@ static JSC::JSValue convertNodeVariantToJSValue(JSC::ExecState* exec, WebCore::J { return toJS(exec, globalObject, QtDRTNodeRuntime::get(variant.value<QDRTNode>())); } -#endif void QtDRTNodeRuntime::initialize() { @@ -193,10 +184,8 @@ void QtDRTNodeRuntime::initialize() if (initialized) return; initialized = true; -#if USE(JSC) int id = qRegisterMetaType<QDRTNode>(); JSC::Bindings::registerCustomType(id, convertJSValueToNodeVariant, convertNodeVariantToJSValue); -#endif } DumpRenderTreeSupportQt::DumpRenderTreeSupportQt() @@ -384,31 +373,17 @@ void DumpRenderTreeSupportQt::clearFrameName(QWebFrame* frame) int DumpRenderTreeSupportQt::javaScriptObjectsCount() { -#if USE(JSC) return JSDOMWindowBase::commonJSGlobalData()->heap.globalObjectCount(); -#elif USE(V8) - // FIXME: Find a way to do this using V8. - return 1; -#endif } void DumpRenderTreeSupportQt::garbageCollectorCollect() { -#if USE(JSC) gcController().garbageCollectNow(); -#elif USE(V8) - v8::V8::LowMemoryNotification(); -#endif } void DumpRenderTreeSupportQt::garbageCollectorCollectOnAlternateThread(bool waitUntilDone) { -#if USE(JSC) gcController().garbageCollectOnAlternateThreadForDebugging(waitUntilDone); -#elif USE(V8) - // FIXME: Find a way to do this using V8. - garbageCollectorCollect(); -#endif } int DumpRenderTreeSupportQt::pageNumberForElementById(QWebFrame* frame, const QString& id, float width, float height) @@ -893,15 +868,7 @@ void DumpRenderTreeSupportQt::evaluateScriptInIsolatedWorld(QWebFrame* frame, in if (!proxy) return; -#if USE(JSC) proxy->executeScriptInWorld(scriptWorld->world(), script, true); -#elif USE(V8) - ScriptSourceCode source(script); - Vector<ScriptSourceCode> sources; - sources.append(source); - Vector<ScriptValue> result; - proxy->evaluateInIsolatedWorld(0, sources, &result); -#endif } QString DumpRenderTreeSupportQt::pageSizeAndMarginsInPixels(QWebFrame* frame, int pageIndex, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft) @@ -1095,7 +1062,6 @@ QString DumpRenderTreeSupportQt::layerTreeAsText(QWebFrame* frame) void DumpRenderTreeSupportQt::injectInternalsObject(QWebFrame* frame) { WebCore::Frame* coreFrame = QWebFramePrivate::core(frame); -#if USE(JSC) JSDOMWindow* window = toJSDOMWindow(coreFrame, mainThreadNormalWorld()); Q_ASSERT(window); @@ -1105,23 +1071,16 @@ void DumpRenderTreeSupportQt::injectInternalsObject(QWebFrame* frame) JSContextRef context = toRef(exec); WebCoreTestSupport::injectInternalsObject(context); -#elif USE(V8) - v8::HandleScope handleScope; - WebCoreTestSupport::injectInternalsObject(V8Proxy::mainWorldContext(coreFrame)); -#endif } void DumpRenderTreeSupportQt::injectInternalsObject(JSContextRef context) { -#if USE(JSC) WebCoreTestSupport::injectInternalsObject(context); -#endif } void DumpRenderTreeSupportQt::resetInternalsObject(QWebFrame* frame) { WebCore::Frame* coreFrame = QWebFramePrivate::core(frame); -#if USE(JSC) JSDOMWindow* window = toJSDOMWindow(coreFrame, mainThreadNormalWorld()); Q_ASSERT(window); @@ -1131,10 +1090,6 @@ void DumpRenderTreeSupportQt::resetInternalsObject(QWebFrame* frame) JSContextRef context = toRef(exec); WebCoreTestSupport::resetInternalsObject(context); -#elif USE(V8) - v8::HandleScope handleScope; - WebCoreTestSupport::resetInternalsObject(V8Proxy::mainWorldContext(coreFrame)); -#endif } QImage DumpRenderTreeSupportQt::paintPagesWithBoundaries(QWebFrame* qframe) diff --git a/Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h b/Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h index 21564e222..e0c868081 100644 --- a/Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h +++ b/Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h @@ -34,20 +34,11 @@ class Text; class Node; } - -#if defined(WTF_USE_V8) && WTF_USE_V8 -namespace V8 { -namespace Bindings { -class QtDRTNodeRuntime; -} -} -#else namespace JSC { namespace Bindings { class QtDRTNodeRuntime; } } -#endif class QWebElement; class QWebFrame; @@ -74,11 +65,7 @@ private: friend class DumpRenderTreeSupportQt; -#if defined(WTF_USE_V8) && WTF_USE_V8 - friend class V8::Bindings::QtDRTNodeRuntime; -#else friend class QtDRTNodeRuntime; -#endif WebCore::Node* m_node; }; diff --git a/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp b/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp index 70f29366e..a2c3cb210 100644 --- a/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp +++ b/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp @@ -50,9 +50,7 @@ #if ENABLE(ICONDATABASE) #include "IconDatabaseClientQt.h" #endif -#if USE(JSC) #include "JSDOMWindowBase.h" -#endif #include "MIMETypeRegistry.h" #include "MouseEvent.h" #include "NotImplemented.h" @@ -69,9 +67,6 @@ #include "ResourceResponse.h" #include "ScriptController.h" #include "Settings.h" -#if USE(V8) -#include "V8DOMWindow.h" -#endif #include "ViewportArguments.h" #include "WebEventConversion.h" @@ -390,17 +385,6 @@ void FrameLoaderClientQt::dispatchDidChangeLocationWithinPage() m_webFrame->page()->d->updateNavigationActions(); } -#if USE(V8) -void FrameLoaderClientQt::didCreateScriptContext(v8::Handle<v8::Context>, int, int) -{ -} -void FrameLoaderClientQt::willReleaseScriptContext(v8::Handle<v8::Context>, int) -{ -} -void FrameLoaderClientQt::didCreateIsolatedScriptContext() -{ -} -#endif void FrameLoaderClientQt::dispatchDidPushStateWithinPage() { @@ -989,12 +973,7 @@ WTF::PassRefPtr<WebCore::DocumentLoader> FrameLoaderClientQt::createDocumentLoad // Use the default timeout interval for JS as the HTML tokenizer delay. This ensures // that long-running JavaScript will still allow setHtml() to be synchronous, while // still giving a reasonable timeout to prevent deadlock. -#if USE(JSC) double delay = JSDOMWindowBase::commonJSGlobalData()->timeoutChecker.timeoutInterval() / 1000.0f; -#elif USE(V8) - // FIXME: Hard coded for now. - double delay = 10000 / 1000.0f; -#endif m_frame->page()->setCustomHTMLTokenizerTimeDelay(delay); } else m_frame->page()->setCustomHTMLTokenizerTimeDelay(-1); diff --git a/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h b/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h index d123b56c8..781971d15 100644 --- a/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h +++ b/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h @@ -218,21 +218,6 @@ public: virtual void documentElementAvailable(); virtual void didPerformFirstNavigation() const; -#if USE(V8) - // A frame's V8 context was created or destroyed. - virtual void didCreateScriptContext(v8::Handle<v8::Context>, int, int); - virtual void willReleaseScriptContext(v8::Handle<v8::Context>, int); - - // A context untied to a frame was created (through evaluateInIsolatedWorld). - // This context is not tied to the lifetime of its frame, and is destroyed - // in garbage collection. - virtual void didCreateIsolatedScriptContext(); - - // Returns true if we should allow the given V8 extension to be added to - // the script context at the currently loading page and given extension group. - virtual bool allowScriptExtension(const String& extensionName, int extensionGroup, int worldID) { return false; } -#endif - virtual void registerForIconNotification(bool); QString chooseFile(const QString& oldFile); diff --git a/Source/WebKit/qt/WebCoreSupport/InitWebCoreQt.cpp b/Source/WebKit/qt/WebCoreSupport/InitWebCoreQt.cpp index 5ac449d5d..c63ccb042 100644 --- a/Source/WebKit/qt/WebCoreSupport/InitWebCoreQt.cpp +++ b/Source/WebKit/qt/WebCoreSupport/InitWebCoreQt.cpp @@ -83,9 +83,9 @@ void initializeWebCoreQt() #endif // QWebSettings::SearchCancelButtonGraphic - Image::setPlatformResource("searchCancelButton", QApplication::style()->standardPixmap(QStyle::SP_DialogCloseButton)); + Image::setPlatformResource("searchCancelButton", QApplication::style()->standardPixmap(QStyle::SP_DialogCloseButton).toImage()); // QWebSettings::SearchCancelButtonPressedGraphic - Image::setPlatformResource("searchCancelButtonPressed", QApplication::style()->standardPixmap(QStyle::SP_DialogCloseButton)); + Image::setPlatformResource("searchCancelButtonPressed", QApplication::style()->standardPixmap(QStyle::SP_DialogCloseButton).toImage()); initialized = true; } diff --git a/Source/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp b/Source/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp index 4b9709d22..73f6dd4a4 100644 --- a/Source/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp +++ b/Source/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp @@ -201,8 +201,9 @@ void InspectorClientQt::inspectorDestroyed() } -void InspectorClientQt::openInspectorFrontend(WebCore::InspectorController* inspectorController) +WebCore::InspectorFrontendChannel* InspectorClientQt::openInspectorFrontend(WebCore::InspectorController* inspectorController) { + WebCore::InspectorFrontendChannel* frontendChannel = 0; #if ENABLE(INSPECTOR) OwnPtr<QWebView> inspectorView = adoptPtr(new QWebView); // FIXME: Where does inspectorPage get deleted? @@ -212,7 +213,7 @@ void InspectorClientQt::openInspectorFrontend(WebCore::InspectorController* insp QWebInspector* inspector = m_inspectedWebPage->d->getOrCreateInspector(); // Remote frontend was attached. if (m_remoteFrontEndChannel) - return; + return 0; // This is a known hook that allows changing the default URL for the // Web inspector. This is used for SDK purposes. Please keep this hook @@ -243,7 +244,9 @@ void InspectorClientQt::openInspectorFrontend(WebCore::InspectorController* insp // Web Inspector should not belong to any other page groups since it is a specialized debugger window. m_frontendWebPage->handle()->page->setGroupName("__WebInspectorPageGroup__"); + frontendChannel = this; #endif + return frontendChannel; } void InspectorClientQt::closeInspectorFrontend() @@ -271,7 +274,7 @@ void InspectorClientQt::attachAndReplaceRemoteFrontend(InspectorServerRequestHan { #if ENABLE(INSPECTOR) m_remoteFrontEndChannel = channel; - m_inspectedWebPage->d->inspectorController()->connectFrontend(); + m_inspectedWebPage->d->inspectorController()->connectFrontend(this); #endif } diff --git a/Source/WebKit/qt/WebCoreSupport/InspectorClientQt.h b/Source/WebKit/qt/WebCoreSupport/InspectorClientQt.h index 6c7d00f85..49ba000ad 100644 --- a/Source/WebKit/qt/WebCoreSupport/InspectorClientQt.h +++ b/Source/WebKit/qt/WebCoreSupport/InspectorClientQt.h @@ -31,6 +31,7 @@ #define InspectorClientQt_h #include "InspectorClient.h" +#include "InspectorFrontendChannel.h" #include "InspectorFrontendClientLocal.h" #include <QtCore/QString> #include <wtf/Forward.h> @@ -45,13 +46,13 @@ class InspectorFrontendClientQt; class InspectorServerRequestHandlerQt; class Page; -class InspectorClientQt : public InspectorClient { +class InspectorClientQt : public InspectorClient, public InspectorFrontendChannel { public: InspectorClientQt(QWebPage*); virtual void inspectorDestroyed(); - virtual void openInspectorFrontend(WebCore::InspectorController*); + virtual WebCore::InspectorFrontendChannel* openInspectorFrontend(WebCore::InspectorController*); virtual void closeInspectorFrontend(); virtual void bringFrontendToFront(); diff --git a/Source/WebKit/qt/v8/ForwardingHeaders/v8-debug.h b/Source/WebKit/qt/v8/ForwardingHeaders/v8-debug.h deleted file mode 100644 index e6bfdb784..000000000 --- a/Source/WebKit/qt/v8/ForwardingHeaders/v8-debug.h +++ /dev/null @@ -1 +0,0 @@ -#include <private/v8-debug.h> diff --git a/Source/WebKit/qt/v8/ForwardingHeaders/v8-preparser.h b/Source/WebKit/qt/v8/ForwardingHeaders/v8-preparser.h deleted file mode 100644 index 7198b74ff..000000000 --- a/Source/WebKit/qt/v8/ForwardingHeaders/v8-preparser.h +++ /dev/null @@ -1 +0,0 @@ -#include <private/v8-preparser.h> diff --git a/Source/WebKit/qt/v8/ForwardingHeaders/v8-profiler.h b/Source/WebKit/qt/v8/ForwardingHeaders/v8-profiler.h deleted file mode 100644 index 37fbebd5b..000000000 --- a/Source/WebKit/qt/v8/ForwardingHeaders/v8-profiler.h +++ /dev/null @@ -1 +0,0 @@ -#include <private/v8-profiler.h> diff --git a/Source/WebKit/qt/v8/ForwardingHeaders/v8-testing.h b/Source/WebKit/qt/v8/ForwardingHeaders/v8-testing.h deleted file mode 100644 index d62f8f904..000000000 --- a/Source/WebKit/qt/v8/ForwardingHeaders/v8-testing.h +++ /dev/null @@ -1 +0,0 @@ -#include <private/v8-testing.h> diff --git a/Source/WebKit/qt/v8/ForwardingHeaders/v8.h b/Source/WebKit/qt/v8/ForwardingHeaders/v8.h deleted file mode 100644 index 195f5fbe5..000000000 --- a/Source/WebKit/qt/v8/ForwardingHeaders/v8.h +++ /dev/null @@ -1 +0,0 @@ -#include <private/v8.h> diff --git a/Source/WebKit/qt/v8/ForwardingHeaders/v8stdint.h b/Source/WebKit/qt/v8/ForwardingHeaders/v8stdint.h deleted file mode 100644 index 850e67052..000000000 --- a/Source/WebKit/qt/v8/ForwardingHeaders/v8stdint.h +++ /dev/null @@ -1 +0,0 @@ -#include <private/v8stdint.h> diff --git a/Source/WebKit/win/ChangeLog b/Source/WebKit/win/ChangeLog index 889e24c9b..e836a123e 100644 --- a/Source/WebKit/win/ChangeLog +++ b/Source/WebKit/win/ChangeLog @@ -1,3 +1,18 @@ +2012-07-17 Vivek Galatage <vivekgalatage@gmail.com> + + Web Inspector: refactor InspectorController::connectFrontend() to accept InspectorFrontendChannel. + https://bugs.webkit.org/show_bug.cgi?id=91196 + + Reviewed by Pavel Feldman. + + Refactoring InspectorClients. InspectorClient::openInspectorFrontend + now returning the InspectorFrontendChannel. + + * WebCoreSupport/WebInspectorClient.cpp: + (WebInspectorClient::openInspectorFrontend): + * WebCoreSupport/WebInspectorClient.h: + (WebInspectorClient): + 2012-07-14 Eric Carlson <eric.carlson@apple.com> Enable AVCF hardware video decoding diff --git a/Source/WebKit/win/WebCoreSupport/WebInspectorClient.cpp b/Source/WebKit/win/WebCoreSupport/WebInspectorClient.cpp index 0355282c6..2eed79758 100644 --- a/Source/WebKit/win/WebCoreSupport/WebInspectorClient.cpp +++ b/Source/WebKit/win/WebCoreSupport/WebInspectorClient.cpp @@ -87,7 +87,7 @@ void WebInspectorClient::inspectorDestroyed() delete this; } -void WebInspectorClient::openInspectorFrontend(InspectorController* inspectorController) +WebCore::InspectorFrontendChannel* WebInspectorClient::openInspectorFrontend(InspectorController* inspectorController) { registerWindowClass(); @@ -96,21 +96,21 @@ void WebInspectorClient::openInspectorFrontend(InspectorController* inspectorCon 0, 0, 0, 0); if (!frontendHwnd) - return; + return 0; COMPtr<WebView> frontendWebView(AdoptCOM, WebView::createInstance()); if (FAILED(frontendWebView->setHostWindow((OLE_HANDLE)(ULONG64)frontendHwnd))) - return; + return 0; RECT rect; GetClientRect(frontendHwnd, &rect); if (FAILED(frontendWebView->initWithFrame(rect, 0, 0))) - return; + return 0; COMPtr<WebInspectorDelegate> delegate(AdoptCOM, WebInspectorDelegate::createInstance()); if (FAILED(frontendWebView->setUIDelegate(delegate.get()))) - return; + return 0; // Keep preferences separate from the rest of the client, making sure we are using expected preference values. // FIXME: It's crazy that we have to do this song and dance to end up with @@ -120,64 +120,65 @@ void WebInspectorClient::openInspectorFrontend(InspectorController* inspectorCon COMPtr<WebPreferences> tempPreferences(AdoptCOM, WebPreferences::createInstance()); COMPtr<IWebPreferences> iPreferences; if (FAILED(tempPreferences->initWithIdentifier(BString(L"WebInspectorPreferences"), &iPreferences))) - return; + return 0; COMPtr<WebPreferences> preferences(Query, iPreferences); if (!preferences) - return; + return 0; if (FAILED(preferences->setAutosaves(FALSE))) - return; + return 0; if (FAILED(preferences->setLoadsImagesAutomatically(TRUE))) - return; + return 0; if (FAILED(preferences->setAuthorAndUserStylesEnabled(TRUE))) - return; + return 0; if (FAILED(preferences->setAllowsAnimatedImages(TRUE))) - return; + return 0; if (FAILED(preferences->setLoadsImagesAutomatically(TRUE))) - return; + return 0; if (FAILED(preferences->setPlugInsEnabled(FALSE))) - return; + return 0; if (FAILED(preferences->setJavaEnabled(FALSE))) - return; + return 0; if (FAILED(preferences->setUserStyleSheetEnabled(FALSE))) - return; + return 0; if (FAILED(preferences->setTabsToLinks(FALSE))) - return; + return 0; if (FAILED(preferences->setMinimumFontSize(0))) - return; + return 0; if (FAILED(preferences->setMinimumLogicalFontSize(9))) - return; + return 0; if (FAILED(preferences->setFixedFontFamily(BString(L"Courier New")))) - return; + return 0; if (FAILED(preferences->setDefaultFixedFontSize(13))) - return; + return 0; if (FAILED(frontendWebView->setPreferences(preferences.get()))) - return; + return 0; frontendWebView->setProhibitsMainFrameScrolling(TRUE); HWND frontendWebViewHwnd; if (FAILED(frontendWebView->viewWindow(reinterpret_cast<OLE_HANDLE*>(&frontendWebViewHwnd)))) - return; + return 0; COMPtr<WebMutableURLRequest> request(AdoptCOM, WebMutableURLRequest::createInstance()); RetainPtr<CFURLRef> htmlURLRef(AdoptCF, CFBundleCopyResourceURL(getWebKitBundle(), CFSTR("inspector"), CFSTR("html"), CFSTR("inspector"))); if (!htmlURLRef) - return; + return 0; CFStringRef urlStringRef = ::CFURLGetString(htmlURLRef.get()); if (FAILED(request->initWithURL(BString(urlStringRef), WebURLRequestUseProtocolCachePolicy, 60))) - return; + return 0; if (FAILED(frontendWebView->topLevelFrame()->loadRequest(request.get()))) - return; + return 0; m_frontendPage = core(frontendWebView.get()); OwnPtr<WebInspectorFrontendClient> frontendClient = adoptPtr(new WebInspectorFrontendClient(m_inspectedWebView, m_inspectedWebViewHwnd, frontendHwnd, frontendWebView, frontendWebViewHwnd, this, createFrontendSettings())); m_frontendClient = frontendClient.get(); m_frontendPage->inspectorController()->setInspectorFrontendClient(frontendClient.release()); m_frontendHwnd = frontendHwnd; + return this; } void WebInspectorClient::closeInspectorFrontend() diff --git a/Source/WebKit/win/WebCoreSupport/WebInspectorClient.h b/Source/WebKit/win/WebCoreSupport/WebInspectorClient.h index 8224b8879..e34333d24 100644 --- a/Source/WebKit/win/WebCoreSupport/WebInspectorClient.h +++ b/Source/WebKit/win/WebCoreSupport/WebInspectorClient.h @@ -31,6 +31,7 @@ #include <WebCore/COMPtr.h> #include <WebCore/InspectorClient.h> +#include <WebCore/InspectorFrontendChannel.h> #include <WebCore/InspectorFrontendClientLocal.h> #include <WebCore/PlatformString.h> #include <WebCore/WindowMessageListener.h> @@ -50,14 +51,14 @@ class WebInspectorFrontendClient; class WebNodeHighlight; class WebView; -class WebInspectorClient : public WebCore::InspectorClient { +class WebInspectorClient : public WebCore::InspectorClient, public WebCore::InspectorFrontendChannel { public: WebInspectorClient(WebView*); // InspectorClient virtual void inspectorDestroyed(); - virtual void openInspectorFrontend(WebCore::InspectorController*); + virtual WebCore::InspectorFrontendChannel* openInspectorFrontend(WebCore::InspectorController*); virtual void closeInspectorFrontend(); virtual void bringFrontendToFront(); diff --git a/Source/WebKit/wince/ChangeLog b/Source/WebKit/wince/ChangeLog index 2fc0e425c..714aefa2c 100644 --- a/Source/WebKit/wince/ChangeLog +++ b/Source/WebKit/wince/ChangeLog @@ -1,3 +1,18 @@ +2012-07-17 Vivek Galatage <vivekgalatage@gmail.com> + + Web Inspector: refactor InspectorController::connectFrontend() to accept InspectorFrontendChannel. + https://bugs.webkit.org/show_bug.cgi?id=91196 + + Reviewed by Pavel Feldman. + + Refactoring InspectorClients. InspectorClient::openInspectorFrontend + now returning the InspectorFrontendChannel. + + * WebCoreSupport/InspectorClientWinCE.cpp: + (WebKit::InspectorClientWinCE::openInspectorFrontend): + * WebCoreSupport/InspectorClientWinCE.h: + (InspectorClientWinCE): + 2012-05-31 Hajime Morrita <morrita@chromium.org> REGRESSION(r117572): editing/spelling/spellcheck-async-remove-frame.html crashes on Mac diff --git a/Source/WebKit/wince/WebCoreSupport/InspectorClientWinCE.cpp b/Source/WebKit/wince/WebCoreSupport/InspectorClientWinCE.cpp index 5bb34ef8c..360f61a17 100644 --- a/Source/WebKit/wince/WebCoreSupport/InspectorClientWinCE.cpp +++ b/Source/WebKit/wince/WebCoreSupport/InspectorClientWinCE.cpp @@ -45,9 +45,10 @@ void InspectorClientWinCE::inspectorDestroyed() delete this; } -void InspectorClientWinCE::openInspectorFrontend(InspectorController* controller) +InspectorFrontendChannel* InspectorClientWinCE::openInspectorFrontend(InspectorController* controller) { notImplemented(); + return 0; } void InspectorClientWinCE::closeInspectorFrontend() diff --git a/Source/WebKit/wince/WebCoreSupport/InspectorClientWinCE.h b/Source/WebKit/wince/WebCoreSupport/InspectorClientWinCE.h index dfd82303a..d86aaae91 100644 --- a/Source/WebKit/wince/WebCoreSupport/InspectorClientWinCE.h +++ b/Source/WebKit/wince/WebCoreSupport/InspectorClientWinCE.h @@ -26,19 +26,20 @@ #define InspectorClientWinCE_h #include "InspectorClient.h" +#include "InspectorFrontendChannel.h" class WebView; namespace WebKit { -class InspectorClientWinCE : public WebCore::InspectorClient { +class InspectorClientWinCE : public WebCore::InspectorClient, public WebCore::InspectorFrontendChannel { public: InspectorClientWinCE(WebView* webView); ~InspectorClientWinCE(); virtual void inspectorDestroyed(); - virtual void openInspectorFrontend(WebCore::InspectorController*); + virtual WebCore::InspectorFrontendChannel* openInspectorFrontend(WebCore::InspectorController*); virtual void closeInspectorFrontend(); virtual void bringFrontendToFront(); diff --git a/Source/WebKit/wx/ChangeLog b/Source/WebKit/wx/ChangeLog index f0913c36c..7e68e4a80 100644 --- a/Source/WebKit/wx/ChangeLog +++ b/Source/WebKit/wx/ChangeLog @@ -1,3 +1,18 @@ +2012-07-17 Vivek Galatage <vivekgalatage@gmail.com> + + Web Inspector: refactor InspectorController::connectFrontend() to accept InspectorFrontendChannel. + https://bugs.webkit.org/show_bug.cgi?id=91196 + + Reviewed by Pavel Feldman. + + Refactoring InspectorClients. InspectorClient::openInspectorFrontend + now returning the InspectorFrontendChannel. + + * WebKitSupport/InspectorClientWx.cpp: + (WebCore::InspectorClientWx::openInspectorFrontend): + * WebKitSupport/InspectorClientWx.h: + (InspectorClientWx): + 2012-07-02 Benjamin Poulain <bpoulain@apple.com> Do not do any logging initialization when logging is disabled diff --git a/Source/WebKit/wx/WebKitSupport/InspectorClientWx.cpp b/Source/WebKit/wx/WebKitSupport/InspectorClientWx.cpp index 8a4e7927a..a7a5de7ca 100644 --- a/Source/WebKit/wx/WebKitSupport/InspectorClientWx.cpp +++ b/Source/WebKit/wx/WebKitSupport/InspectorClientWx.cpp @@ -47,9 +47,10 @@ void InspectorClientWx::inspectorDestroyed() notImplemented(); } -void InspectorClientWx::openInspectorFrontend(WebCore::InspectorController*) +InspectorFrontendChannel* InspectorClientWx::openInspectorFrontend(WebCore::InspectorController*) { notImplemented(); + return 0; } void InspectorClientWx::closeInspectorFrontend() diff --git a/Source/WebKit/wx/WebKitSupport/InspectorClientWx.h b/Source/WebKit/wx/WebKitSupport/InspectorClientWx.h index e10e67b2e..7c5d4343a 100644 --- a/Source/WebKit/wx/WebKitSupport/InspectorClientWx.h +++ b/Source/WebKit/wx/WebKitSupport/InspectorClientWx.h @@ -27,20 +27,21 @@ #define InspectorClientWx_h #include "InspectorClient.h" +#include "InspectorFrontendChannel.h" #include <wtf/Forward.h> namespace WebCore { class Page; -class InspectorClientWx : public InspectorClient { +class InspectorClientWx : public InspectorClient, public InspectorFrontendChannel { public: InspectorClientWx(); ~InspectorClientWx(); virtual void inspectorDestroyed(); - virtual void openInspectorFrontend(WebCore::InspectorController*); + virtual InspectorFrontendChannel* openInspectorFrontend(WebCore::InspectorController*); virtual void closeInspectorFrontend(); virtual void bringFrontendToFront(); diff --git a/Source/WebKit2/CMakeLists.txt b/Source/WebKit2/CMakeLists.txt index 1da9a6ac8..c8d1c35fc 100644 --- a/Source/WebKit2/CMakeLists.txt +++ b/Source/WebKit2/CMakeLists.txt @@ -55,6 +55,7 @@ SET(WebKit2_INCLUDE_DIRECTORIES "${WEBCORE_DIR}/editing" "${WEBCORE_DIR}/history" "${WEBCORE_DIR}/html" + "${WEBCORE_DIR}/html/shadow" "${WEBCORE_DIR}/html/track" "${WEBCORE_DIR}/inspector" "${WEBCORE_DIR}/loader" diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog index f9f6f1d91..42222d87c 100644 --- a/Source/WebKit2/ChangeLog +++ b/Source/WebKit2/ChangeLog @@ -1,3 +1,355 @@ +2012-07-18 Zeno Albisser <zeno@webkit.org> + + [Qt][WK2] Caching of ShareableSurfaces breaks tiling. + https://bugs.webkit.org/show_bug.cgi?id=91609 + + A ShareableSurface should only be cached, + when it is GraphicsSurface based. + + Reviewed by Kenneth Rohde Christiansen. + + * UIProcess/LayerTreeCoordinatorProxy.cpp: + (WebKit::LayerTreeCoordinatorProxy::updateTileForLayer): + * UIProcess/LayerTreeCoordinatorProxy.h: + (LayerTreeCoordinatorProxy): + +2012-07-18 Carlos Garcia Campos <cgarcia@igalia.com> + + [GTK] Fix a crash due to an invalid assert + https://bugs.webkit.org/show_bug.cgi?id=91614 + + Reviewed by Xan Lopez. + + In webkitWebViewBaseContainerAdd() there's + ASSERT(priv->inspectorView); that should be the opposite, since we + shoulnd't have an inspector view when the inspector view is added. + + * UIProcess/API/gtk/WebKitWebViewBase.cpp: + (webkitWebViewBaseContainerAdd): + +2012-07-18 Thiago Marcos P. Santos <thiago.santos@intel.com> + + [CMake] Make gtest a shared library + https://bugs.webkit.org/show_bug.cgi?id=90973 + + Reviewed by Daniel Bates. + + No need to link with gtest dependencies now since it is a shared library. + + * PlatformEfl.cmake: + +2012-07-18 YoungTaeck Song <youngtaeck.song@samsung.com> + + [WK2][EFL] Add a common code using Color instead of QColor + https://bugs.webkit.org/show_bug.cgi?id=91580 + + Reviewed by Simon Hausmann. + + This patch is a subset of Efl's UI_SIDE_COMPOSITING implementation. + drawBorder's argument is QColor. So add a common code using Color to be used by Efl. + + * UIProcess/texmap/LayerBackingStore.cpp: + (WebKit::LayerBackingStore::paintToTextureMapper): + +2012-07-17 Christophe Dumez <christophe.dumez@intel.com> + + [EFL] Replace 0 by NULL in public headers documentation + https://bugs.webkit.org/show_bug.cgi?id=91470 + + Reviewed by Dirk Pranke. + + Use NULL instead of 0 for pointer types in public + C headers. + + * UIProcess/API/efl/ewk_intent.h: + * UIProcess/API/efl/ewk_intent_service.h: + * UIProcess/API/efl/ewk_url_request.h: + * UIProcess/API/efl/ewk_url_response.h: + * UIProcess/API/efl/ewk_view.h: + * UIProcess/API/efl/ewk_web_resource.h: + +2012-07-17 Carlos Garcia Campos <cgarcia@igalia.com> + + [GTK] Don't use deprecated soup API in WebKit2APITests/TestResources + https://bugs.webkit.org/show_bug.cgi?id=91496 + + Reviewed by Martin Robinson. + + soup_message_headers_get() is deprecated, use + soup_message_headers_get_one() instead. + + * UIProcess/API/gtk/tests/TestResources.cpp: + (serverCallback): + +2012-07-17 Carlos Garcia Campos <cgarcia@igalia.com> + + [GTK] Fix a typo in WebKit2APITests/TestResources + https://bugs.webkit.org/show_bug.cgi?id=91495 + + Reviewed by Xan Lopez. + + * UIProcess/API/gtk/tests/TestResources.cpp: + (testWebResourceLoading): + (testWebResourceResponse): + (testWebResourceMimeType): + (testWebResourceActiveURI): + +2012-07-17 Vivek Galatage <vivekgalatage@gmail.com> + + Web Inspector: refactor InspectorController::connectFrontend() to accept InspectorFrontendChannel. + https://bugs.webkit.org/show_bug.cgi?id=91196 + + Reviewed by Pavel Feldman. + + Refactoring InspectorClients. InspectorClient::openInspectorFrontend + now returning the InspectorFrontendChannel. + + * WebProcess/WebCoreSupport/WebInspectorClient.cpp: + (WebKit::WebInspectorClient::openInspectorFrontend): + * WebProcess/WebCoreSupport/WebInspectorClient.h: + (WebInspectorClient): + +2012-07-17 Carlos Garcia Campos <cgarcia@igalia.com> + + [GTK] Paste primary selection when middle clicking in X11 WebKit2 + https://bugs.webkit.org/show_bug.cgi?id=91411 + + Reviewed by Xan Lopez. + + Handle middle click events to paste primary selection as expected + in any X11 application. + + * WebProcess/WebPage/WebPage.cpp: + (WebKit::handleMouseEvent): Call handleMousePressedEvent() for GTK+ + platform. + * WebProcess/WebPage/WebPage.h: + (WebPage): Add handleMousePressedEvent() for GTK+ platform. + * WebProcess/WebPage/gtk/WebPageGtk.cpp: + (WebKit::WebPage::handleMousePressedEvent): Handle middle click + events to paste primary selection like we do in WebKit1. + +2012-07-17 Ryuan Choi <ryuan.choi@samsung.com> + + [EFL] Move codes related to theme setting from Widget to RenderTheme + https://bugs.webkit.org/show_bug.cgi?id=89842 + + Reviewed by Kenneth Rohde Christiansen. + + * CMakeLists.txt: Added html/shadow to WebKit_INCLUDE_DIRECTORIES. + * WebProcess/WebPage/efl/WebPageEfl.cpp: + (WebKit::WebPage::setThemePath): Called RenderThemeEfl::setThemePath instead of setting theme in FrameView. + +2012-07-17 David Barr <davidbarr@chromium.org> + + Introduce ENABLE_CSS_IMAGE_ORIENTATION compile flag + https://bugs.webkit.org/show_bug.cgi?id=89055 + + Reviewed by Kent Tamura. + + The css3-images module is at candidate recommendation. + http://www.w3.org/TR/2012/CR-css3-images-20120417/#the-image-orientation + + Add a configuration option for CSS image-orientation support, disabling it by default. + + * Configurations/FeatureDefines.xcconfig: + +2012-07-16 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Add RegisterProtocolHandlerClient to the Modules/protocolhandler + https://bugs.webkit.org/show_bug.cgi?id=90940 + + Reviewed by Hajime Morita. + + As a step to let protocol handler be moved to the modules, RegisterProtocolHandlerClient needs + to be added to the Modules/protocolhandler. Because ChromeClient has some virtual functions for + protocol handlers, virtual functions should be moved to RegisterProtocolHandlerClient. + + In order to support this, WebRegisterProtocolHandlerClient class is added. However, this is not implemented yet. + In addition, existing virtual functions in WebChromeClient are moved to WebRegisterProtocolHandlerClient. + + * WebProcess/WebCoreSupport/WebChromeClient.h: + * WebProcess/WebCoreSupport/WebRegisterProtocolHandlerClient.h: Added. + (WebKit): + (WebRegisterProtoclHandlerClient): + (WebKit::WebRegisterProtoclHandlerClient::isProtocolHandlerRegistered): + (WebKit::WebRegisterProtoclHandlerClient::unregisterProtocolHandler): + +2012-07-16 Pete Williamson <petewil@google.com> + + Export the iconURL list to make it available to the Internals class for testing + https://bugs.webkit.org/show_bug.cgi?id=88665 + + Reviewed by Kent Tamura. + + * win/WebKit2.def: export the DocumentL::iconURLs function + +2012-07-16 Hajime Morrita <morrita@chromium.org> + + WebCore needs WEBCORE_TESTING macro to mark methods being exported for testing. + https://bugs.webkit.org/show_bug.cgi?id=90764 + + Reviewed by Adam Barth. + + Removed symbols which are now covered by WEBCORE_TESTING. + + * win/WebKit2.def: + * win/WebKit2CFLite.def: + +2012-07-16 Christophe Dumez <christophe.dumez@intel.com> + + [EFL][WK2] Implement decidePolicyForResponse in policy client + https://bugs.webkit.org/show_bug.cgi?id=91401 + + Reviewed by Kenneth Rohde Christiansen. + + Provide implementation for decidePolicyForResponse callback + in WebKit2 EFL's policy client. + + * UIProcess/API/efl/ewk_view_policy_client.cpp: + (decidePolicyForResponseCallback): + (ewk_view_policy_client_attach): + +2012-07-16 Ryuan Choi <ryuan.choi@samsung.com> + + [EFL][WK2] Add APIs to support theme. + https://bugs.webkit.org/show_bug.cgi?id=90107 + + Reviewed by Hajime Morita. + + RenderThemeEfl uses edj file to render native theme of form elements. + This patch provides default theme and a way to change edj theme file for + WebKit2/Efl. + + * PlatformEfl.cmake: + * UIProcess/API/efl/ewk_view.cpp: + (_Ewk_View_Private_Data): + (ewk_view_base_add): + (ewk_view_theme_set): + (ewk_view_theme_get): + * UIProcess/API/efl/ewk_view.h: + * UIProcess/WebPageProxy.h: + (WebPageProxy): + * UIProcess/efl/WebPageProxyEfl.cpp: + (WebKit::WebPageProxy::setThemePath): + * WebProcess/WebPage/WebPage.h: + * WebProcess/WebPage/WebPage.messages.in: + * WebProcess/WebPage/efl/WebPageEfl.cpp: + (WebKit::WebPage::setThemePath): + +2012-07-16 Kihong Kwon <kihong.kwon@samsung.com> + + Remove setController from BatteryClient + https://bugs.webkit.org/show_bug.cgi?id=90944 + + Reviewed by Adam Barth. + + Remove WebBatteryClient::setController function. + + * WebProcess/WebCoreSupport/WebBatteryClient.cpp: + * WebProcess/WebCoreSupport/WebBatteryClient.h: + (WebBatteryClient): + +2012-07-16 Christophe Dumez <christophe.dumez@intel.com> + + [EFL][WK2] Make Ewk_Navigation_Policy_Decision ref counted + https://bugs.webkit.org/show_bug.cgi?id=91343 + + Reviewed by Antonio Gomes. + + Make Ewk_Navigation_Policy_Decision ref counted so that the + client can make navigation policy decisions asynchronously + by ref'ing the Ewk_Navigation_Policy_Decision object passed + with the "policy,*" signals. + + * UIProcess/API/efl/ewk_navigation_policy_decision.cpp: + (_Ewk_Navigation_Policy_Decision): + (_Ewk_Navigation_Policy_Decision::_Ewk_Navigation_Policy_Decision): + (_Ewk_Navigation_Policy_Decision::~_Ewk_Navigation_Policy_Decision): + (ewk_navigation_policy_decision_ref): + (ewk_navigation_policy_decision_unref): + * UIProcess/API/efl/ewk_navigation_policy_decision.h: + * UIProcess/API/efl/ewk_view.h: + * UIProcess/API/efl/ewk_view_policy_client.cpp: + (decidePolicyForNavigationAction): + (decidePolicyForNewWindowAction): + +2012-07-16 Zoltan Horvath <zoltan@webkit.org> + + [Qt] Change NativeImagePtr from QPixmap* to QImage* + https://bugs.webkit.org/show_bug.cgi?id=88785 + + Reviewed by Simon Hausmann. + + Since we use raster engine there is no difference between QPixmap and QImage, so we are going + to use QImage everywhere where it is possible. This refactoring contains the change of the + NativeImagePtr typedef from QPixmap* to QImage* and covers the related modifications. + + Part of the change is similar to Viatcheslav Ostapenko's internal work. + + Covered by existing tests. + + * Shared/qt/ShareableBitmapQt.cpp: + (WebKit::ShareableBitmap::createImage): + * UIProcess/qt/QtWebIconDatabaseClient.cpp: + (WebKit::QtWebIconDatabaseClient::iconImageForPageURL): + * WebProcess/WebCoreSupport/qt/WebDragClientQt.cpp: + (WebKit::convertQImageToShareableBitmap): + (WebKit::WebDragClient::startDrag): + * WebProcess/WebPage/LayerTreeCoordinator/LayerTreeCoordinator.cpp: + (WebKit::LayerTreeCoordinator::adoptImageBackingStore): + +2012-07-16 Carlos Garcia Campos <cgarcia@igalia.com> + + Unreviewed. Fix make distcheck. + + * UIProcess/API/gtk/tests/GNUmakefile.am: Add test resources to + EXTRA_DIST. + +2012-07-15 Christophe Dumez <christophe.dumez@intel.com> + + [EFL][WK2] Define destructors for Ewk structures + https://bugs.webkit.org/show_bug.cgi?id=91338 + + Reviewed by Kentaro Hara. + + Add destructors to Ewk structures and move + memory freeing code from *_free() or *_unref() + functions to the destructors. + + * UIProcess/API/efl/ewk_intent.cpp: + (_Ewk_Intent::_Ewk_Intent): + (_Ewk_Intent): + (_Ewk_Intent::~_Ewk_Intent): + (ewk_intent_unref): + * UIProcess/API/efl/ewk_intent_service.cpp: + (_Ewk_Intent_Service): + (_Ewk_Intent_Service::~_Ewk_Intent_Service): + (ewk_intent_service_unref): + * UIProcess/API/efl/ewk_navigation_policy_decision.cpp: + (_Ewk_Navigation_Policy_Decision): + (_Ewk_Navigation_Policy_Decision::~_Ewk_Navigation_Policy_Decision): + (ewk_navigation_policy_decision_free): + * UIProcess/API/efl/ewk_url_request.cpp: + (_Ewk_Url_Request): + (_Ewk_Url_Request::~_Ewk_Url_Request): + (ewk_url_request_unref): + * UIProcess/API/efl/ewk_url_response.cpp: + (_Ewk_Url_Response): + (_Ewk_Url_Response::~_Ewk_Url_Response): + (ewk_url_response_unref): + * UIProcess/API/efl/ewk_view.cpp: + (_Ewk_View_Private_Data): + (_Ewk_View_Private_Data::~_Ewk_View_Private_Data): + (_ewk_view_priv_del): + * UIProcess/API/efl/ewk_web_error.cpp: + (_Ewk_Web_Error): + (_Ewk_Web_Error::~_Ewk_Web_Error): + (ewk_web_error_free): + * UIProcess/API/efl/ewk_web_resource.cpp: + (_Ewk_Web_Resource): + (_Ewk_Web_Resource::~_Ewk_Web_Resource): + (ewk_web_resource_unref): + 2012-07-14 Eric Carlson <eric.carlson@apple.com> Enable AVCF hardware video decoding diff --git a/Source/WebKit2/Configurations/FeatureDefines.xcconfig b/Source/WebKit2/Configurations/FeatureDefines.xcconfig index 7f95c3018..1fc82597c 100644 --- a/Source/WebKit2/Configurations/FeatureDefines.xcconfig +++ b/Source/WebKit2/Configurations/FeatureDefines.xcconfig @@ -42,6 +42,7 @@ ENABLE_CSS_BOX_DECORATION_BREAK = ENABLE_CSS_BOX_DECORATION_BREAK; ENABLE_CSS_EXCLUSIONS = ENABLE_CSS_EXCLUSIONS; ENABLE_CSS_FILTERS = ENABLE_CSS_FILTERS; ENABLE_CSS_SHADERS = ENABLE_CSS_SHADERS; +ENABLE_CSS_IMAGE_ORIENTATION = ; ENABLE_CSS_IMAGE_RESOLUTION = ; ENABLE_CSS_REGIONS = ENABLE_CSS_REGIONS; ENABLE_CSS_VARIABLES = ; @@ -134,4 +135,4 @@ ENABLE_WEB_TIMING = ; ENABLE_WORKERS = ENABLE_WORKERS; ENABLE_XSLT = ENABLE_XSLT; -FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS3_FLEXBOX) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_VARIABLES) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIALOG_ELEMENT) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LINK_PREFETCH) $(ENABLE_LINK_PRERENDER) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_TAG) $(ENABLE_MICRODATA) $(ENABLE_MUTATION_OBSERVERS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_TAG) $(ENABLE_QUOTA) $(ENABLE_REGISTER_PROTOCOL_HANDLER) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SVG) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TEXT_NOTIFICATIONS_ONLY) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_UNDO_MANAGER) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XSLT); +FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS3_FLEXBOX) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_VARIABLES) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIALOG_ELEMENT) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LINK_PREFETCH) $(ENABLE_LINK_PRERENDER) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_TAG) $(ENABLE_MICRODATA) $(ENABLE_MUTATION_OBSERVERS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_TAG) $(ENABLE_QUOTA) $(ENABLE_REGISTER_PROTOCOL_HANDLER) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SVG) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TEXT_NOTIFICATIONS_ONLY) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_UNDO_MANAGER) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XSLT); diff --git a/Source/WebKit2/Configurations/Version.xcconfig b/Source/WebKit2/Configurations/Version.xcconfig index d0b2d142f..c2637aa45 100644 --- a/Source/WebKit2/Configurations/Version.xcconfig +++ b/Source/WebKit2/Configurations/Version.xcconfig @@ -22,7 +22,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. MAJOR_VERSION = 537; -MINOR_VERSION = 1; +MINOR_VERSION = 2; TINY_VERSION = 0; FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION); diff --git a/Source/WebKit2/PlatformEfl.cmake b/Source/WebKit2/PlatformEfl.cmake index 9870e0e2e..db0e45914 100644 --- a/Source/WebKit2/PlatformEfl.cmake +++ b/Source/WebKit2/PlatformEfl.cmake @@ -156,6 +156,8 @@ LIST (APPEND WebProcess_LIBRARIES ${SQLITE_LIBRARIES} ) +ADD_DEFINITIONS(-DDEFAULT_THEME_PATH=\"${CMAKE_INSTALL_PREFIX}/${DATA_INSTALL_DIR}/themes\") + ADD_CUSTOM_TARGET(forwarding-headerEfl COMMAND ${PERL_EXECUTABLE} ${WEBKIT2_DIR}/Scripts/generate-forwarding-headers.pl ${WEBKIT2_DIR} ${DERIVED_SOURCES_WEBKIT2_DIR}/include efl ) @@ -186,12 +188,14 @@ INSTALL(FILES ${EWebKit2_HEADERS} DESTINATION include/${WebKit2_LIBRARY_NAME}-${ INCLUDE_DIRECTORIES(${THIRDPARTY_DIR}/gtest/include) SET(EWK2UnitTests_LIBRARIES + ${WTF_LIBRARY_NAME} ${JavaScriptCore_LIBRARY_NAME} ${WebCore_LIBRARY_NAME} ${WebKit2_LIBRARY_NAME} ${ECORE_LIBRARIES} ${ECORE_EVAS_LIBRARIES} ${EVAS_LIBRARIES} + gtest ) IF (ENABLE_GLIB_SUPPORT) @@ -204,7 +208,9 @@ ENDIF() SET(WEBKIT2_EFL_TEST_DIR "${WEBKIT2_DIR}/UIProcess/API/efl/tests") SET(TEST_RESOURCES_DIR ${WEBKIT2_EFL_TEST_DIR}/resources) -ADD_DEFINITIONS(-DTEST_RESOURCES_DIR=\"${TEST_RESOURCES_DIR}\") +ADD_DEFINITIONS(-DTEST_RESOURCES_DIR=\"${TEST_RESOURCES_DIR}\" + -DGTEST_LINKED_AS_SHARED_LIBRARY=1 +) ADD_LIBRARY(ewk2UnitTestUtils ${WEBKIT2_EFL_TEST_DIR}/UnitTestUtils/EWK2UnitTestBase.cpp @@ -225,6 +231,6 @@ IF (ENABLE_API_TESTS) ADD_EXECUTABLE(${testName} ${WEBKIT2_EFL_TEST_DIR}/${testName}.cpp) ADD_TEST(${testName} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${testName}) SET_TESTS_PROPERTIES(${testName} PROPERTIES TIMEOUT 60) - TARGET_LINK_LIBRARIES(${testName} ${EWK2UnitTests_LIBRARIES} ewk2UnitTestUtils gtest pthread) + TARGET_LINK_LIBRARIES(${testName} ${EWK2UnitTests_LIBRARIES} ewk2UnitTestUtils) ENDFOREACH () ENDIF () diff --git a/Source/WebKit2/Shared/qt/ShareableBitmapQt.cpp b/Source/WebKit2/Shared/qt/ShareableBitmapQt.cpp index a7ab8d4b3..b6ceb3e15 100644 --- a/Source/WebKit2/Shared/qt/ShareableBitmapQt.cpp +++ b/Source/WebKit2/Shared/qt/ShareableBitmapQt.cpp @@ -52,8 +52,8 @@ void ShareableBitmap::releaseSharedMemoryData(void* typelessBitmap) PassRefPtr<Image> ShareableBitmap::createImage() { - QPixmap* pixmap = new QPixmap(QPixmap::fromImage(createQImage())); - return BitmapImage::create(pixmap); + QImage* image = new QImage(createQImage()); + return BitmapImage::create(image); } PassOwnPtr<GraphicsContext> ShareableBitmap::createGraphicsContext() diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_intent.cpp b/Source/WebKit2/UIProcess/API/efl/ewk_intent.cpp index ba923ee0b..7322108be 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_intent.cpp +++ b/Source/WebKit2/UIProcess/API/efl/ewk_intent.cpp @@ -59,7 +59,14 @@ struct _Ewk_Intent { , action(0) , type(0) , service(0) + { } + + ~_Ewk_Intent() { + ASSERT(!__ref); + eina_stringshare_del(action); + eina_stringshare_del(type); + eina_stringshare_del(service); } }; @@ -90,9 +97,6 @@ void ewk_intent_unref(Ewk_Intent* intent) if (--intent->__ref) return; - eina_stringshare_del(intent->action); - eina_stringshare_del(intent->type); - eina_stringshare_del(intent->service); delete intent; #endif } diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_intent.h b/Source/WebKit2/UIProcess/API/efl/ewk_intent.h index fdcfe00d4..ae73c6ce5 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_intent.h +++ b/Source/WebKit2/UIProcess/API/efl/ewk_intent.h @@ -50,7 +50,7 @@ EAPI void ewk_intent_ref(Ewk_Intent *intent); /** * Decreases the reference count of the given object, possibly freeing it. * - * When the reference count it's reached 0, the intent is freed. + * When the reference count reaches 0, the intent is freed. * * @param intent the intent object to decrease the reference count */ @@ -103,7 +103,7 @@ EAPI const char *ewk_intent_service_get(const Ewk_Intent *intent); * * @param intent intent item to query. * - * @return @c Eina_List with suggested service URLs on success, or @c 0 on failure, + * @return @c Eina_List with suggested service URLs on success, or @c NULL on failure, * the Eina_List and its items should be freed after use. Use free() to free the * items. */ @@ -124,7 +124,7 @@ EAPI char *ewk_intent_extra_get(const Ewk_Intent *intent, const char *key); * * @param intent intent item to query. * - * @return @c Eina_List with names of extra metadata on success, or @c 0 on failure, + * @return @c Eina_List with names of extra metadata on success, or @c NULL on failure, * the Eina_List and its items should be freed after use. Use free() to free the * items. */ diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_intent_service.cpp b/Source/WebKit2/UIProcess/API/efl/ewk_intent_service.cpp index 9395f421f..18422b757 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_intent_service.cpp +++ b/Source/WebKit2/UIProcess/API/efl/ewk_intent_service.cpp @@ -62,6 +62,16 @@ struct _Ewk_Intent_Service { , title(0) , disposition(0) { } + + ~_Ewk_Intent_Service() + { + ASSERT(!__ref); + eina_stringshare_del(action); + eina_stringshare_del(type); + eina_stringshare_del(href); + eina_stringshare_del(title); + eina_stringshare_del(disposition); + } }; #define EWK_INTENT_SERVICE_WK_GET_OR_RETURN(service, wkService_, ...) \ @@ -91,11 +101,6 @@ void ewk_intent_service_unref(Ewk_Intent_Service* service) if (--service->__ref) return; - eina_stringshare_del(service->action); - eina_stringshare_del(service->type); - eina_stringshare_del(service->href); - eina_stringshare_del(service->title); - eina_stringshare_del(service->disposition); delete service; #endif } diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_intent_service.h b/Source/WebKit2/UIProcess/API/efl/ewk_intent_service.h index de22f6c4c..958e05448 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_intent_service.h +++ b/Source/WebKit2/UIProcess/API/efl/ewk_intent_service.h @@ -50,7 +50,7 @@ EAPI void ewk_intent_service_ref(Ewk_Intent_Service *service); /** * Decreases the reference count of the given object, possibly freeing it. * - * When the reference count it's reached 0, the intent service is freed. + * When the reference count reaches 0, the intent service is freed. * * @param service the intent service object to decrease the reference count */ diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_navigation_policy_decision.cpp b/Source/WebKit2/UIProcess/API/efl/ewk_navigation_policy_decision.cpp index a21649d34..ae725d74a 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_navigation_policy_decision.cpp +++ b/Source/WebKit2/UIProcess/API/efl/ewk_navigation_policy_decision.cpp @@ -40,6 +40,7 @@ using namespace WebKit; * @brief Contains the navigation policy decision data. */ struct _Ewk_Navigation_Policy_Decision { + unsigned int __ref; /**< the reference count of the object */ WKRetainPtr<WKFramePolicyListenerRef> listener; bool actedUponByClient; Ewk_Navigation_Type navigationType; @@ -49,7 +50,8 @@ struct _Ewk_Navigation_Policy_Decision { const char* frameName; _Ewk_Navigation_Policy_Decision(WKFramePolicyListenerRef _listener, Ewk_Navigation_Type _navigationType, Event_Mouse_Button _mouseButton, Event_Modifier_Keys _modifiers, Ewk_Url_Request* _request, const char* _frameName) - : listener(_listener) + : __ref(1) + , listener(_listener) , actedUponByClient(false) , navigationType(_navigationType) , mouseButton(_mouseButton) @@ -57,18 +59,34 @@ struct _Ewk_Navigation_Policy_Decision { , request(_request) , frameName(eina_stringshare_add(_frameName)) { } + + ~_Ewk_Navigation_Policy_Decision() + { + ASSERT(!__ref); + + // This is the default choice for all policy decisions in WebPageProxy.cpp. + if (!actedUponByClient) + WKFramePolicyListenerUse(listener.get()); + + ewk_url_request_unref(request); + eina_stringshare_del(frameName); + } }; -void ewk_navigation_policy_decision_free(Ewk_Navigation_Policy_Decision* decision) +void ewk_navigation_policy_decision_ref(Ewk_Navigation_Policy_Decision* decision) +{ + EINA_SAFETY_ON_NULL_RETURN(decision); + + ++decision->__ref; +} + +void ewk_navigation_policy_decision_unref(Ewk_Navigation_Policy_Decision* decision) { EINA_SAFETY_ON_NULL_RETURN(decision); - // This is the default choice for all policy decisions in WebPageProxy.cpp. - if (!decision->actedUponByClient) - WKFramePolicyListenerUse(decision->listener.get()); + if (--decision->__ref) + return; - ewk_url_request_unref(decision->request); - eina_stringshare_del(decision->frameName); delete decision; } diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_navigation_policy_decision.h b/Source/WebKit2/UIProcess/API/efl/ewk_navigation_policy_decision.h index 7681a9f20..dec9c09f9 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_navigation_policy_decision.h +++ b/Source/WebKit2/UIProcess/API/efl/ewk_navigation_policy_decision.h @@ -67,11 +67,20 @@ typedef enum { } Event_Modifier_Keys; /** - * Frees the given object. + * Increases the reference count of the given object. * - * @param decision the policy decision object to free + * @param decision the policy decision object to increase the reference count */ -EAPI void ewk_navigation_policy_decision_free(Ewk_Navigation_Policy_Decision *decision); +EAPI void ewk_navigation_policy_decision_ref(Ewk_Navigation_Policy_Decision *decision); + +/** + * Decreases the reference count of the given object, possibly freeing it. + * + * When the reference count reaches 0, the object is freed. + * + * @param decision the policy decision object to decrease the reference count + */ +EAPI void ewk_navigation_policy_decision_unref(Ewk_Navigation_Policy_Decision *decision); /** * Query type for this navigation policy decision. diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_url_request.cpp b/Source/WebKit2/UIProcess/API/efl/ewk_url_request.cpp index f29a40e5d..a424ddda3 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_url_request.cpp +++ b/Source/WebKit2/UIProcess/API/efl/ewk_url_request.cpp @@ -56,6 +56,14 @@ struct _Ewk_Url_Request { , first_party(0) , http_method(0) { } + + ~_Ewk_Url_Request() + { + ASSERT(!__ref); + eina_stringshare_del(url); + eina_stringshare_del(first_party); + eina_stringshare_del(http_method); + } }; #define EWK_URL_REQUEST_WK_GET_OR_RETURN(request, wkRequest_, ...) \ @@ -82,9 +90,6 @@ void ewk_url_request_unref(Ewk_Url_Request* request) if (--request->__ref) return; - eina_stringshare_del(request->url); - eina_stringshare_del(request->first_party); - eina_stringshare_del(request->http_method); delete request; } diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_url_request.h b/Source/WebKit2/UIProcess/API/efl/ewk_url_request.h index 0150b8917..ec44f5c1e 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_url_request.h +++ b/Source/WebKit2/UIProcess/API/efl/ewk_url_request.h @@ -50,7 +50,7 @@ EAPI void ewk_url_request_ref(Ewk_Url_Request *request); /** * Decreases the reference count of the given object, possibly freeing it. * - * When the reference count it's reached 0, the URL request is freed. + * When the reference count reaches 0, the URL request is freed. * * @param request the URL request object to decrease the reference count */ diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_url_response.cpp b/Source/WebKit2/UIProcess/API/efl/ewk_url_response.cpp index 2ab129717..137753d60 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_url_response.cpp +++ b/Source/WebKit2/UIProcess/API/efl/ewk_url_response.cpp @@ -46,6 +46,13 @@ struct _Ewk_Url_Response { , url(0) , mimeType(0) { } + + ~_Ewk_Url_Response() + { + ASSERT(!__ref); + eina_stringshare_del(url); + eina_stringshare_del(mimeType); + } }; void ewk_url_response_ref(Ewk_Url_Response* response) @@ -61,8 +68,6 @@ void ewk_url_response_unref(Ewk_Url_Response* response) if (--response->__ref) return; - eina_stringshare_del(response->url); - eina_stringshare_del(response->mimeType); delete response; } diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_url_response.h b/Source/WebKit2/UIProcess/API/efl/ewk_url_response.h index 165e9a61c..c02622dd7 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_url_response.h +++ b/Source/WebKit2/UIProcess/API/efl/ewk_url_response.h @@ -50,7 +50,7 @@ EAPI void ewk_url_response_ref(Ewk_Url_Response *response); /** * Decreases the reference count of the given object, possibly freeing it. * - * When the reference count it's reached 0, the URL request is freed. + * When the reference count reaches 0, the URL response is freed. * * @param response the URL response object to decrease the reference count */ diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp b/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp index eb1e5e7b2..8b7132b48 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp +++ b/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp @@ -49,12 +49,21 @@ struct _Ewk_View_Private_Data { OwnPtr<PageClientImpl> pageClient; const char* uri; const char* title; + const char* theme; LoadingResourcesMap loadingResourcesMap; _Ewk_View_Private_Data() : uri(0) , title(0) + , theme(0) { } + + ~_Ewk_View_Private_Data() + { + eina_stringshare_del(uri); + eina_stringshare_del(title); + eina_stringshare_del(theme); + } }; #define EWK_VIEW_TYPE_CHECK(ewkView, result) \ @@ -276,12 +285,6 @@ static Ewk_View_Private_Data* _ewk_view_priv_new(Ewk_View_Smart_Data* smartData) static void _ewk_view_priv_del(Ewk_View_Private_Data* priv) { - if (!priv) - return; - - priv->pageClient = nullptr; - eina_stringshare_del(priv->uri); - eina_stringshare_del(priv->title); delete priv; } @@ -507,6 +510,8 @@ Evas_Object* ewk_view_base_add(Evas* canvas, WKContextRef contextRef, WKPageGrou ewk_view_policy_client_attach(toAPI(priv->pageClient->page()), ewkView); ewk_view_resource_load_client_attach(toAPI(priv->pageClient->page()), ewkView); + ewk_view_theme_set(ewkView, DEFAULT_THEME_PATH"/default.edj"); + return ewkView; } @@ -738,6 +743,24 @@ void ewk_view_intent_request_new(Evas_Object* ewkView, const Ewk_Intent* ewkInte #endif } +void ewk_view_theme_set(Evas_Object* ewkView, const char* path) +{ + EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData); + EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv); + + if (!eina_stringshare_replace(&priv->theme, path)) + return; + + priv->pageClient->page()->setThemePath(path); +} + +const char* ewk_view_theme_get(const Evas_Object* ewkView) +{ + EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0); + return priv->theme; +} + void ewk_view_display(Evas_Object* ewkView, const IntRect& rect) { EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData); diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_view.h b/Source/WebKit2/UIProcess/API/efl/ewk_view.h index 58552ec7d..fe3f10675 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_view.h +++ b/Source/WebKit2/UIProcess/API/efl/ewk_view.h @@ -35,7 +35,11 @@ * - "load,provisional,redirect", void: view received redirect for provisional load. * - "load,provisional,started", void: view started provisional load. * - "policy,decision,navigation", Ewk_Navigation_Policy_Decision*: a navigation policy decision should be taken. + * To make a policy decision asynchronously, simply increment the reference count of the + * #Ewk_Navigation_Policy_Decision object using ewk_navigation_policy_decision_ref(). * - "policy,decision,new,window", Ewk_Navigation_Policy_Decision*: a new window policy decision should be taken. + * To make a policy decision asynchronously, simply increment the reference count of the + * #Ewk_Navigation_Policy_Decision object using ewk_navigation_policy_decision_ref(). * - "resource,request,failed", const Ewk_Web_Resource_Load_Error*: a resource failed loading. * - "resource,request,finished", const Ewk_Web_Resource*: a resource finished loading. * - "resource,request,new", const Ewk_Web_Resource_Request*: a resource request was initiated. @@ -189,7 +193,7 @@ struct _Ewk_Web_Resource_Load_Error { * * @param e canvas object where to create the view object * - * @return view object on success or @c 0 on failure + * @return view object on success or @c NULL on failure */ EAPI Evas_Object *ewk_view_add(Evas *e); @@ -199,7 +203,7 @@ EAPI Evas_Object *ewk_view_add(Evas *e); * @param e canvas object where to create the view object * @param context Ewk_Context object to declare process model * - * @return view object on success or @c 0 on failure + * @return view object on success or @c NULL on failure */ EAPI Evas_Object *ewk_view_add_with_context(Evas *e, Ewk_Context *context); @@ -221,7 +225,7 @@ EAPI Eina_Bool ewk_view_uri_set(Evas_Object *o, const char *uri); * * @param o view object to get current URI * - * @return current URI on success or @c 0 on failure + * @return current URI on success or @c NULL on failure */ EAPI const char *ewk_view_uri_get(const Evas_Object *o); @@ -311,7 +315,7 @@ EAPI Eina_Bool ewk_view_forward_possible(Evas_Object *o); * * @param o view object to get current title * - * @return current title on success or @c 0 on failure + * @return current title on success or @c NULL on failure */ EAPI const char *ewk_view_title_get(const Evas_Object *o); @@ -393,6 +397,29 @@ EAPI float ewk_view_device_pixel_ratio_get(const Evas_Object *o); */ EAPI Eina_Bool ewk_view_device_pixel_ratio_set(Evas_Object *o, float ratio); +/** + * Sets the theme path that will be used by this view. + * + * This also sets the theme on the main frame. As frames inherit theme + * from their parent, this will have all frames with unset theme to + * use this one. + * + * @param o view object to change theme + * @param path theme path, may be @c NULL to reset to the default theme + */ +EAPI void ewk_view_theme_set(Evas_Object *o, const char *path); + +/** + * Gets the theme set on this view. + * + * This returns the value set by ewk_view_theme_set(). + * + * @param o view object to get theme path + * + * @return the theme path, may be @c NULL if not set + */ +EAPI const char *ewk_view_theme_get(const Evas_Object *o); + #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_view_policy_client.cpp b/Source/WebKit2/UIProcess/API/efl/ewk_view_policy_client.cpp index 5f689e56d..6e2540f80 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_view_policy_client.cpp +++ b/Source/WebKit2/UIProcess/API/efl/ewk_view_policy_client.cpp @@ -26,12 +26,14 @@ #include "config.h" #include "WKFrame.h" +#include "WKFramePolicyListener.h" #include "ewk_navigation_policy_decision.h" #include "ewk_navigation_policy_decision_private.h" #include "ewk_view_policy_client_private.h" #include "ewk_view_private.h" #include <wtf/text/CString.h> +using namespace WebCore; using namespace WebKit; static inline Evas_Object* toEwkView(const void* clientInfo) @@ -43,14 +45,47 @@ static void decidePolicyForNavigationAction(WKPageRef page, WKFrameRef frame, WK { Ewk_Navigation_Policy_Decision* decision = ewk_navigation_policy_decision_new(navigationType, mouseButton, modifiers, request, 0, listener); ewk_view_navigation_policy_decision(toEwkView(clientInfo), decision); - ewk_navigation_policy_decision_free(decision); + ewk_navigation_policy_decision_unref(decision); } static void decidePolicyForNewWindowAction(WKPageRef page, WKFrameRef frame, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKURLRequestRef request, WKStringRef frameName, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo) { Ewk_Navigation_Policy_Decision* decision = ewk_navigation_policy_decision_new(navigationType, mouseButton, modifiers, request, toImpl(frameName)->string().utf8().data(), listener); ewk_view_new_window_policy_decision(toEwkView(clientInfo), decision); - ewk_navigation_policy_decision_free(decision); + ewk_navigation_policy_decision_unref(decision); +} + +static void decidePolicyForResponseCallback(WKPageRef page, WKFrameRef frame, WKURLResponseRef response, WKURLRequestRef, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo) +{ + const ResourceResponse resourceResponse = toImpl(response)->resourceResponse(); + // If the URL Response has "Content-Disposition: attachment;" header, then + // we should download it. + if (resourceResponse.isAttachment()) { + WKFramePolicyListenerDownload(listener); + return; + } + + String mimeType = toImpl(response)->resourceResponse().mimeType().lower(); + bool canShowMIMEType = toImpl(frame)->canShowMIMEType(mimeType); + if (WKFrameIsMainFrame(frame)) { + if (canShowMIMEType) { + WKFramePolicyListenerUse(listener); + return; + } + + // If we can't use (show) it then we should download it. + WKFramePolicyListenerDownload(listener); + return; + } + + // We should ignore downloadable top-level content for subframes, with an exception for text/xml and application/xml so we can still support Acid3 test. + // It makes the browser intentionally behave differently when it comes to text(application)/xml content in subframes vs. mainframe. + if (!canShowMIMEType && !(mimeType == "text/xml" || mimeType == "application/xml")) { + WKFramePolicyListenerIgnore(listener); + return; + } + + WKFramePolicyListenerUse(listener); } void ewk_view_policy_client_attach(WKPageRef pageRef, Evas_Object* ewkView) @@ -61,6 +96,7 @@ void ewk_view_policy_client_attach(WKPageRef pageRef, Evas_Object* ewkView) policyClient.clientInfo = ewkView; policyClient.decidePolicyForNavigationAction = decidePolicyForNavigationAction; policyClient.decidePolicyForNewWindowAction = decidePolicyForNewWindowAction; + policyClient.decidePolicyForResponse = decidePolicyForResponseCallback; WKPageSetPagePolicyClient(pageRef, &policyClient); } diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_web_error.cpp b/Source/WebKit2/UIProcess/API/efl/ewk_web_error.cpp index 0ac75ab68..f16fb2cc3 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_web_error.cpp +++ b/Source/WebKit2/UIProcess/API/efl/ewk_web_error.cpp @@ -50,6 +50,12 @@ struct _Ewk_Web_Error { , url(0) , description(0) { } + + ~_Ewk_Web_Error() + { + eina_stringshare_del(url); + eina_stringshare_del(description); + } }; #define EWK_WEB_ERROR_WK_GET_OR_RETURN(error, wkError_, ...) \ @@ -63,12 +69,10 @@ struct _Ewk_Web_Error { } \ WKErrorRef wkError_ = (error)->wkError.get() -void ewk_web_error_free(Ewk_Web_Error *error) +void ewk_web_error_free(Ewk_Web_Error* error) { EINA_SAFETY_ON_NULL_RETURN(error); - eina_stringshare_del(error->url); - eina_stringshare_del(error->description); delete error; } diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_web_resource.cpp b/Source/WebKit2/UIProcess/API/efl/ewk_web_resource.cpp index 44d9c2afc..e0d728a9e 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_web_resource.cpp +++ b/Source/WebKit2/UIProcess/API/efl/ewk_web_resource.cpp @@ -39,6 +39,12 @@ struct _Ewk_Web_Resource { , url(eina_stringshare_add(_url)) , isMainResource(_isMainResource) { } + + ~_Ewk_Web_Resource() + { + ASSERT(!__ref); + eina_stringshare_del(url); + } }; void ewk_web_resource_ref(Ewk_Web_Resource* resource) @@ -55,7 +61,6 @@ void ewk_web_resource_unref(Ewk_Web_Resource* resource) if (--resource->__ref) return; - eina_stringshare_del(resource->url); delete resource; } diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_web_resource.h b/Source/WebKit2/UIProcess/API/efl/ewk_web_resource.h index 3d78d4bc9..47fd7adf4 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_web_resource.h +++ b/Source/WebKit2/UIProcess/API/efl/ewk_web_resource.h @@ -50,7 +50,7 @@ EAPI void ewk_web_resource_ref(Ewk_Web_Resource *resource); /** * Decreases the reference count of the given object, possibly freeing it. * - * When the reference count it's reached 0, the resource is freed. + * When the reference count reaches 0, the resource is freed. * * @param resource the resource object to decrease the reference count */ diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp index b7ffc98b8..f65fa97ed 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp @@ -188,7 +188,7 @@ static void webkitWebViewBaseContainerAdd(GtkContainer* container, GtkWidget* wi if (WEBKIT_IS_WEB_VIEW_BASE(widget) && WebInspectorProxy::isInspectorPage(WEBKIT_WEB_VIEW_BASE(widget)->priv->pageProxy.get())) { - ASSERT(priv->inspectorView); + ASSERT(!priv->inspectorView); priv->inspectorView = widget; priv->inspectorViewHeight = gMinimumAttachedInspectorHeight; } else { diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am b/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am index 919202522..3fadf40b4 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am +++ b/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am @@ -67,6 +67,10 @@ Libraries_libWebKit2APITestCore_la_SOURCES = \ Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h Libraries_libWebKit2APITestCore_la_CPPFLAGS = $(webkit2_tests_cppflags) +EXTRA_DIST += \ + Source/WebKit2/UIProcess/API/gtk/tests/resources/test-cert.pem \ + Source/WebKit2/UIProcess/API/gtk/tests/resources/test-key.pem + Programs_WebKit2APITests_TestWebKitWebContext_SOURCES = \ Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebContext.cpp Programs_WebKit2APITests_TestWebKitWebContext_CPPFLAGS = \ diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp index 7de95e0f0..43f59e1e7 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp @@ -293,16 +293,16 @@ public: m_loadEvents.append(Failed); } - void waitUntilResourceLoadFinsihed() + void waitUntilResourceLoadFinished() { m_resource = 0; m_resourcesLoaded = 0; g_main_loop_run(m_mainLoop); } - WebKitURIResponse* waitUntilResourceLoadFinsihedAndReturnURIResponse() + WebKitURIResponse* waitUntilResourceLoadFinishedAndReturnURIResponse() { - waitUntilResourceLoadFinsihed(); + waitUntilResourceLoadFinished(); g_assert(m_resource); return webkit_web_resource_get_response(m_resource.get()); } @@ -315,7 +315,7 @@ public: static void testWebResourceLoading(SingleResourceLoadTest* test, gconstpointer) { test->loadURI(kServer->getURIForPath("/javascript.html").data()); - test->waitUntilResourceLoadFinsihed(); + test->waitUntilResourceLoadFinished(); g_assert(test->m_resource); Vector<SingleResourceLoadTest::LoadEvents>& events = test->m_loadEvents; g_assert_cmpint(events.size(), ==, 5); @@ -327,7 +327,7 @@ static void testWebResourceLoading(SingleResourceLoadTest* test, gconstpointer) events.clear(); test->loadURI(kServer->getURIForPath("/redirected-css.html").data()); - test->waitUntilResourceLoadFinsihed(); + test->waitUntilResourceLoadFinished(); g_assert(test->m_resource); g_assert_cmpint(events.size(), ==, 6); g_assert_cmpint(events[0], ==, SingleResourceLoadTest::Started); @@ -339,7 +339,7 @@ static void testWebResourceLoading(SingleResourceLoadTest* test, gconstpointer) events.clear(); test->loadURI(kServer->getURIForPath("/invalid-css.html").data()); - test->waitUntilResourceLoadFinsihed(); + test->waitUntilResourceLoadFinished(); g_assert(test->m_resource); g_assert_cmpint(events.size(), ==, 4); g_assert_cmpint(events[0], ==, SingleResourceLoadTest::Started); @@ -353,47 +353,47 @@ static void testWebResourceResponse(SingleResourceLoadTest* test, gconstpointer) { // No cached resource: First load. test->loadURI(kServer->getURIForPath("/javascript.html").data()); - WebKitURIResponse* response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + WebKitURIResponse* response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_OK); // No cached resource: Second load. test->loadURI(kServer->getURIForPath("/javascript.html").data()); - response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_OK); // No cached resource: Reload. webkit_web_view_reload(test->m_webView); - response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_OK); // Cached resource: First load. test->loadURI(kServer->getURIForPath("/image.html").data()); - response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_OK); // Cached resource: Second load. test->loadURI(kServer->getURIForPath("/image.html").data()); - response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_OK); // Cached resource: Reload. webkit_web_view_reload(test->m_webView); - response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_NOT_MODIFIED); } static void testWebResourceMimeType(SingleResourceLoadTest* test, gconstpointer) { test->loadURI(kServer->getURIForPath("/javascript.html").data()); - WebKitURIResponse* response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + WebKitURIResponse* response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); g_assert_cmpstr(webkit_uri_response_get_mime_type(response), ==, "text/javascript"); test->loadURI(kServer->getURIForPath("/image.html").data()); - response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); g_assert_cmpstr(webkit_uri_response_get_mime_type(response), ==, "image/vnd.microsoft.icon"); test->loadURI(kServer->getURIForPath("/redirected-css.html").data()); - response = test->waitUntilResourceLoadFinsihedAndReturnURIResponse(); + response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); g_assert_cmpstr(webkit_uri_response_get_mime_type(response), ==, "text/css"); } @@ -475,7 +475,7 @@ private: static void testWebResourceActiveURI(ResourceURITrackingTest* test, gconstpointer) { test->loadURI(kServer->getURIForPath("/redirected-css.html").data()); - test->waitUntilResourceLoadFinsihed(); + test->waitUntilResourceLoadFinished(); } static void testWebResourceGetData(ResourcesTest* test, gconstpointer) @@ -543,7 +543,7 @@ static void serverCallback(SoupServer* server, SoupMessage* message, const char* soup_message_set_status(message, SOUP_STATUS_OK); - if (soup_message_headers_get(message->request_headers, "If-Modified-Since")) { + if (soup_message_headers_get_one(message->request_headers, "If-Modified-Since")) { soup_message_set_status(message, SOUP_STATUS_NOT_MODIFIED); soup_message_body_complete(message->response_body); return; diff --git a/Source/WebKit2/UIProcess/LayerTreeCoordinatorProxy.cpp b/Source/WebKit2/UIProcess/LayerTreeCoordinatorProxy.cpp index dad90934c..629291a4b 100644 --- a/Source/WebKit2/UIProcess/LayerTreeCoordinatorProxy.cpp +++ b/Source/WebKit2/UIProcess/LayerTreeCoordinatorProxy.cpp @@ -61,26 +61,20 @@ void LayerTreeCoordinatorProxy::createTileForLayer(int layerID, int tileID, cons updateTileForLayer(layerID, tileID, targetRect, updateInfo); } -static inline uint64_t createLayerTileUniqueKey(int layerID, int tileID) -{ - uint64_t key = layerID; - key <<= 32; - key |= tileID; - return key; -} - void LayerTreeCoordinatorProxy::updateTileForLayer(int layerID, int tileID, const IntRect& targetRect, const WebKit::SurfaceUpdateInfo& updateInfo) { RefPtr<ShareableSurface> surface; #if USE(GRAPHICS_SURFACE) - uint64_t key = createLayerTileUniqueKey(layerID, tileID); - - HashMap<uint64_t, RefPtr<ShareableSurface> >::iterator it = m_surfaces.find(key); - if (it == m_surfaces.end()) { - surface = ShareableSurface::create(updateInfo.surfaceHandle); - m_surfaces.add(key, surface); + int token = updateInfo.surfaceHandle.graphicsSurfaceToken(); + if (token) { + HashMap<uint32_t, RefPtr<ShareableSurface> >::iterator it = m_surfaces.find(token); + if (it == m_surfaces.end()) { + surface = ShareableSurface::create(updateInfo.surfaceHandle); + m_surfaces.add(token, surface); + } else + surface = it->second; } else - surface = it->second; + surface = ShareableSurface::create(updateInfo.surfaceHandle); #else surface = ShareableSurface::create(updateInfo.surfaceHandle); #endif diff --git a/Source/WebKit2/UIProcess/LayerTreeCoordinatorProxy.h b/Source/WebKit2/UIProcess/LayerTreeCoordinatorProxy.h index c0edb6658..b4e7b7ce2 100644 --- a/Source/WebKit2/UIProcess/LayerTreeCoordinatorProxy.h +++ b/Source/WebKit2/UIProcess/LayerTreeCoordinatorProxy.h @@ -79,7 +79,7 @@ protected: DrawingAreaProxy* m_drawingAreaProxy; RefPtr<WebLayerTreeRenderer> m_renderer; #if USE(GRAPHICS_SURFACE) - HashMap<uint64_t, RefPtr<ShareableSurface> > m_surfaces; + HashMap<uint32_t, RefPtr<ShareableSurface> > m_surfaces; #endif }; diff --git a/Source/WebKit2/UIProcess/WebPageProxy.h b/Source/WebKit2/UIProcess/WebPageProxy.h index 6c7e68811..29a6c65c5 100644 --- a/Source/WebKit2/UIProcess/WebPageProxy.h +++ b/Source/WebKit2/UIProcess/WebPageProxy.h @@ -362,6 +362,9 @@ public: void proxyAuthenticationRequiredRequest(const String& hostname, uint16_t port, const String& prefilledUsername, String& username, String& password); void setUserScripts(const Vector<String>&); #endif // PLATFORM(QT). +#if PLATFORM(EFL) + void setThemePath(const String&); +#endif #if PLATFORM(QT) void setComposition(const String& text, Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd); diff --git a/Source/WebKit2/UIProcess/efl/WebPageProxyEfl.cpp b/Source/WebKit2/UIProcess/efl/WebPageProxyEfl.cpp index b076b4ef6..e1eda1035 100644 --- a/Source/WebKit2/UIProcess/efl/WebPageProxyEfl.cpp +++ b/Source/WebKit2/UIProcess/efl/WebPageProxyEfl.cpp @@ -28,6 +28,8 @@ #include "NotImplemented.h" #include "PageClientImpl.h" +#include "WebPageMessages.h" +#include "WebProcessProxy.h" #include <sys/utsname.h> @@ -76,4 +78,9 @@ void WebPageProxy::loadRecentSearches(const String&, Vector<String>&) notImplemented(); } +void WebPageProxy::setThemePath(const String& themePath) +{ + process()->send(Messages::WebPage::SetThemePath(themePath), m_pageID, 0); +} + } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp b/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp index 592bb371c..afdfa6fcd 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp +++ b/Source/WebKit2/UIProcess/qt/QtWebIconDatabaseClient.cpp @@ -90,11 +90,11 @@ QImage QtWebIconDatabaseClient::iconImageForPageURL(const WTF::String& pageURL, WebCore::IntSize size(iconSize.width(), iconSize.height()); - QPixmap* nativeImage = m_iconDatabase->nativeImageForPageURL(pageURL, size); + QImage* nativeImage = m_iconDatabase->nativeImageForPageURL(pageURL, size); if (!nativeImage) return QImage(); - return nativeImage->toImage(); + return *nativeImage; } void QtWebIconDatabaseClient::retainIconForPageURL(const String& pageURL) diff --git a/Source/WebKit2/UIProcess/texmap/LayerBackingStore.cpp b/Source/WebKit2/UIProcess/texmap/LayerBackingStore.cpp index 967f07513..43dbe0cba 100644 --- a/Source/WebKit2/UIProcess/texmap/LayerBackingStore.cpp +++ b/Source/WebKit2/UIProcess/texmap/LayerBackingStore.cpp @@ -141,7 +141,8 @@ void LayerBackingStore::paintToTextureMapper(TextureMapper* textureMapper, const static bool shouldDebug = shouldShowTileDebugVisuals(); if (!shouldDebug) continue; - textureMapper->drawBorder(QColor(Qt::red), 2, tile->rect(), transform); + + textureMapper->drawBorder(Color(0xFF, 0, 0), 2, tile->rect(), transform); textureMapper->drawRepaintCounter(static_cast<LayerBackingStoreTile*>(tile)->repaintCount(), 8, tilesToPaint[i]->rect().location(), transform); } } diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebBatteryClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebBatteryClient.cpp index 8ed4dde03..91033fa64 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebBatteryClient.cpp +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebBatteryClient.cpp @@ -36,14 +36,6 @@ using namespace WebCore; namespace WebKit { -void WebBatteryClient::setController(WebCore::BatteryController*) -{ - // We provide an empty implementation for this method so that - // it compiles. We don't need it since WebBatteryManager - // retrieves the controller directly from the page by calling - // BatteryController::from(). -} - void WebBatteryClient::startUpdating() { WebProcess::shared().batteryManager().registerWebPage(m_page); diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebBatteryClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebBatteryClient.h index 0e5c70ed4..b260c624c 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebBatteryClient.h +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebBatteryClient.h @@ -44,7 +44,6 @@ public: virtual ~WebBatteryClient() { } private: - virtual void setController(WebCore::BatteryController*) OVERRIDE; virtual void startUpdating() OVERRIDE; virtual void stopUpdating() OVERRIDE; virtual void batteryControllerDestroyed() OVERRIDE; diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h index e3b3a5e84..aa5457799 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h @@ -220,15 +220,6 @@ private: virtual void numWheelEventHandlersChanged(unsigned) OVERRIDE; virtual void numTouchEventHandlersChanged(unsigned) OVERRIDE { } -#if ENABLE(REGISTER_PROTOCOL_HANDLER) - virtual void registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title) OVERRIDE { } -#endif - -#if ENABLE(CUSTOM_SCHEME_HANDLER) - virtual CustomHandlersState isProtocolHandlerRegistered(const String&, const String&, const String&) { return CustomHandlersDeclined; } - virtual void unregisterProtocolHandler(const String&, const String&, const String&) { } -#endif - String m_cachedToolTip; mutable RefPtr<WebFrame> m_cachedFrameSetLargestFrame; mutable bool m_cachedMainFrameHasHorizontalScrollbar; diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.cpp index 14511856b..2c30b72bd 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.cpp +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.cpp @@ -43,10 +43,11 @@ void WebInspectorClient::inspectorDestroyed() delete this; } -void WebInspectorClient::openInspectorFrontend(InspectorController*) +WebCore::InspectorFrontendChannel* WebInspectorClient::openInspectorFrontend(InspectorController*) { WebPage* inspectorPage = m_page->inspector()->createInspectorPage(); ASSERT_UNUSED(inspectorPage, inspectorPage); + return this; } void WebInspectorClient::closeInspectorFrontend() diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.h index 7926d5a80..850041af1 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.h +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.h @@ -31,6 +31,7 @@ #include "PageOverlay.h" #include <WebCore/InspectorClient.h> +#include <WebCore/InspectorFrontendChannel.h> namespace WebCore { class GraphicsContext; @@ -41,7 +42,7 @@ namespace WebKit { class WebPage; -class WebInspectorClient : public WebCore::InspectorClient, private PageOverlay::Client { +class WebInspectorClient : public WebCore::InspectorClient, public WebCore::InspectorFrontendChannel, private PageOverlay::Client { public: WebInspectorClient(WebPage* page) : m_page(page) @@ -52,7 +53,7 @@ public: private: virtual void inspectorDestroyed() OVERRIDE; - virtual void openInspectorFrontend(WebCore::InspectorController*) OVERRIDE; + virtual InspectorFrontendChannel* openInspectorFrontend(WebCore::InspectorController*) OVERRIDE; virtual void closeInspectorFrontend() OVERRIDE; virtual void bringFrontendToFront() OVERRIDE; virtual void didResizeMainFrame(WebCore::Frame*) OVERRIDE; diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebRegisterProtocolHandlerClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebRegisterProtocolHandlerClient.h new file mode 100644 index 000000000..7019747b9 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebRegisterProtocolHandlerClient.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2012 Samsung Electronics. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebRegisterProtocolHandlerClient_h +#define WebRegisterProtocolHandlerClient_h + +#include <WebCore/RegisterProtocolHandlerClient.h> +#include <wtf/text/WTFString.h> + +namespace WebKit { + +class WebRegisterProtocolHandlerClient : public WebCore::RegisterProtocolHandlerClient { +public: + virtual ~WebRegisterProtocolHandlerClient() { } + +private: +#if ENABLE(REGISTER_PROTOCOL_HANDLER) + virtual void registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title) OVERRIDE { } +#endif + +#if ENABLE(CUSTOM_SCHEME_HANDLER) + virtual CustomHandlersState isProtocolHandlerRegistered(const String&, const String&, const String&) { return CustomHandlersDeclined; } + virtual void unregisterProtocolHandler(const String&, const String&, const String&) { } +#endif +}; + +} + +#endif // WebRegisterProtocolHandlerClient_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebDragClientQt.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebDragClientQt.cpp index bbdb635b3..d9e6d1d13 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebDragClientQt.cpp +++ b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebDragClientQt.cpp @@ -38,15 +38,15 @@ using namespace WebCore; namespace WebKit { -static PassRefPtr<ShareableBitmap> convertQPixmapToShareableBitmap(QPixmap* pixmap) +static PassRefPtr<ShareableBitmap> convertQImageToShareableBitmap(QImage* image) { - if (!pixmap) + if (!image) return 0; - RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(IntSize(pixmap->size()), ShareableBitmap::SupportsAlpha); + RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(IntSize(image->size()), ShareableBitmap::SupportsAlpha); OwnPtr<GraphicsContext> graphicsContext = bitmap->createGraphicsContext(); - graphicsContext->platformContext()->drawPixmap(0, 0, *pixmap); + graphicsContext->platformContext()->drawImage(0, 0, *image); return bitmap.release(); } @@ -57,7 +57,7 @@ void WebDragClient::startDrag(DragImageRef dragImage, const IntPoint& clientPosi static_cast<ClipboardQt*>(clipboard)->invalidateWritableData(); DragData dragData(clipboardData, clientPosition, globalPosition, dragOperationMask); - RefPtr<ShareableBitmap> bitmap = convertQPixmapToShareableBitmap(dragImage); + RefPtr<ShareableBitmap> bitmap = convertQImageToShareableBitmap(dragImage); ShareableBitmap::Handle handle; if (bitmap && !bitmap->createHandle(handle)) return; diff --git a/Source/WebKit2/WebProcess/WebPage/LayerTreeCoordinator/LayerTreeCoordinator.cpp b/Source/WebKit2/WebProcess/WebPage/LayerTreeCoordinator/LayerTreeCoordinator.cpp index ae099d15c..a3b9a1391 100644 --- a/Source/WebKit2/WebProcess/WebPage/LayerTreeCoordinator/LayerTreeCoordinator.cpp +++ b/Source/WebKit2/WebProcess/WebPage/LayerTreeCoordinator/LayerTreeCoordinator.cpp @@ -409,12 +409,12 @@ int64_t LayerTreeCoordinator::adoptImageBackingStore(Image* image) int64_t key = 0; #if PLATFORM(QT) - QPixmap* pixmap = image->nativeImageForCurrentFrame(); + QImage* nativeImage = image->nativeImageForCurrentFrame(); - if (!pixmap) + if (!nativeImage) return InvalidWebLayerID; - key = pixmap->cacheKey(); + key = nativeImage->cacheKey(); #endif HashMap<int64_t, int>::iterator it = m_directlyCompositedImageRefCounts.find(key); diff --git a/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp b/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp index 68d3b0c41..7fa40e14f 100644 --- a/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp +++ b/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp @@ -27,7 +27,6 @@ #include "WebInspector.h" #if ENABLE(INSPECTOR) - #include "WebFrame.h" #include "WebInspectorFrontendClient.h" #include "WebInspectorProxyMessages.h" @@ -35,21 +34,23 @@ #include "WebPageCreationParameters.h" #include "WebProcess.h" #include <WebCore/InspectorController.h> +#include <WebCore/InspectorFrontendChannel.h> #include <WebCore/Page.h> using namespace WebCore; namespace WebKit { -PassRefPtr<WebInspector> WebInspector::create(WebPage* page) +PassRefPtr<WebInspector> WebInspector::create(WebPage* page, InspectorFrontendChannel* frontendChannel) { - return adoptRef(new WebInspector(page)); + return adoptRef(new WebInspector(page, frontendChannel)); } -WebInspector::WebInspector(WebPage* page) +WebInspector::WebInspector(WebPage* page, InspectorFrontendChannel* frontendChannel) : m_page(page) , m_inspectorPage(0) , m_frontendClient(0) + , m_frontendChannel(frontendChannel) #if ENABLE(INSPECTOR_SERVER) , m_remoteFrontendConnected(false) #endif @@ -91,6 +92,7 @@ void WebInspector::destroyInspectorPage() { m_inspectorPage = 0; m_frontendClient = 0; + m_frontendChannel = 0; } // Called from WebInspectorFrontendClient @@ -255,8 +257,8 @@ void WebInspector::remoteFrontendConnected() ASSERT(!m_remoteFrontendConnected); // Switching between in-process and remote inspectors isn't supported yet. ASSERT(!m_inspectorPage); - - m_page->corePage()->inspectorController()->connectFrontend(); + + m_page->corePage()->inspectorController()->connectFrontend(m_frontendChannel); m_remoteFrontendConnected = true; } diff --git a/Source/WebKit2/WebProcess/WebPage/WebInspector.h b/Source/WebKit2/WebProcess/WebPage/WebInspector.h index 575725ae6..c041546a8 100644 --- a/Source/WebKit2/WebProcess/WebPage/WebInspector.h +++ b/Source/WebKit2/WebProcess/WebPage/WebInspector.h @@ -33,6 +33,10 @@ #include <wtf/Noncopyable.h> #include <wtf/text/WTFString.h> +namespace WebCore { +class InspectorFrontendChannel; +} + namespace WebKit { class WebInspectorFrontendClient; @@ -43,7 +47,7 @@ class WebInspector : public APIObject { public: static const Type APIType = TypeBundleInspector; - static PassRefPtr<WebInspector> create(WebPage*); + static PassRefPtr<WebInspector> create(WebPage*, WebCore::InspectorFrontendChannel*); WebPage* page() const { return m_page; } WebPage* inspectorPage() const { return m_inspectorPage; } @@ -77,7 +81,7 @@ private: friend class WebInspectorClient; friend class WebInspectorFrontendClient; - explicit WebInspector(WebPage*); + explicit WebInspector(WebPage*, WebCore::InspectorFrontendChannel*); virtual Type type() const { return APIType; } @@ -116,6 +120,7 @@ private: WebPage* m_page; WebPage* m_inspectorPage; WebInspectorFrontendClient* m_frontendClient; + WebCore::InspectorFrontendChannel* m_frontendChannel; #if PLATFORM(MAC) String m_localizedStringsURL; #endif diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp index 2cb290e50..77987f26c 100644 --- a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp @@ -245,6 +245,7 @@ WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters) #if ENABLE(PAGE_VISIBILITY_API) , m_visibilityState(WebCore::PageVisibilityStateVisible) #endif + , m_inspectorClient(0) { ASSERT(m_pageID); // FIXME: This is a non-ideal location for this Setting and @@ -262,7 +263,8 @@ WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters) #endif pageClients.backForwardClient = WebBackForwardListProxy::create(this); #if ENABLE(INSPECTOR) - pageClients.inspectorClient = new WebInspectorClient(this); + m_inspectorClient = new WebInspectorClient(this); + pageClients.inspectorClient = m_inspectorClient; #endif #if USE(AUTOCORRECTION_PANEL) pageClients.alternativeTextClient = new WebAlternativeTextClient(this); @@ -1339,6 +1341,10 @@ static bool handleMouseEvent(const WebMouseEvent& mouseEvent, WebPage* page, boo if (isContextClick(platformMouseEvent)) handled = handleContextMenuEvent(platformMouseEvent, page); #endif +#if PLATFORM(GTK) + bool gtkMouseButtonPressHandled = page->handleMousePressedEvent(platformMouseEvent); + handled = handled || gtkMouseButtonPressHandled; +#endif return handled; } @@ -2085,7 +2091,7 @@ WebInspector* WebPage::inspector() if (m_isClosed) return 0; if (!m_inspector) - m_inspector = WebInspector::create(this); + m_inspector = WebInspector::create(this, m_inspectorClient); return m_inspector.get(); } #endif diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.h b/Source/WebKit2/WebProcess/WebPage/WebPage.h index d234a1da4..4d20421e0 100644 --- a/Source/WebKit2/WebProcess/WebPage/WebPage.h +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.h @@ -131,6 +131,7 @@ class WebFrame; class WebFullScreenManager; class WebImage; class WebInspector; +class WebInspectorClient; class WebKeyboardEvent; class WebMouseEvent; class WebNotificationClient; @@ -403,6 +404,10 @@ public: SandboxExtensionTracker& sandboxExtensionTracker() { return m_sandboxExtensionTracker; } +#if PLATFORM(EFL) + void setThemePath(const String&); +#endif + #if PLATFORM(QT) void setComposition(const String& text, Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd); void confirmComposition(const String& text, int64_t selectionStart, int64_t selectionLength); @@ -445,6 +450,7 @@ public: #elif PLATFORM(GTK) void updateAccessibilityTree(); + bool handleMousePressedEvent(const WebCore::PlatformMouseEvent&); #if USE(TEXTURE_MAPPER_GL) void widgetMapped(int64_t nativeWindowHandle); #endif @@ -871,6 +877,7 @@ private: #if ENABLE(PAGE_VISIBILITY_API) WebCore::PageVisibilityState m_visibilityState; #endif + WebInspectorClient* m_inspectorClient; }; } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in index 75f7245f5..4c260eb90 100644 --- a/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in @@ -230,6 +230,10 @@ messages -> WebPage { DeliverIntentToFrame(uint64_t frameID, WebKit::IntentData intentData); #endif +#if PLATFORM(EFL) + SetThemePath(WTF::String themePath) +#endif + #if PLATFORM(QT) SetComposition(WTF::String text, WTF::Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd) ConfirmComposition(WTF::String text, int64_t selectionStart, int64_t selectionLength) diff --git a/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp b/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp index df0f17f87..fa570358a 100644 --- a/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp +++ b/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp @@ -34,9 +34,11 @@ #include <WebCore/EflKeyboardUtilities.h> #include <WebCore/FocusController.h> #include <WebCore/Frame.h> +#include <WebCore/FrameView.h> #include <WebCore/KeyboardEvent.h> #include <WebCore/Page.h> #include <WebCore/PlatformKeyboardEvent.h> +#include <WebCore/RenderThemeEfl.h> #include <WebCore/Settings.h> using namespace WebCore; @@ -104,4 +106,10 @@ const char* WebPage::interpretKeyEvent(const KeyboardEvent* event) return getKeyPressCommandName(event); } +void WebPage::setThemePath(const String& themePath) +{ + WebCore::RenderThemeEfl* theme = static_cast<WebCore::RenderThemeEfl*>(m_page->theme()); + theme->setThemePath(themePath); +} + } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp index a02891cc1..30aaa4037 100644 --- a/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp +++ b/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp @@ -37,6 +37,7 @@ #include <WebCore/Frame.h> #include <WebCore/KeyboardEvent.h> #include <WebCore/Page.h> +#include <WebCore/PasteboardHelper.h> #include <WebCore/PlatformKeyboardEvent.h> #include <WebCore/Settings.h> #include <wtf/gobject/GOwnPtr.h> @@ -159,7 +160,31 @@ void WebPage::widgetMapped(int64_t nativeWindowHandle) { m_nativeWindowHandle = nativeWindowHandle; } +#endif + +bool WebPage::handleMousePressedEvent(const PlatformMouseEvent& platformMouseEvent) +{ + bool returnValue = false; + if (platformMouseEvent.button() != WebCore::MiddleButton) + return returnValue; + +#if PLATFORM(X11) + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame) + return returnValue; + PasteboardHelper* pasteboardHelper = PasteboardHelper::defaultPasteboardHelper(); + bool wasUsingPrimary = pasteboardHelper->usePrimarySelectionClipboard(); + pasteboardHelper->setUsePrimarySelectionClipboard(true); + + Editor* editor = frame->editor(); + returnValue = editor->canPaste() || editor->canDHTMLPaste(); + editor->paste(); + + pasteboardHelper->setUsePrimarySelectionClipboard(wasUsingPrimary); #endif + return returnValue; +} + } // namespace WebKit diff --git a/Source/WebKit2/win/WebKit2.def b/Source/WebKit2/win/WebKit2.def index 4c742953c..563758064 100644 --- a/Source/WebKit2/win/WebKit2.def +++ b/Source/WebKit2/win/WebKit2.def @@ -153,8 +153,6 @@ EXPORTS ??1ClientRectList@WebCore@@QAE@XZ ??0String@WTF@@QAE@PBD@Z ??0String@WTF@@QAE@PB_W@Z - ??1FrameDestructionObserver@WebCore@@MAE@XZ - ??0FrameDestructionObserver@WebCore@@QAE@PAVFrame@1@@Z ?absoluteBoundingBoxRect@RenderObject@WebCore@@QBE?AVIntRect@2@_N@Z ?absoluteBoundingBoxRectIgnoringTransforms@RenderObject@WebCore@@QBE?AVIntRect@2@XZ ?description@DocumentMarker@WebCore@@QBEABVString@WTF@@XZ @@ -174,7 +172,6 @@ EXPORTS ?externalRepresentation@WebCore@@YA?AVString@WTF@@PAVElement@1@I@Z ?find@StringImpl@WTF@@QAEIPAV12@I@Z ?find@StringImpl@WTF@@QAEIPAV12@@Z - ?frameDestroyed@FrameDestructionObserver@WebCore@@UAEXXZ ?absoluteCaretBounds@FrameSelection@WebCore@@QAE?AVIntRect@2@XZ ?fromUTF8WithLatin1Fallback@String@WTF@@SA?AV12@PBEI@Z ?getCachedDOMStructure@WebCore@@YAPAVStructure@JSC@@PAVJSDOMGlobalObject@1@PBUClassInfo@3@@Z @@ -197,7 +194,6 @@ EXPORTS ?previous@ComposedShadowTreeWalker@WebCore@@QAEXXZ ?number@String@WTF@@SA?AV12@I@Z ?number@String@WTF@@SA?AV12@H@Z - ?observeFrame@FrameDestructionObserver@WebCore@@IAEXPAVFrame@2@@Z ?overrideUserPreferredLanguages@WebCore@@YAXABV?$Vector@VString@WTF@@$0A@@WTF@@@Z ?numberOfScopedHTMLStyleChildren@Node@WebCore@@QBEIXZ ?page@Document@WebCore@@QBEPAVPage@2@XZ @@ -254,7 +250,6 @@ EXPORTS ?userPreferredLanguages@WebCore@@YA?AV?$Vector@VString@WTF@@$0A@@WTF@@XZ ?utf8@String@WTF@@QBE?AVCString@2@_N@Z ?view@Document@WebCore@@QBEPAVFrameView@2@XZ - ?willDetachPage@FrameDestructionObserver@WebCore@@UAEXXZ ??1ContextDestructionObserver@WebCore@@MAE@XZ ?contextDestroyed@ContextDestructionObserver@WebCore@@UAEXXZ ??0ContextDestructionObserver@WebCore@@QAE@PAVScriptExecutionContext@1@@Z @@ -278,3 +273,4 @@ EXPORTS ?jsStringSlowCase@WebCore@@YA?AVJSValue@JSC@@PAVExecState@3@AAV?$HashMap@PAVStringImpl@WTF@@V?$Weak@VJSString@JSC@@@JSC@@U?$PtrHash@PAVStringImpl@WTF@@@2@U?$HashTraits@PAVStringImpl@WTF@@@2@U?$HashTraits@V?$Weak@VJSString@JSC@@@JSC@@@2@@WTF@@PAVStringImpl@6@@Z ?registerURLSchemeAsBypassingContentSecurityPolicy@SchemeRegistry@WebCore@@SAXABVString@WTF@@@Z ?removeURLSchemeRegisteredAsBypassingContentSecurityPolicy@SchemeRegistry@WebCore@@SAXABVString@WTF@@@Z + ?iconURLs@Document@WebCore@@QAEABV?$Vector@UIconURL@WebCore@@$0A@@WTF@@XZ
\ No newline at end of file diff --git a/Source/WebKit2/win/WebKit2CFLite.def b/Source/WebKit2/win/WebKit2CFLite.def index fb51f6223..0e5d1b2c7 100644 --- a/Source/WebKit2/win/WebKit2CFLite.def +++ b/Source/WebKit2/win/WebKit2CFLite.def @@ -146,8 +146,6 @@ EXPORTS ??1ClientRectList@WebCore@@QAE@XZ ??0String@WTF@@QAE@PBD@Z ??0String@WTF@@QAE@PB_W@Z - ??1FrameDestructionObserver@WebCore@@MAE@XZ - ??0FrameDestructionObserver@WebCore@@QAE@PAVFrame@1@@Z ??1ContextDestructionObserver@WebCore@@MAE@XZ ?contextDestroyed@ContextDestructionObserver@WebCore@@UAEXXZ ??0ContextDestructionObserver@WebCore@@QAE@PAVScriptExecutionContext@1@@Z @@ -170,7 +168,6 @@ EXPORTS ?externalRepresentation@WebCore@@YA?AVString@WTF@@PAVElement@1@I@Z ?find@StringImpl@WTF@@QAEIPAV12@I@Z ?find@StringImpl@WTF@@QAEIPAV12@@Z - ?frameDestroyed@FrameDestructionObserver@WebCore@@UAEXXZ ?absoluteCaretBounds@FrameSelection@WebCore@@QAE?AVIntRect@2@XZ ?fromUTF8WithLatin1Fallback@String@WTF@@SA?AV12@PBEI@Z ?getCachedDOMStructure@WebCore@@YAPAVStructure@JSC@@PAVJSDOMGlobalObject@1@PBUClassInfo@3@@Z @@ -193,7 +190,6 @@ EXPORTS ?previous@ComposedShadowTreeWalker@WebCore@@QAEXXZ ?number@String@WTF@@SA?AV12@I@Z ?number@String@WTF@@SA?AV12@H@Z - ?observeFrame@FrameDestructionObserver@WebCore@@IAEXPAVFrame@2@@Z ?overrideUserPreferredLanguages@WebCore@@YAXABV?$Vector@VString@WTF@@$0A@@WTF@@@Z ?numberOfScopedHTMLStyleChildren@Node@WebCore@@QBEIXZ ?page@Document@WebCore@@QBEPAVPage@2@XZ @@ -250,7 +246,6 @@ EXPORTS ?userPreferredLanguages@WebCore@@YA?AV?$Vector@VString@WTF@@$0A@@WTF@@XZ ?utf8@String@WTF@@QBE?AVCString@2@_N@Z ?view@Document@WebCore@@QBEPAVFrameView@2@XZ - ?willDetachPage@FrameDestructionObserver@WebCore@@UAEXXZ ?nodesFromRect@Document@WebCore@@QBE?AV?$PassRefPtr@VNodeList@WebCore@@@WTF@@HHIIII_N0@Z ?selectionStartHasMarkerFor@Editor@WebCore@@QBE_NW4MarkerType@DocumentMarker@2@HH@Z ?restrictScaleFactorToInitialScaleIfNotUserScalable@WebCore@@YAXAAUViewportAttributes@1@@Z diff --git a/Source/api.pri b/Source/api.pri index 00c9fe1aa..61984d244 100644 --- a/Source/api.pri +++ b/Source/api.pri @@ -77,7 +77,7 @@ runSyncQt() # Generate forwarding headers for the QtWebKit API WEBKIT += wtf -!v8:WEBKIT += javascriptcore +WEBKIT += javascriptcore WEBKIT += webcore diff --git a/Source/autotools/symbols.filter b/Source/autotools/symbols.filter index 48e9505a6..5def47471 100644 --- a/Source/autotools/symbols.filter +++ b/Source/autotools/symbols.filter @@ -37,6 +37,7 @@ _ZN7WebCore4toJSEPN3JSC9ExecStateEPNS_17JSDOMGlobalObjectEPNS_5RangeE; _ZN7WebCore5Range6createEN3WTF10PassRefPtrINS_8DocumentEEENS2_INS_4NodeEEEiS6_i; _ZN7WebCore5RangeD1Ev; _ZN7WebCore8Document36updateLayoutIgnorePendingStylesheetsEv; +_ZN7WebCore8Document8iconURLsEv; _ZN7WebCore9HTMLNames8inputTagE; _ZN7WebCore9HTMLNames11textareaTagE; _ZN7WebCore10JSDocument10putVirtualEPN3JSC9ExecStateERKNS1_10IdentifierENS1_7JSValueERNS1_15PutPropertySlotE; @@ -148,11 +149,6 @@ _ZN7WebCore8Settings24setMockScrollbarsEnabledEb; _ZN7WebCore8Settings37setFixedElementsLayoutRelativeToFrameEb; _ZN7WebCore9FrameView17paintControlTintsEv; _ZN7WebCore9FrameView19scrollElementToRectEPNS_7ElementERKNS_7IntRectE; -_ZN7WebCore24FrameDestructionObserverD2Ev; -_ZN7WebCore24FrameDestructionObserverC2EPNS_5FrameE; -_ZN7WebCore24FrameDestructionObserver12observeFrameEPNS_5FrameE; -_ZN7WebCore24FrameDestructionObserver14frameDestroyedEv; -_ZN7WebCore24FrameDestructionObserver14willDetachPageEv; _ZN7WebCore22RuntimeEnabledFeatures31isMultipleShadowSubtreesEnabledE; _ZN7WebCore22RuntimeEnabledFeatures32setMultipleShadowSubtreesEnabledEb; _ZN7WebCore22RuntimeEnabledFeatures18isShadowDOMEnabledE; diff --git a/Source/cmake/WebKitFeatures.cmake b/Source/cmake/WebKitFeatures.cmake index 2e93826f6..eb2631597 100644 --- a/Source/cmake/WebKitFeatures.cmake +++ b/Source/cmake/WebKitFeatures.cmake @@ -24,6 +24,7 @@ MACRO (WEBKIT_OPTION_BEGIN) WEBKIT_OPTION_DEFINE(ENABLE_CSS_BOX_DECORATION_BREAK "Toggle Box Decoration Break (CSS Backgrounds and Borders) support" ON) WEBKIT_OPTION_DEFINE(ENABLE_CSS_EXCLUSIONS "Toggle CSS Exclusion support" OFF) WEBKIT_OPTION_DEFINE(ENABLE_CSS_FILTERS "Toggle CSS Filters support" OFF) + WEBKIT_OPTION_DEFINE(ENABLE_CSS_IMAGE_ORIENTATION "Toggle CSS image-orientation support" OFF) WEBKIT_OPTION_DEFINE(ENABLE_CSS_IMAGE_RESOLUTION "Toggle CSS image-resolution support" OFF) WEBKIT_OPTION_DEFINE(ENABLE_CSS_IMAGE_SET "Toggle CSS image-set support" OFF) WEBKIT_OPTION_DEFINE(ENABLE_CSS_REGIONS "Toggle CSS regions support" OFF) diff --git a/Source/cmake/gtest/CMakeLists.txt b/Source/cmake/gtest/CMakeLists.txt index eb123c671..adf064705 100644 --- a/Source/cmake/gtest/CMakeLists.txt +++ b/Source/cmake/gtest/CMakeLists.txt @@ -11,7 +11,7 @@ INCLUDE_DIRECTORIES(${THIRDPARTY_DIR}/gtest SET(GTEST_DIR "${THIRDPARTY_DIR}/gtest") -ADD_LIBRARY(gtest +ADD_LIBRARY(gtest SHARED ${GTEST_DIR}/src/gtest.cc ${GTEST_DIR}/src/gtest-death-test.cc ${GTEST_DIR}/src/gtest-filepath.cc @@ -20,3 +20,14 @@ ADD_LIBRARY(gtest ${GTEST_DIR}/src/gtest-test-part.cc ${GTEST_DIR}/src/gtest-typed-test.cc ) + +ADD_DEFINITIONS(-DGTEST_CREATE_SHARED_LIBRARY=1) + +TARGET_LINK_LIBRARIES(gtest + ${WTF_LIBRARY_NAME} +) + +IF(CMAKE_USE_PTHREADS_INIT) + TARGET_LINK_LIBRARIES(gtest ${CMAKE_THREAD_LIBS_INIT}) + ADD_DEFINITIONS(-DGTEST_HAS_PTHREAD=1) +ENDIF() diff --git a/Source/cmakeconfig.h.cmake b/Source/cmakeconfig.h.cmake index 035bd10eb..a12e43a24 100644 --- a/Source/cmakeconfig.h.cmake +++ b/Source/cmakeconfig.h.cmake @@ -18,6 +18,7 @@ #cmakedefine01 ENABLE_CSS3_FLEXBOX #cmakedefine01 ENABLE_CSS_BOX_DECORATION_BREAK #cmakedefine01 ENABLE_CSS_EXCLUSIONS +#cmakedefine01 ENABLE_CSS_IMAGE_ORIENTATION #cmakedefine01 ENABLE_CSS_IMAGE_RESOLUTION #cmakedefine01 ENABLE_CSS_IMAGE_SET #cmakedefine01 ENABLE_CSS_REGIONS diff --git a/Tools/ChangeLog b/Tools/ChangeLog index a605a49c9..5ed428bc0 100644 --- a/Tools/ChangeLog +++ b/Tools/ChangeLog @@ -1,43 +1,1159 @@ +2012-07-18 Simon Hausmann <simon.hausmann@nokia.com> + + [ANGLE] On QT, use Bison and Flex during ANGLE build + https://bugs.webkit.org/show_bug.cgi?id=91108 + + Reviewed by Kenneth Rohde Christiansen. + + * qmake/mkspecs/features/default_post.prf: Add support for variable_out to our generators, to allow + generating not only for SOURCES but also ANGLE_SOURCES (in this bug) + +2012-07-18 Balazs Kelemen <kbalazs@webkit.org> + + [Qt] plugin tests should not be disabled for WebKit1 + https://bugs.webkit.org/show_bug.cgi?id=91604 + + Reviewed by Simon Hausmann. + + Instead of not building TestNetscapePlugIn, we could programatically + disable actually loading it from WTR until https://bugs.webkit.org/show_bug.cgi?id=86620 + has been solved, so we can still test plugins on WebKit1. + + * Tools.pro: + * WebKitTestRunner/TestController.cpp: + (WTR::TestController::initialize): + * WebKitTestRunner/qt/TestControllerQt.cpp: + (WTR::TestController::initializeTestPluginDirectory): + +2012-07-18 Mario Sanchez Prada <msanchez@igalia.com> + + [WK2][GTK] Implement AccessibilityUIElement in WKTR for GTK + https://bugs.webkit.org/show_bug.cgi?id=89223 + + Reviewed by Chris Fleizach. + + Implemented AccessibilityUIElement in WKTR for GTK, based in the + implementation present in DumpRenderTree. + + Added new files in gtk/ and updated the cross-platform ones. + + * WebKitTestRunner/GNUmakefile.am: + * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp: + (WTR): + * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h: + (AccessibilityUIElement): + * WebKitTestRunner/InjectedBundle/gtk/AccessibilityUIElementGtk.cpp: Added. + (WTR): + (WTR::attributeSetToString): + (WTR::checkElementState): + (WTR::indexRangeInTable): + (WTR::alterCurrentValue): + (WTR::AccessibilityUIElement::AccessibilityUIElement): + (WTR::AccessibilityUIElement::~AccessibilityUIElement): + (WTR::AccessibilityUIElement::isEqual): + (WTR::AccessibilityUIElement::getChildren): + (WTR::AccessibilityUIElement::getChildrenWithRange): + (WTR::AccessibilityUIElement::childrenCount): + (WTR::AccessibilityUIElement::elementAtPoint): + (WTR::AccessibilityUIElement::indexOfChild): + (WTR::AccessibilityUIElement::childAtIndex): + (WTR::AccessibilityUIElement::linkedUIElementAtIndex): + (WTR::AccessibilityUIElement::ariaOwnsElementAtIndex): + (WTR::AccessibilityUIElement::ariaFlowToElementAtIndex): + (WTR::AccessibilityUIElement::disclosedRowAtIndex): + (WTR::AccessibilityUIElement::rowAtIndex): + (WTR::AccessibilityUIElement::selectedChildAtIndex): + (WTR::AccessibilityUIElement::selectedChildrenCount): + (WTR::AccessibilityUIElement::selectedRowAtIndex): + (WTR::AccessibilityUIElement::titleUIElement): + (WTR::AccessibilityUIElement::parentElement): + (WTR::AccessibilityUIElement::disclosedByRow): + (WTR::AccessibilityUIElement::attributesOfLinkedUIElements): + (WTR::AccessibilityUIElement::attributesOfDocumentLinks): + (WTR::AccessibilityUIElement::attributesOfChildren): + (WTR::AccessibilityUIElement::allAttributes): + (WTR::AccessibilityUIElement::stringAttributeValue): + (WTR::AccessibilityUIElement::numberAttributeValue): + (WTR::AccessibilityUIElement::uiElementAttributeValue): + (WTR::AccessibilityUIElement::boolAttributeValue): + (WTR::AccessibilityUIElement::isAttributeSettable): + (WTR::AccessibilityUIElement::isAttributeSupported): + (WTR::AccessibilityUIElement::parameterizedAttributeNames): + (WTR::AccessibilityUIElement::role): + (WTR::AccessibilityUIElement::subrole): + (WTR::AccessibilityUIElement::roleDescription): + (WTR::AccessibilityUIElement::title): + (WTR::AccessibilityUIElement::description): + (WTR::AccessibilityUIElement::orientation): + (WTR::AccessibilityUIElement::stringValue): + (WTR::AccessibilityUIElement::language): + (WTR::AccessibilityUIElement::helpText): + (WTR::AccessibilityUIElement::x): + (WTR::AccessibilityUIElement::y): + (WTR::AccessibilityUIElement::width): + (WTR::AccessibilityUIElement::height): + (WTR::AccessibilityUIElement::clickPointX): + (WTR::AccessibilityUIElement::clickPointY): + (WTR::AccessibilityUIElement::intValue): + (WTR::AccessibilityUIElement::minValue): + (WTR::AccessibilityUIElement::maxValue): + (WTR::AccessibilityUIElement::valueDescription): + (WTR::AccessibilityUIElement::insertionPointLineNumber): + (WTR::AccessibilityUIElement::isActionSupported): + (WTR::AccessibilityUIElement::isEnabled): + (WTR::AccessibilityUIElement::isRequired): + (WTR::AccessibilityUIElement::isFocused): + (WTR::AccessibilityUIElement::isSelected): + (WTR::AccessibilityUIElement::isExpanded): + (WTR::AccessibilityUIElement::isChecked): + (WTR::AccessibilityUIElement::hierarchicalLevel): + (WTR::AccessibilityUIElement::speak): + (WTR::AccessibilityUIElement::ariaIsGrabbed): + (WTR::AccessibilityUIElement::ariaDropEffects): + (WTR::AccessibilityUIElement::lineForIndex): + (WTR::AccessibilityUIElement::rangeForLine): + (WTR::AccessibilityUIElement::rangeForPosition): + (WTR::AccessibilityUIElement::boundsForRange): + (WTR::AccessibilityUIElement::stringForRange): + (WTR::AccessibilityUIElement::attributedStringForRange): + (WTR::AccessibilityUIElement::attributedStringRangeIsMisspelled): + (WTR::AccessibilityUIElement::uiElementForSearchPredicate): + (WTR::AccessibilityUIElement::attributesOfColumnHeaders): + (WTR::AccessibilityUIElement::attributesOfRowHeaders): + (WTR::AccessibilityUIElement::attributesOfColumns): + (WTR::AccessibilityUIElement::attributesOfRows): + (WTR::AccessibilityUIElement::attributesOfVisibleCells): + (WTR::AccessibilityUIElement::attributesOfHeader): + (WTR::AccessibilityUIElement::rowCount): + (WTR::AccessibilityUIElement::columnCount): + (WTR::AccessibilityUIElement::indexInTable): + (WTR::AccessibilityUIElement::rowIndexRange): + (WTR::AccessibilityUIElement::columnIndexRange): + (WTR::AccessibilityUIElement::cellForColumnAndRow): + (WTR::AccessibilityUIElement::horizontalScrollbar): + (WTR::AccessibilityUIElement::verticalScrollbar): + (WTR::AccessibilityUIElement::selectedTextRange): + (WTR::AccessibilityUIElement::setSelectedTextRange): + (WTR::AccessibilityUIElement::increment): + (WTR::AccessibilityUIElement::decrement): + (WTR::AccessibilityUIElement::showMenu): + (WTR::AccessibilityUIElement::press): + (WTR::AccessibilityUIElement::setSelectedChild): + (WTR::AccessibilityUIElement::accessibilityValue): + (WTR::AccessibilityUIElement::documentEncoding): + (WTR::AccessibilityUIElement::documentURI): + (WTR::AccessibilityUIElement::url): + (WTR::AccessibilityUIElement::addNotificationListener): + (WTR::AccessibilityUIElement::removeNotificationListener): + (WTR::AccessibilityUIElement::isFocusable): + (WTR::AccessibilityUIElement::isSelectable): + (WTR::AccessibilityUIElement::isMultiSelectable): + (WTR::AccessibilityUIElement::isVisible): + (WTR::AccessibilityUIElement::isOffScreen): + (WTR::AccessibilityUIElement::isCollapsed): + (WTR::AccessibilityUIElement::isIgnored): + (WTR::AccessibilityUIElement::hasPopup): + (WTR::AccessibilityUIElement::takeFocus): + (WTR::AccessibilityUIElement::takeSelection): + (WTR::AccessibilityUIElement::addSelection): + (WTR::AccessibilityUIElement::removeSelection): + (WTR::AccessibilityUIElement::textMarkerRangeForElement): + (WTR::AccessibilityUIElement::textMarkerRangeLength): + (WTR::AccessibilityUIElement::previousTextMarker): + (WTR::AccessibilityUIElement::nextTextMarker): + (WTR::AccessibilityUIElement::stringForTextMarkerRange): + (WTR::AccessibilityUIElement::textMarkerRangeForMarkers): + (WTR::AccessibilityUIElement::startTextMarkerForTextMarkerRange): + (WTR::AccessibilityUIElement::endTextMarkerForTextMarkerRange): + (WTR::AccessibilityUIElement::textMarkerForPoint): + (WTR::AccessibilityUIElement::accessibilityElementForTextMarker): + (WTR::AccessibilityUIElement::attributedStringForTextMarkerRangeContainsAttribute): + (WTR::AccessibilityUIElement::indexForTextMarker): + (WTR::AccessibilityUIElement::isTextMarkerValid): + (WTR::AccessibilityUIElement::textMarkerForIndex): + + Add documentEncoding and documentURI to AccessibilityUIElement.idl. + + * WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl: + +2012-07-18 Alexis Menard <alexis.menard@openbossa.org> + + [EFL] Build fix in WebKitTestRunner. + https://bugs.webkit.org/show_bug.cgi?id=91567 + + Reviewed by Kentaro Hara. + + sleep() is defined in unistd.h, we need to include it. + + * WebKitTestRunner/efl/TestControllerEfl.cpp: + +2012-07-18 Kristóf Kosztyó <kkristof@inf.u-szeged.hu> + + [NRWT] Unreviewed gardening after r122913 + https://bugs.webkit.org/show_bug.cgi?id=91601 + + * Scripts/webkitpy/layout_tests/port/server_process_unittest.py: + (TrivialMockPort.process_kill_time): + +2012-07-17 Xianzhu Wang <wangxianzhu@chromium.org> + + [Chromium-Android] Run ref tests together to avoid expensive driver restarts + https://bugs.webkit.org/show_bug.cgi?id=91533 + + Reviewed by Dirk Pranke. + + Though DriverProxy maintains two drivers to support pixel tests and non-pixel tests, + chromium-android uses another way because it can't support multiple drivers. + It restarts the driver when pixel-test mode changes (e.g. when running a ref test after + a normal test in --no-pixel-tests mode). However restarting driver is expensive on + Android (several seconds each time). To reduce the cost, a command line option + '--shard-ref-tests' is added to group ref tests in dedicated shards. + The option is by default enabled on Android. + + Will remove the option once DRT supports switching pixel test mode during one run. + (https://bugs.webkit.org/show_bug.cgi?id=91538, https://bugs.webkit.org/show_bug.cgi?id=91539) + + * Scripts/webkitpy/layout_tests/controllers/manager.py: + (Manager._shard_tests): + (Manager._shard_in_two): + (Manager._shard_by_directory): + (Manager._run_tests): + * Scripts/webkitpy/layout_tests/controllers/worker.py: + (Worker._update_test_input): + * Scripts/webkitpy/layout_tests/port/chromium_android.py: + (ChromiumAndroidPort.__init__): + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + (parse_args): + +2012-07-17 Don Olmstead <don.olmstead@am.sony.com> + + NRWT The time before server_process kills DRT should be variable + https://bugs.webkit.org/show_bug.cgi?id=91542 + + Reviewed by Dirk Pranke. + + Added the ability to configure the amount of time + server_process waits before killing the DRT process + during the call to stop. + + * Scripts/webkitpy/layout_tests/port/base.py: + (Port.variable.process_kill_time): + * Scripts/webkitpy/layout_tests/port/server_process.py: + (ServerProcess.stop): + +2012-07-17 Alexis Menard <alexis.menard@openbossa.org> + + webkitdirs.pm should fallback to uname -m if arch is not present. + https://bugs.webkit.org/show_bug.cgi?id=91543 + + Reviewed by Martin Robinson. + + It seems that coreutils is moving away from the 'arch' command. Archlinux + for example doesn't ship it anymore (coreutils 8.17). We can then fallback + to 'uname -m' to find out the architecture. + + * Scripts/webkitdirs.pm: + (determineArchitecture): + +2012-07-17 Dirk Pranke <dpranke@chromium.org> + + nrwt: rename printer.print_update to printer.write_update to match metered_stream + https://bugs.webkit.org/show_bug.cgi?id=91557 + + Reviewed by Ojan Vafai. + + Now that all of the printing logic is in printer.py, I want the + public interface to printer to follow the meteredstream + interface where possible. renaming write_update() gets us close. + + * Scripts/webkitpy/layout_tests/controllers/manager.py: + (Manager._run_tests): + (Manager._set_up_run): + (Manager.start_servers_with_lock): + (Manager.stop_servers_with_lock): + (Manager._clobber_old_results): + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + (run): + * Scripts/webkitpy/layout_tests/views/printing.py: + (Printer.write_update): + * Scripts/webkitpy/layout_tests/views/printing_unittest.py: + (Testprinter.test_write_update): + +2012-07-17 Tony Chang <tony@chromium.org> + + Fix a bug where optimize-baselines would incorrectly fail to optimize + https://bugs.webkit.org/show_bug.cgi?id=91551 + + Reviewed by Adam Barth. + + In some cases, optimize-baseline would correctly optimize the results, but because + we weren't filtering the virtual ports out of _results_by_port_name, we thought + that we had failed to optimize. + + * Scripts/webkitpy/common/checkout/baselineoptimizer.py: + (BaselineOptimizer._find_optimal_result_placement): No virtual filtering here. + (BaselineOptimizer._filtered_results_by_port_name): New function that filters out virtual directories. + (BaselineOptimizer.optimize): Filter out virtual ports. + * Scripts/webkitpy/common/checkout/baselineoptimizer_unittest.py: + (TestBaselineOptimizer._move_baselines): Add a stub so we don't actual move results. + (BaselineOptimizerTest._assertOptimization): Call optimize and verify that the right files were moved. + (BaselineOptimizerTest._assertOptimizationFailed): Add a method for when optimization should fail. + (BaselineOptimizerTest.test_common_directory_includes_root): Update since this test should fail. + (BaselineOptimizerTest.test_virtual_ports_filtered): New test case that demonstrates the bug. + +2012-07-17 Xianzhu Wang <wangxianzhu@chromium.org> + + [Chromium] Add --encode-binary command line option for DRT + https://bugs.webkit.org/show_bug.cgi?id=91532 + + Reviewed by Adam Barth. + + When the option presents, DRT will encode binary output data in base64. + ChromiumAndroidPort will pass the option because 'adb shell' doesn't support + binary data output. + + This change is a refactoring to replace the original hard-coded code for Android. + + * DumpRenderTree/chromium/DumpRenderTree.cpp: + (main): + * DumpRenderTree/chromium/TestEventPrinter.cpp: + (TestEventPrinter::TestEventPrinter): + (TestEventPrinter::handleAudio): New function replacing the original handleAudioHeader + (TestEventPrinter::handleImage): + (TestEventPrinter::handleBinary): Extracted common function for handleAudio and handleImage + * DumpRenderTree/chromium/TestEventPrinter.h: + (TestEventPrinter): + * DumpRenderTree/chromium/TestShell.cpp: + (TestShell::TestShell): + (TestShell::initialize): + (TestShell::dump): + * DumpRenderTree/chromium/TestShell.h: + (TestShell): + (TestShell::setEncodeBinary): + * Scripts/webkitpy/layout_tests/port/chromium_android.py: Add --encode-binary to additional_drt_flags + (ChromiumAndroidPort.__init__): + +2012-07-17 Dirk Pranke <dpranke@chromium.org> + + nrwt: move per-test result output into printing.py + https://bugs.webkit.org/show_bug.cgi?id=91465 + + Reviewed by Ojan Vafai. + + This moves the last substantive logging/printing code from the + manager into printing.py. Subsequent patches in this thread can + largely focus on cleaning up printing.py and will leave the rest + of the code alone. + + This patch also removes manager.update() and + manager.update_summary(), two routines that were no longer being + used or needed (they have been dead for a long time but I didn't + notice them until now). + + * Scripts/webkitpy/layout_tests/controllers/manager.py: + (Manager.results_directory): + (Manager._look_for_new_crash_logs): + (Manager._update_summary_with_result): + * Scripts/webkitpy/layout_tests/views/printing.py: + (Printer.print_finished_test): + +2012-07-17 Dirk Pranke <dpranke@chromium.org> + + nrwt: move config-specific logging to printing.py + https://bugs.webkit.org/show_bug.cgi?id=91450 + + Reviewed by Ojan Vafai. + + More refactoring ... this moves the 'config' output to + printing.py. + + * Scripts/webkitpy/layout_tests/controllers/manager.py: + (Manager._resize_shards): + (Manager._run_tests): + (Manager._upload_json_files): + * Scripts/webkitpy/layout_tests/controllers/manager_unittest.py: + (ManagerTest.get_options): + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: + (run): + * Scripts/webkitpy/layout_tests/views/printing.py: + (Printer.print_config): + (Printer.print_workers_and_shards): + (Printer._print_config): + * Scripts/webkitpy/layout_tests/views/printing_unittest.py: + (Testprinter.test_fallback_path_in_config): + (Testprinter.test_print_config): + +2012-07-17 Dirk Pranke <dpranke@chromium.org> + + nrwt: clean up logging when we're only running one chunk of the tests + https://bugs.webkit.org/show_bug.cgi?id=91447 + + Reviewed by Ojan Vafai. + + Apparently we were creating a 'tests_run.txt' in the results + directory if we were only running one chunk of the tests; after + 3+ years of hacking on this code, that was news to me, so I'm + guessing no one uses this. I'm removing this, and changing the + _print_expected calls to debug messages to simplify the + layering. + + * Scripts/webkitpy/layout_tests/controllers/manager.py: + (Manager._split_into_chunks_if_necessary): + +2012-07-17 Dirk Pranke <dpranke@chromium.org> + + Fix regression in style checker introduced in r122868. + https://bugs.webkit.org/show_bug.cgi?id=91470 + + Unreviewed, build fix. + + * Scripts/webkitpy/style/checkers/cpp.py: + (_FileState.__init__): + +2012-07-17 Dirk Pranke <dpranke@chromium.org> + + nrwt: move the bulk of the "expected" output to printing.py + https://bugs.webkit.org/show_bug.cgi?id=91442 + + Reviewed by Ojan Vafai. + + More printing-related refactoring. This moves all of the code + that prints the results we expect to get, but doesn't move a few + dangling printfs (those'll get hit in a later patch). + + No functional changes; covered by existing tests. + + * Scripts/webkitpy/layout_tests/controllers/manager.py: + (Manager._split_into_chunks_if_necessary): + (Manager.prepare_lists_and_print_output): + (Manager.print_config): + * Scripts/webkitpy/layout_tests/views/printing.py: + (Printer.print_expected): + (Printer): + (Printer._print_expected_results_of_type): + (Printer._num_digits): + (Printer._print_expected): + * Scripts/webkitpy/layout_tests/views/printing_unittest.py: + (Testprinter.test_print_expected): + +2012-07-17 Christophe Dumez <christophe.dumez@intel.com> + + [EFL] Replace 0 by NULL in public headers documentation + https://bugs.webkit.org/show_bug.cgi?id=91470 + + Reviewed by Dirk Pranke. + + Fix style checking to properly detect C headers as C + files. Without this change, the style script would + complain if we use NULL (instead of 0 / null) in C + headers. + + * Scripts/webkitpy/style/checkers/cpp.py: + (_FileState.__init__): + (_FileState.is_c): + (_FileState.is_c_or_objective_c): + +2012-07-17 Xianzhu Wang <wangxianzhu@chromium.org> + + [chromium] remove --test-shell support from DRT + https://bugs.webkit.org/show_bug.cgi?id=86927 + + Reviewed by Adam Barth. + + Now no one use --test-shell. All of us use the standard DRT mode. + + * DumpRenderTree/chromium/DumpRenderTree.cpp: Removed support of --test-shell and --pixel-tests=filename options. (--pixel-tests without '=' is kept for DRT mode.) + (runTest): + (main): + * DumpRenderTree/chromium/TestEventPrinter.cpp: + (TestEventPrinter::TestEventPrinter): + (TestEventPrinter::~TestEventPrinter): + (TestEventPrinter::handleTestHeader): + (TestEventPrinter::handleTimedOut): + (TestEventPrinter::handleTextHeader): + (TestEventPrinter::handleTextFooter): + (TestEventPrinter::handleAudioHeader): + (TestEventPrinter::handleAudioFooter): + (TestEventPrinter::handleImage): Removed the unused filename parameter. + (TestEventPrinter::handleTestFooter): + * DumpRenderTree/chromium/TestEventPrinter.h: + (TestEventPrinter): Made it a concrete class because we have only one implementation. + * DumpRenderTree/chromium/TestShell.cpp: + (TestShell::TestShell): + (TestShell::initialize): + (TestShell::dumpImage): + * DumpRenderTree/chromium/TestShell.h: + (TestParams): Removed pixelFileName field. + (TestShell): + +2012-07-17 Xianzhu Wang <wangxianzhu@chromium.org> + + remove ChromiumDriver from NRWT + https://bugs.webkit.org/show_bug.cgi?id=88478 + + Now WebKitDriver has replaced ChromiumDriver since test_shell mode is deperecated. + + Reviewed by Dirk Pranke. + + * Scripts/webkitpy/layout_tests/port/chromium.py: Removed ChromiumDriver code. + (ChromiumPort._driver_class): Removed. WebKitPort._driver_class() will be used. + * Scripts/webkitpy/layout_tests/port/chromium_unittest.py: + +2012-07-17 No'am Rosenthal <noam.rosenthal@nokia.com> + + Unreviewed. Add QtGraphics, TextureMapper and OpenGL to watchlist. + + * Scripts/webkitpy/common/config/watchlist: + +2012-07-17 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r122828. + http://trac.webkit.org/changeset/122828 + https://bugs.webkit.org/show_bug.cgi?id=91516 + + DumpRenderTree crashes after printing test results. (Requested + by vsevik on #webkit). + + * DumpRenderTree/chromium/TestRunner/TestInterfaces.cpp: + (TestInterfaces::TestInterfaces): + (TestInterfaces::~TestInterfaces): + (TestInterfaces::bindTo): + (TestInterfaces::resetAll): + * DumpRenderTree/chromium/TestRunner/TestInterfaces.h: + (TestInterfaces): + * DumpRenderTree/chromium/TestShell.cpp: + (TestShell::initialize): + (TestShell::createMainWindow): + (TestShell::~TestShell): + (TestShell::resetTestController): + (TestShell::bindJSObjectsToWindow): + * DumpRenderTree/chromium/TestShell.h: + (TestShell::accessibilityController): + (TestShell): + +2012-07-17 Gabor Ballabas <gaborb@inf.u-szeged.hu> + + [Qt][V8] Remove the V8 related codepaths and configuration + https://bugs.webkit.org/show_bug.cgi?id=90863 + + Reviewed by Simon Hausmann. + + * Scripts/build-webkit: Remove --v8 option. + +2012-07-17 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r122834. + http://trac.webkit.org/changeset/122834 + https://bugs.webkit.org/show_bug.cgi?id=91492 + + it broke the chromium (Requested by kkristof on #webkit). + + * Scripts/build-webkit: + +2012-07-17 Gabor Ballabas <gaborb@inf.u-szeged.hu> + + [Qt][V8] Remove the V8 related codepaths and configuration + https://bugs.webkit.org/show_bug.cgi?id=90863 + + Reviewed by Simon Hausmann. + + * Scripts/build-webkit: Remove --v8 option. + +2012-07-17 Balazs Kelemen <kbalazs@webkit.org> + + [Qt] Add --use-test-fonts option to Minibrowser + https://bugs.webkit.org/show_bug.cgi?id=91402 + + Reviewed by Tor Arne Vestbø. + + Same stuff that already exists for QtTestBrowser. + + * MiniBrowser/qt/MiniBrowser.pro: + * MiniBrowser/qt/MiniBrowserApplication.cpp: + (MiniBrowserApplication::handleUserOptions): + +2012-07-17 Adam Barth <abarth@webkit.org> + + [Chromium] TestInterfaces should be responsible for owning and binding AccessibilityController and TextInputController + https://bugs.webkit.org/show_bug.cgi?id=91459 + + Reviewed by Ryosuke Niwa. + + Rather than having TestShell own and bind each of these JavaScript APIs + individually, TestShell should delegate that work to TestInterfaces. + This patch moves AccessibilityController and TextInputController to be + the responsibility of TestInterfaces. + + * DumpRenderTree/chromium/TestRunner/TestInterfaces.cpp: + (TestInterfaces::TestInterfaces): + (TestInterfaces::~TestInterfaces): + (TestInterfaces::setWebView): + (TestInterfaces::bindTo): + (TestInterfaces::resetAll): + * DumpRenderTree/chromium/TestRunner/TestInterfaces.h: + (WebKit): + (TestInterfaces): + (TestInterfaces::accessibilityController): + * DumpRenderTree/chromium/TestShell.cpp: + (TestShell::initialize): + (TestShell::createMainWindow): + (TestShell::~TestShell): + (TestShell::resetTestController): + (TestShell::bindJSObjectsToWindow): + * DumpRenderTree/chromium/TestShell.h: + (TestShell::accessibilityController): + (TestShell): + +2012-07-17 Adam Barth <abarth@webkit.org> + + [Chromium] Move TextInputController into TestRunner.a + https://bugs.webkit.org/show_bug.cgi?id=91457 + + Reviewed by Ryosuke Niwa. + + This patch is purely moving code. TextInputController is one of the + objects exposed to JavaScript and so should be in the TestRunner + library. + + * DumpRenderTree/DumpRenderTree.gypi: + * DumpRenderTree/chromium/TestRunner/TextInputController.cpp: Renamed from Tools/DumpRenderTree/chromium/TextInputController.cpp. + * DumpRenderTree/chromium/TestRunner/TextInputController.h: Renamed from Tools/DumpRenderTree/chromium/TextInputController.h. + +2012-07-17 Adam Barth <abarth@webkit.org> + + [Chromium] TextInputController shouldn't know about TestShell + https://bugs.webkit.org/show_bug.cgi?id=91455 + + Reviewed by Kent Tamura. + + This patch uses the same pattern we used for the + AccessibilityController to remove the dependency on TestShell. + + * DumpRenderTree/chromium/TestShell.cpp: + (TestShell::initialize): + (TestShell::createMainWindow): + (TestShell::~TestShell): + * DumpRenderTree/chromium/TextInputController.cpp: + (TextInputController::TextInputController): + (TextInputController::insertText): + (TextInputController::doCommand): + (TextInputController::setMarkedText): + (TextInputController::unmarkText): + (TextInputController::hasMarkedText): + (TextInputController::markedRange): + (TextInputController::selectedRange): + (TextInputController::firstRectForCharacterRange): + (TextInputController::validAttributesForMarkedText): + (TextInputController::setComposition): + * DumpRenderTree/chromium/TextInputController.h: + (WebKit): + (TextInputController): + (TextInputController::setWebView): + +2012-07-17 David Barr <davidbarr@chromium.org> + + Introduce ENABLE_CSS_IMAGE_ORIENTATION compile flag + https://bugs.webkit.org/show_bug.cgi?id=89055 + + Reviewed by Kent Tamura. + + The css3-images module is at candidate recommendation. + http://www.w3.org/TR/2012/CR-css3-images-20120417/#the-image-orientation + + Add a configuration option for CSS image-orientation support, disabling it by default. + + * Scripts/webkitperl/FeatureList.pm: + * qmake/mkspecs/features/features.pri: + +2012-07-16 Adam Barth <abarth@webkit.org> + + [Chromium] Move Task.(cpp|h) into TestRunner.a + https://bugs.webkit.org/show_bug.cgi?id=91446 + + Reviewed by Ryosuke Niwa. + + Task is a dependency of EventSender, which needs to move into TestRunner.a. + + * DumpRenderTree/DumpRenderTree.gypi: + * DumpRenderTree/chromium/TestRunner/Task.cpp: Renamed from Tools/DumpRenderTree/chromium/Task.cpp. + * DumpRenderTree/chromium/TestRunner/Task.h: Renamed from Tools/DumpRenderTree/chromium/Task.h. + +2012-07-16 Adam Barth <abarth@webkit.org> + + [Chromium] Move AccessibilityController and AccessibilityUIElement into TestRunner.a + https://bugs.webkit.org/show_bug.cgi?id=91443 + + Reviewed by Tony Chang. + + Purely a file move (and a sorting of #includes). + + * DumpRenderTree/DumpRenderTree.gypi: + * DumpRenderTree/chromium/TestRunner/AccessibilityController.cpp: Renamed from Tools/DumpRenderTree/chromium/AccessibilityController.cpp. + * DumpRenderTree/chromium/TestRunner/AccessibilityController.h: Renamed from Tools/DumpRenderTree/chromium/AccessibilityController.h. + * DumpRenderTree/chromium/TestRunner/AccessibilityUIElement.cpp: Renamed from Tools/DumpRenderTree/chromium/AccessibilityUIElement.cpp. + * DumpRenderTree/chromium/TestRunner/AccessibilityUIElement.h: Renamed from Tools/DumpRenderTree/chromium/AccessibilityUIElement.h. + +2012-07-16 Adam Barth <abarth@webkit.org> + + [Chromium] AccessibilityController shouldn't know anything about TestShell + https://bugs.webkit.org/show_bug.cgi?id=91441 + + Reviewed by Tony Chang. + + This patch is a precursor to moving AccessibilityController.cpp into TestRunner.a. + + * DumpRenderTree/chromium/AccessibilityController.cpp: + (AccessibilityController::AccessibilityController): + (AccessibilityController::getFocusedElement): + (AccessibilityController::getRootElement): + * DumpRenderTree/chromium/AccessibilityController.h: + (WebKit): + (AccessibilityController): + (AccessibilityController::setWebView): + * DumpRenderTree/chromium/TestShell.cpp: + (TestShell::initialize): + (TestShell::createMainWindow): + (TestShell::~TestShell): + +2012-07-16 Adam Barth <abarth@webkit.org> + + [Chromium] Introduce TestInterfaces to hold all the JavaScript interfaces needed for LayoutTests + https://bugs.webkit.org/show_bug.cgi?id=91312 + + Reviewed by Ryosuke Niwa. + + Looking forward to moving more objects into TestRunner.a, we're going + to need an object to own all the interfaces and to put them through + their lifecycle. + + * DumpRenderTree/DumpRenderTree.gypi: + * DumpRenderTree/chromium/TestShell.cpp: + (TestShell::initialize): + (TestShell::resetTestController): + (TestShell::bindJSObjectsToWindow): + * DumpRenderTree/chromium/TestShell.h: + (TestShell): + * DumpRenderTree/chromium/TestRunner/TestInterfaces.cpp: Added. + * DumpRenderTree/chromium/TestRunner/TestInterfaces.h: Added. + +2012-07-16 Ryuan Choi <ryuan.choi@samsung.com> + + [EFL][WK2] Add APIs to support theme. + https://bugs.webkit.org/show_bug.cgi?id=90107 + + Reviewed by Hajime Morita. + + Override default theme path for MiniBrowser and WebKitTestRunner. + + * MiniBrowser/efl/CMakeLists.txt: + * MiniBrowser/efl/main.c: + (browserCreate): + * WebKitTestRunner/PlatformEfl.cmake: + * WebKitTestRunner/efl/PlatformWebViewEfl.cpp: + (WTR::PlatformWebView::PlatformWebView): + +2012-07-16 Ryuan Choi <ryuan.choi@samsung.com> + + [EFL][DRT] Implement dumpFrameScrollPosition + https://bugs.webkit.org/show_bug.cgi?id=87638 + + Reviewed by Hajime Morita. + + * DumpRenderTree/efl/DumpRenderTree.cpp: + (dumpFrameScrollPosition): Implemented. + (shouldDumpFrameScrollPosition): Fixed wrong condition like other ports. + +2012-07-16 Don Olmstead <don.olmstead@am.sony.com> + + NRWRT Should provide a VS project to work on + https://bugs.webkit.org/show_bug.cgi?id=91436 + + Reviewed by Dirk Pranke. + + Adding VS2010 project for modifying webkitpy. Uses pytools + <http://pytools.codeplex.com> which integrates python into + Visual Studio. + + * Scripts/webkitpy/webkitpy.pyproj: Added. + * Scripts/webkitpy/webkitpy.sln: Added. + +2012-07-16 Adam Barth <abarth@webkit.org> + + [Chromium] Move GamepadController into TestRunner.a + https://bugs.webkit.org/show_bug.cgi?id=91311 + + Reviewed by Tony Chang. + + GamepadController looks like a simple class to move into TestRunner.a + because it has almost zero dependence on TestShell. + + * DumpRenderTree/DumpRenderTree.gyp/DumpRenderTree.gyp: + * DumpRenderTree/DumpRenderTree.gypi: + * DumpRenderTree/chromium/TestRunner/CppBoundClass.cpp: Renamed from Tools/DumpRenderTree/chromium/CppBoundClass.cpp. + * DumpRenderTree/chromium/TestRunner/CppBoundClass.h: Renamed from Tools/DumpRenderTree/chromium/CppBoundClass.h. + * DumpRenderTree/chromium/TestRunner/CppVariant.cpp: Renamed from Tools/DumpRenderTree/chromium/CppVariant.cpp. + * DumpRenderTree/chromium/TestRunner/CppVariant.h: Renamed from Tools/DumpRenderTree/chromium/CppVariant.h. + - GamepadController depends on these bindings helpers. + * DumpRenderTree/chromium/TestRunner/GamepadController.cpp: Renamed from Tools/DumpRenderTree/chromium/GamepadController.cpp. + * DumpRenderTree/chromium/TestRunner/GamepadController.h: Renamed from Tools/DumpRenderTree/chromium/GamepadController.h. + - Just moved these files and removed the unused TestShell + references. + * DumpRenderTree/chromium/TestRunner/Stub.cpp: Removed. + - No longer needed. + * DumpRenderTree/chromium/TestShell.cpp: + - Update call to constructor to avoid passing in this. + +2012-07-16 Xianzhu Wang <wangxianzhu@chromium.org> + + [Chromium-android] Don't use test_shell mode of DRT + https://bugs.webkit.org/show_bug.cgi?id=88542 + + Reviewed by Dirk Pranke. + + Test shell mode is about to be removed. + Switch to use DRT mode for chromium-android. + + Summary of changes: + 1. ChromiumAndroidDriver now inherits from WebKitDriver instead of ChromiumDriver (to be deprecated). + 2. Conforms to the DRT mode protocol for input/output of DumpRenderTree. + 3. Added support for Android 'adb shell' input/output (base64, newline mode, etc.) + + * DumpRenderTree/chromium/TestEventPrinter.cpp: + (DRTPrinter::handleImage): Outputs base64 on Android. + * DumpRenderTree/chromium/TestShellAndroid.cpp: + (platformInit): Changed err_file to err_fifo, required by python ServerProcess. + * Scripts/webkitpy/layout_tests/port/chromium_android.py: + (ChromiumAndroidPort.__init__): + (ChromiumAndroidPort.create_driver): Override to create driver without DriverProxy to ensure 1 Driver per run. + (ChromiumAndroidDriver): + (ChromiumAndroidDriver.__init__): + (ChromiumAndroidDriver.cmd_line): + (ChromiumAndroidDriver._deadlock_detector): + (ChromiumAndroidDriver._drt_cmd_line): + (ChromiumAndroidDriver.start): + (ChromiumAndroidDriver._start): + (ChromiumAndroidDriver._start_once): + (ChromiumAndroidDriver.run_test): + (ChromiumAndroidDriver.stop): + (ChromiumAndroidDriver._command_from_driver_input): + (ChromiumAndroidDriver._read_prompt): + * Scripts/webkitpy/layout_tests/port/chromium_android_unittest.py: + (ChromiumAndroidPortTest.test_driver_cmd_line): + (ChromiumAndroidDriverTest.test_cmd_line): + (ChromiumAndroidDriverTest): + (ChromiumAndroidDriverTest.test_drt_cmd_line): + (ChromiumAndroidDriverTest.test_read_prompt): + (ChromiumAndroidDriverTest.test_command_from_driver_input): + (ChromiumAndroidDriverTest.test_write_command_and_read_line): + * Scripts/webkitpy/layout_tests/port/server_process.py: + (ServerProcess.__init__): Added universal_newlines to handle Android 'adb shell' line ends. + (ServerProcess._start): + (ServerProcess._wait_for_data_and_update_buffers_using_select): Handles unexpected EOF which indicates crash on Android. + (ServerProcess.stop): Added kill_directly parameter to kill the process without waiting it (which always timeouts for Android). + (ServerProcess.replace_outputs): Added to combine different input/output pipes into one ServerProcess. + * Scripts/webkitpy/layout_tests/port/webkit.py: + (WebKitDriver._command_from_driver_input): + (WebKitDriver.run_test): Changed timeout origin so that slow start() on Android won't cause timeout of layout test case. + * Scripts/webkitpy/layout_tests/port/webkit_unittest.py: + (MockServerProcess.read_stdout): + (MockServerProcess.start): + (MockServerProcess): + (MockServerProcess.stop): + (MockServerProcess.kill): + (WebKitDriverTest.test_read_block): + (WebKitDriverTest.test_read_binary_block): + (WebKitDriverTest.test_read_base64_block): + +2012-07-16 Dirk Pranke <dpranke@chromium.org> + + nrwt: move a bunch of printing code from manager.py to printing.py + https://bugs.webkit.org/show_bug.cgi?id=91439 + + Reviewed by Ojan Vafai. + + All of the logic that handles what gets logged should eventually + live in printing.py; this patch moves a large chunk of code that + prints all of the stuff after the run completes. + + There are no functional changes, this is just moving code + around. Covered by existing tests (updated as necessary). + + This code is all pretty messy and most of it should be deleted + (or extracted after the fact from results.json), but I'm saving + that for further patches. My goal is just to manager.py to a + more manageable state. + + * Scripts/webkitpy/layout_tests/controllers/manager.py: + (Manager.prepare_lists_and_print_output): + (Manager.run): + (Manager._mark_interrupted_tests_as_skipped): + (Manager._update_summary_with_result): + (Manager._num_digits): + * Scripts/webkitpy/layout_tests/controllers/manager_unittest.py: + (ManagerTest.test_interrupt_if_at_failure_limits): + (ResultSummaryTest.summarized_results): + * Scripts/webkitpy/layout_tests/models/result_summary.py: + (ResultSummary.__init__): + (ResultSummary.add): + Here we had to add a list of the slow tests to the result + summary so that we didn't need to call back into the manager and + the test expectations object to figure out if a test is SLOW. + * Scripts/webkitpy/layout_tests/views/printing.py: + (Printer.print_results): + (Printer): + (Printer._print_timing_statistics): + (Printer._print_aggregate_test_statistics): + (Printer._print_individual_test_times): + (Printer._print_test_list_timing): + (Printer._print_directory_timings): + (Printer._print_statistics_for_test_timings): + (Printer._print_result_summary): + (Printer._print_result_summary_entry): + * Scripts/webkitpy/layout_tests/views/printing_unittest.py: + (Testprinter.test_print_unexpected_results.get_unexpected_results): + (Testprinter): + +2012-07-16 Adam Barth <abarth@webkit.org> + + [Chromium] Create a stub TestRunner.a target + https://bugs.webkit.org/show_bug.cgi?id=91309 + + Reviewed by Ryosuke Niwa. + + * DumpRenderTree/DumpRenderTree.gyp/DumpRenderTree.gyp: + * DumpRenderTree/DumpRenderTree.gypi: + * DumpRenderTree/chromium/TestRunner/Stub.cpp: Added. + +2012-07-16 Dirk Pranke <dpranke@chromium.org> + + test-webkitpy: clean up logging to make it ninja-esque + https://bugs.webkit.org/show_bug.cgi?id=91297 + + Reviewed by Adam Barth. + + This patch changes the output of test-webkitpy to be closer to + what ninja produces. Namely: + + If you are running with stderr writing to a tty (and not -v), we + will no longer print '...' as tests complete. Instead, we use a + metered stream and print entries of the form: + '[X/Y] test_name passed/failed/erred' + where X is the current test # and Y is the total number of tests. + + If you are running with stderr piped to a file or other non-tty + object (or with -v), you get the same output, one per line for + every test. + + In addition, if tests fail or err out, you get the stack trace + immediately; you don't have to wait until the end of the run. + + Lastly, this change cleans up the unit tests for test-webkitpy + itself to not confuse the logger and to work cleanly w/ multiple + processes. It looks like between this and all the clean up in + MessagePool that happened as it landed, we can now run + multiprocessing tests in parallel. + + * Scripts/webkitpy/test/finder.py: + (Finder._default_names): + * Scripts/webkitpy/test/finder_unittest.py: + (FinderTest.setUp): + (FinderTest.tearDown): + * Scripts/webkitpy/test/printer.py: + (Printer.__init__): + (Printer.configure): + (Printer.print_started_test): + (Printer.print_finished_test): + (Printer._test_line): + (Printer.print_result): + * Scripts/webkitpy/test/runner.py: + (Runner.run): + * Scripts/webkitpy/test/runner_unittest.py: + (RunnerTest.setUp): + (RunnerTest): + (RunnerTest.tearDown): + (RunnerTest.assert_run): + (RunnerTest.test_regular): + (RunnerTest.test_verbose): + (RunnerTest.test_timing): + +2012-07-16 Dirk Pranke <dpranke@chromium.org> + + test-webkitpy: handle failures properly when running in parallel + https://bugs.webkit.org/show_bug.cgi?id=91416 + + Reviewed by Adam Barth. + + It turns out that unittest.TestResults contain a handle to the + test method itself, which isn't picklable; it's sufficient to just + store the test name instead of the actual method. By doing so + we can move the test_name() method from the printer to the + runner where it belongs (so the printer is less dependent on the + unittest framework's data structures). + + This change should really have a test but I don't know how to + write one that properly captures the behavior and won't cause + test-webkitpy itself to fail. I've verified the fix by hand, at + least, in the meantime. + + * Scripts/webkitpy/test/printer.py: + (Printer.__init__): + (Printer.print_result): + * Scripts/webkitpy/test/runner.py: + (_test_name): + (Runner.all_test_names): + (_Worker.handle): + +2012-07-16 Dirk Pranke <dpranke@chromium.org> + + test-webkitpy: handle failures properly when running in parallel + https://bugs.webkit.org/show_bug.cgi?id=91416 + + Reviewed by Tony Chang. + + It turns out that unittest.TestResults contain a handle to the + test method itself, which isn't picklable; it's sufficient to just + store the test name instead of the actual method. By doing so + we can move the test_name() method from the printer to the + runner where it belongs (so the printer is less dependent on the + unittest framework's data structures). + + This change should really have a test but I don't know how to + write one that properly captures the behavior and won't cause + test-webkitpy itself to fail. I've verified the fix by hand, at + least, in the meantime. + + * Scripts/webkitpy/test/printer.py: + (Printer.__init__): + (Printer.print_result): + * Scripts/webkitpy/test/runner.py: + (_test_name): + (Runner.all_test_names): + (_Worker.handle): + +2012-07-16 Dirk Pranke <dpranke@chromium.org> + + test-webkitpy: run tests in parallel + https://bugs.webkit.org/show_bug.cgi?id=91294 + + Reviewed by Ojan Vafai. + + This change adds support for running tests in parallel. This is + not yet on by default, since the logging isn't very pretty w/ + parallel tests. + + Also, there are some (multiprocessing-related) tests that can't be + run in parallel and so we skip them in that situation; I need to + come up with a mechanism for dealing with this, since you + apparently can't use multiprocessing as both a parent and a + child process. + + * Scripts/webkitpy/test/finder.py: + (Finder.find_names): + (Finder._default_names): + * Scripts/webkitpy/test/main.py: + (Tester._parse_args): + (Tester.run): + * Scripts/webkitpy/test/main_unittest.py: + (TesterTest.test_no_tests_found): + * Scripts/webkitpy/test/runner.py: + (Runner.run): + * Scripts/webkitpy/test/runner_unittest.py: + (RunnerTest.test_regular): + (RunnerTest.test_verbose): + (RunnerTest.test_timing): + +2012-07-16 Dirk Pranke <dpranke@chromium.org> + + test-webkitpy: use message pools + https://bugs.webkit.org/show_bug.cgi?id=91292 + + Reviewed by Ojan Vafai. + + Restructure the test-running code to be message-driven and + use a MessagePool; note that this does not yet actually run the + tests in parallel. + + Also clean up the unit tests so that the fake loader is passed + to the _Worker properly, and reduce a lot of the cut&pasted code + in the tests. + + No functional changes; covered by existing tests. + + * Scripts/webkitpy/test/printer.py: + (Printer.print_started_test): + (Printer.print_finished_test): + * Scripts/webkitpy/test/runner.py: + (Runner.__init__): + (Runner.run): + (Runner.handle): + (_Worker): + (_Worker.__init__): + (_Worker.handle): + * Scripts/webkitpy/test/runner_unittest.py: + (RunnerTest.assert_run): + (RunnerTest.test_regular): + (RunnerTest.test_verbose): + (RunnerTest.test_timing): + 2012-07-16 Simon Hausmann <simon.hausmann@nokia.com> [Qt] Fix Qt5 module dependencies https://bugs.webkit.org/show_bug.cgi?id=91388 - Reviewed by NOBODY (OOPS!). + Reviewed by Laszlo Gombos. Removed ancient qtscript and qtxmlpatterns module dependencies. * qmake/qt_webkit.pri: -2012-07-16 Simon Hausmann <simon.hausmann@nokia.com> +2012-07-16 Thiago Marcos P. Santos <thiago.santos@intel.com> - [Qt] MSVC: unresolved external symbol __DllMainCRTStartup@12 - https://bugs.webkit.org/show_bug.cgi?id=91229 + run-webkit-test returns 254 at exit even when it succeeds + https://bugs.webkit.org/show_bug.cgi?id=91370 - Reviewed by NOBODY (OOPS!). + Reviewed by Simon Hausmann. - In order to successfully link a DLL on Windows we need to have at least - one object file (or compilation unit). The forward export header files were - supposed to be that, but unfortunately the rule in win32/default_post.prf for - creating the header files had some bugs, among others that it did an exists() - check on the depending static library. At the time qmake is ran those libraries - do not exist yet and therefore the corresponding extra compiler rules were never - created, resulting in empty OBJECTS/SOURCES. + sys.exit() is implemented by raising SystemExit which inherits from + BaseException. Since we are catching BaseException, run_webkit_tests.py + was always returning an error code. - Even without such an exists() check, qmake extra compilers require the files - referred to in the .input variable to exist at qmake time. In this case the input - files were the static libraries, which do not exist yet. + * Scripts/webkitpy/layout_tests/run_webkit_tests.py: - This patch solves this by using a qmake extra target instead of extra - compiler, which does not have this limitation. The target is referenced - through the extension of GENERATED_SOURCES. +2012-07-15 Carlos Garcia Campos <cgarcia@igalia.com> - The patch also adds a d/_debug suffix for debug builds, do allow for separate - symbol exports if necessary. + Unreviewed. Fix make distcheck. - * Scripts/generate-win32-export-forwards: Support multiple input files, i.e. - consider the last argument to be the output file and everything else input. - * qmake/mkspecs/features/win32/default_post.prf: + * GNUmakefile.am: Add missing file to compilation. + +2012-07-15 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Unreviewed. Add EFLWebKit2PublicAPI, EFLWebKit2PlatformSpecific to watch list. + + * Scripts/webkitpy/common/config/watchlist: + +2012-07-15 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Unreviewed. Add gyuyoung.kim@samsung.com to watch list. + + * Scripts/webkitpy/common/config/watchlist: + +2012-07-15 Joseph Pecoraro <pecoraro@apple.com> + + Windowless WebView not firing JavaScript load event if there is a media element + https://bugs.webkit.org/show_bug.cgi?id=91331 + + Reviewed by Eric Carlson. + + Test a windowless WebView loading a page with a media element. The load + event should happen on the next spin of the run loop, but we spin check + the page, with a timeout of 250ms. + + * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: + * TestWebKitAPI/Tests/mac/WindowlessWebViewWithMedia.html: Added. + * TestWebKitAPI/Tests/mac/WindowlessWebViewWithMedia.mm: Added. + (-[WindowlessWebViewWithMediaFrameLoadDelegate webView:didFinishLoadForFrame:]): + (TestWebKitAPI::spinLoop): Spin check with timeout. Runs a block each spin to early bail. + (TestWebKitAPI::TEST): 2012-07-14 Benjamin Poulain <bpoulain@apple.com> diff --git a/Tools/DumpRenderTree/DumpRenderTree.gyp/DumpRenderTree.gyp b/Tools/DumpRenderTree/DumpRenderTree.gyp/DumpRenderTree.gyp index 2f29f058c..4fc5468f2 100644 --- a/Tools/DumpRenderTree/DumpRenderTree.gyp/DumpRenderTree.gyp +++ b/Tools/DumpRenderTree/DumpRenderTree.gyp/DumpRenderTree.gyp @@ -75,11 +75,35 @@ ], }, { + 'target_name': 'TestRunner', + 'type': 'static_library', + 'dependencies': [ + '<(source_dir)/WebKit/chromium/WebKit.gyp:webkit', + '<(source_dir)/WTF/WTF.gyp/WTF.gyp:wtf', + '<(chromium_src_dir)/webkit/support/webkit_support.gyp:webkit_support', + ], + 'include_dirs': [ + '<(chromium_src_dir)', + '<(source_dir)/WebKit/chromium/public', + '<(DEPTH)', + '../chromium/TestRunner', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + '../chromium/TestRunner', + ], + }, + 'sources': [ + '<@(test_runner_files)', + ], + }, + { 'target_name': 'DumpRenderTree', 'type': 'executable', 'mac_bundle': 1, 'dependencies': [ 'ImageDiff', + 'TestRunner', 'copy_TestNetscapePlugIn', '<(source_dir)/WebKit/chromium/WebKit.gyp:inspector_resources', '<(source_dir)/WebKit/chromium/WebKit.gyp:webkit', diff --git a/Tools/DumpRenderTree/DumpRenderTree.gypi b/Tools/DumpRenderTree/DumpRenderTree.gypi index a414fd25a..61e6a138f 100644 --- a/Tools/DumpRenderTree/DumpRenderTree.gypi +++ b/Tools/DumpRenderTree/DumpRenderTree.gypi @@ -1,14 +1,6 @@ { 'variables': { 'drt_files': [ - 'chromium/AccessibilityController.cpp', - 'chromium/AccessibilityController.h', - 'chromium/AccessibilityUIElement.cpp', - 'chromium/AccessibilityUIElement.h', - 'chromium/CppBoundClass.cpp', - 'chromium/CppBoundClass.h', - 'chromium/CppVariant.cpp', - 'chromium/CppVariant.h', 'chromium/DRTDevToolsAgent.cpp', 'chromium/DRTDevToolsAgent.h', 'chromium/DRTDevToolsClient.cpp', @@ -16,8 +8,6 @@ 'chromium/DumpRenderTree.cpp', 'chromium/EventSender.cpp', 'chromium/EventSender.h', - 'chromium/GamepadController.cpp', - 'chromium/GamepadController.h', 'chromium/LayoutTestController.cpp', 'chromium/LayoutTestController.h', 'chromium/MockGrammarCheck.cpp', @@ -32,8 +22,6 @@ 'chromium/MockWebSpeechRecognizer.h', 'chromium/NotificationPresenter.h', 'chromium/NotificationPresenter.cpp', - 'chromium/Task.h', - 'chromium/Task.cpp', 'chromium/TestEventPrinter.h', 'chromium/TestEventPrinter.cpp', 'chromium/TestNavigationController.cpp', @@ -48,8 +36,6 @@ 'chromium/TestShellX11.cpp', 'chromium/TestWebPlugin.cpp', 'chromium/TestWebPlugin.h', - 'chromium/TextInputController.cpp', - 'chromium/TextInputController.h', 'chromium/WebPermissions.cpp', 'chromium/WebPermissions.h', 'chromium/WebPreferences.cpp', @@ -65,6 +51,24 @@ 'chromium/WebViewHost.cpp', 'chromium/WebViewHost.h', ], + 'test_runner_files': [ + 'chromium/TestRunner/AccessibilityController.cpp', + 'chromium/TestRunner/AccessibilityController.h', + 'chromium/TestRunner/AccessibilityUIElement.cpp', + 'chromium/TestRunner/AccessibilityUIElement.h', + 'chromium/TestRunner/CppBoundClass.cpp', + 'chromium/TestRunner/CppBoundClass.h', + 'chromium/TestRunner/CppVariant.cpp', + 'chromium/TestRunner/CppVariant.h', + 'chromium/TestRunner/GamepadController.cpp', + 'chromium/TestRunner/GamepadController.h', + 'chromium/TestRunner/Task.cpp', + 'chromium/TestRunner/Task.h', + 'chromium/TestRunner/TestInterfaces.cpp', + 'chromium/TestRunner/TestInterfaces.h', + 'chromium/TestRunner/TextInputController.cpp', + 'chromium/TestRunner/TextInputController.h', + ], 'test_plugin_files': [ 'TestNetscapePlugIn/PluginObject.cpp', 'TestNetscapePlugIn/PluginObject.h', diff --git a/Tools/DumpRenderTree/chromium/DumpRenderTree.cpp b/Tools/DumpRenderTree/chromium/DumpRenderTree.cpp index 7b1284d31..789aa877f 100644 --- a/Tools/DumpRenderTree/chromium/DumpRenderTree.cpp +++ b/Tools/DumpRenderTree/chromium/DumpRenderTree.cpp @@ -47,8 +47,6 @@ static const char optionThreaded[] = "--threaded"; static const char optionDebugRenderTree[] = "--debug-render-tree"; static const char optionDebugLayerTree[] = "--debug-layer-tree"; -static const char optionPixelTestsWithName[] = "--pixel-tests="; -static const char optionTestShell[] = "--test-shell"; static const char optionAllowExternalPages[] = "--allow-external-pages"; static const char optionStartupDialog[] = "--testshell-startup-dialog"; static const char optionCheckLayoutTestSystemDeps[] = "--check-layout-test-sys-deps"; @@ -66,6 +64,7 @@ static const char optionEnablePerTilePainting[] = "--enable-per-tile-painting"; static const char optionStressOpt[] = "--stress-opt"; static const char optionStressDeopt[] = "--stress-deopt"; static const char optionJavaScriptFlags[] = "--js-flags="; +static const char optionEncodeBinary[] = "--encode-binary"; static const char optionNoTimeout[] = "--no-timeout"; static const char optionWebCoreLogChannels[] = "--webcore-log-channels="; @@ -81,30 +80,15 @@ public: } }; -static void runTest(TestShell& shell, TestParams& params, const string& testName, bool testShellMode) +static void runTest(TestShell& shell, TestParams& params, const string& testName) { int oldTimeoutMsec = shell.layoutTestTimeout(); params.pixelHash = ""; string pathOrURL = testName; - if (testShellMode) { - string timeOut; - string::size_type separatorPosition = pathOrURL.find(' '); - if (separatorPosition != string::npos) { - timeOut = pathOrURL.substr(separatorPosition + 1); - pathOrURL.erase(separatorPosition); - separatorPosition = timeOut.find_first_of(' '); - if (separatorPosition != string::npos) { - params.pixelHash = timeOut.substr(separatorPosition + 1); - timeOut.erase(separatorPosition); - } - shell.setLayoutTestTimeout(atoi(timeOut.c_str())); - } - } else { - string::size_type separatorPosition = pathOrURL.find("'"); - if (separatorPosition != string::npos) { - params.pixelHash = pathOrURL.substr(separatorPosition + 1); - pathOrURL.erase(separatorPosition); - } + string::size_type separatorPosition = pathOrURL.find("'"); + if (separatorPosition != string::npos) { + params.pixelHash = pathOrURL.substr(separatorPosition + 1); + pathOrURL.erase(separatorPosition); } params.testUrl = webkit_support::CreateURLForPathOrURL(pathOrURL); webkit_support::SetCurrentDirectoryForFileURL(params.testUrl); @@ -136,7 +120,6 @@ int main(int argc, char* argv[]) TestParams params; Vector<string> tests; bool serverMode = false; - bool testShellMode = false; bool allowExternalPages = false; bool startupDialog = false; bool acceleratedCompositingForVideoEnabled = false; @@ -150,6 +133,7 @@ int main(int argc, char* argv[]) bool stressDeopt = false; bool hardwareAcceleratedGL = false; string javaScriptFlags; + bool encodeBinary = false; bool noTimeout = false; for (int i = 1; i < argc; ++i) { string argument(argv[i]); @@ -159,17 +143,11 @@ int main(int argc, char* argv[]) params.dumpTree = false; else if (argument == optionPixelTests) params.dumpPixels = true; - else if (!argument.find(optionPixelTestsWithName)) { - params.dumpPixels = true; - params.pixelFileName = argument.substr(strlen(optionPixelTestsWithName)); - } else if (argument == optionDebugRenderTree) + else if (argument == optionDebugRenderTree) params.debugRenderTree = true; else if (argument == optionDebugLayerTree) params.debugLayerTree = true; - else if (argument == optionTestShell) { - testShellMode = true; - serverMode = true; - } else if (argument == optionAllowExternalPages) + else if (argument == optionAllowExternalPages) allowExternalPages = true; else if (argument == optionStartupDialog) startupDialog = true; @@ -205,6 +183,8 @@ int main(int argc, char* argv[]) stressDeopt = true; else if (!argument.find(optionJavaScriptFlags)) javaScriptFlags = argument.substr(strlen(optionJavaScriptFlags)); + else if (argument == optionEncodeBinary) + encodeBinary = true; else if (argument == optionNoTimeout) noTimeout = true; else if (!argument.find(optionWebCoreLogChannels)) { @@ -215,10 +195,6 @@ int main(int argc, char* argv[]) else tests.append(argument); } - if (testShellMode && params.dumpPixels && params.pixelFileName.empty()) { - fprintf(stderr, "--pixel-tests with --test-shell requires a file name.\n"); - return EXIT_FAILURE; - } if (stressOpt && stressDeopt) { fprintf(stderr, "--stress-opt and --stress-deopt are mutually exclusive.\n"); return EXIT_FAILURE; @@ -231,7 +207,6 @@ int main(int argc, char* argv[]) { // Explicit scope for the TestShell instance. TestShell shell; - shell.setTestShellMode(testShellMode); shell.setAllowExternalPages(allowExternalPages); shell.setAcceleratedCompositingForVideoEnabled(acceleratedCompositingForVideoEnabled); shell.setThreadedCompositingEnabled(threadedCompositingEnabled); @@ -243,6 +218,7 @@ int main(int argc, char* argv[]) shell.setJavaScriptFlags(javaScriptFlags); shell.setStressOpt(stressOpt); shell.setStressDeopt(stressDeopt); + shell.setEncodeBinary(encodeBinary); if (noTimeout) { // 0x20000000ms is big enough for the purpose to avoid timeout in debugging. shell.setLayoutTestTimeout(0x20000000); @@ -265,14 +241,14 @@ int main(int argc, char* argv[]) // Explicitly quit on platforms where EOF is not reliable. if (!strcmp(testString, "QUIT")) break; - runTest(shell, params, testString, testShellMode); + runTest(shell, params, testString); } } else if (!tests.size()) puts("#EOF"); else { params.printSeparators = tests.size() > 1; for (unsigned i = 0; i < tests.size(); i++) - runTest(shell, params, tests[i], testShellMode); + runTest(shell, params, tests[i]); } shell.callJSGC(); diff --git a/Tools/DumpRenderTree/chromium/TestEventPrinter.cpp b/Tools/DumpRenderTree/chromium/TestEventPrinter.cpp index 730d76b27..b8aecf100 100644 --- a/Tools/DumpRenderTree/chromium/TestEventPrinter.cpp +++ b/Tools/DumpRenderTree/chromium/TestEventPrinter.cpp @@ -34,84 +34,53 @@ #include <stdio.h> #include <stdlib.h> #include <wtf/Assertions.h> +#include <wtf/text/Base64.h> -class DRTPrinter : public TestEventPrinter { -public: - DRTPrinter() { } - void handleTestHeader(const char* url) const; - void handleTimedOut() const; - void handleTextHeader() const; - void handleTextFooter() const; - void handleAudioHeader() const; - void handleAudioFooter() const; - void handleImage(const char* actualHash, const char* expectedHash, const unsigned char* imageData, size_t imageSize, const char* fileName) const; - void handleImageFooter() const; - void handleTestFooter(bool dumpedAnything) const; -}; - -class TestShellPrinter : public TestEventPrinter { -public: - TestShellPrinter() { } - void handleTestHeader(const char* url) const; - void handleTimedOut() const; - void handleTextHeader() const; - void handleTextFooter() const; - void handleAudioHeader() const; - void handleAudioFooter() const; - void handleImage(const char* actualHash, const char* expectedHash, const unsigned char* imageData, size_t imageSize, const char* fileName) const; - void handleImageFooter() const; - void handleTestFooter(bool dumpedAnything) const; -}; - -TestEventPrinter::~TestEventPrinter() +TestEventPrinter::TestEventPrinter() + : m_encodeBinary(false) { } -PassOwnPtr<TestEventPrinter> TestEventPrinter::createDRTPrinter() -{ - return adoptPtr(new DRTPrinter); -} - -PassOwnPtr<TestEventPrinter> TestEventPrinter::createTestShellPrinter() +TestEventPrinter::~TestEventPrinter() { - return adoptPtr(new TestShellPrinter); } // ---------------------------------------------------------------- -void DRTPrinter::handleTestHeader(const char*) const +void TestEventPrinter::handleTestHeader(const char*) const { } -void DRTPrinter::handleTimedOut() const +void TestEventPrinter::handleTimedOut() const { fprintf(stderr, "FAIL: Timed out waiting for notifyDone to be called\n"); fprintf(stdout, "FAIL: Timed out waiting for notifyDone to be called\n"); } -void DRTPrinter::handleTextHeader() const +void TestEventPrinter::handleTextHeader() const { printf("Content-Type: text/plain\n"); } -void DRTPrinter::handleTextFooter() const +void TestEventPrinter::handleTextFooter() const { printf("#EOF\n"); fprintf(stderr, "#EOF\n"); } -void DRTPrinter::handleAudioHeader() const +void TestEventPrinter::handleAudio(const void* audioData, size_t audioSize) const { printf("Content-Type: audio/wav\n"); + handleBinary(audioData, audioSize); } -void DRTPrinter::handleAudioFooter() const +void TestEventPrinter::handleAudioFooter() const { printf("#EOF\n"); fprintf(stderr, "#EOF\n"); } -void DRTPrinter::handleImage(const char* actualHash, const char* expectedHash, const unsigned char* imageData, size_t imageSize, const char*) const +void TestEventPrinter::handleImage(const char* actualHash, const char* expectedHash, const void* imageData, size_t imageSize) const { ASSERT(actualHash); printf("\nActualHash: %s\n", actualHash); @@ -119,72 +88,28 @@ void DRTPrinter::handleImage(const char* actualHash, const char* expectedHash, c printf("\nExpectedHash: %s\n", expectedHash); if (imageData && imageSize) { printf("Content-Type: image/png\n"); - // Printf formatting for size_t on 32-bit, 64-bit, and on Windows is hard so just cast to an int. - printf("Content-Length: %d\n", static_cast<int>(imageSize)); - if (fwrite(imageData, 1, imageSize, stdout) != imageSize) { - fprintf(stderr, "Short write to stdout.\n"); - exit(1); - } + handleBinary(imageData, imageSize); } } -void DRTPrinter::handleTestFooter(bool) const +void TestEventPrinter::handleTestFooter(bool) const { printf("#EOF\n"); } -// ---------------------------------------------------------------- - -void TestShellPrinter::handleTestHeader(const char* url) const -{ - printf("#URL:%s\n", url); -} - -void TestShellPrinter::handleTimedOut() const -{ - puts("#TEST_TIMED_OUT\n"); -} - -void TestShellPrinter::handleTextHeader() const -{ -} - -void TestShellPrinter::handleTextFooter() const +void TestEventPrinter::handleBinary(const void* data, size_t size) const { -} - -void TestShellPrinter::handleAudioHeader() const -{ - printf("Content-Type: audio/wav\n"); -} - -void TestShellPrinter::handleAudioFooter() const -{ - printf("\n"); -} - -void TestShellPrinter::handleImage(const char* actualHash, const char*, const unsigned char* imageData, size_t imageSize, const char* fileName) const -{ - ASSERT(actualHash); - if (imageData && imageSize) { - ASSERT(fileName); - FILE* fp = fopen(fileName, "wb"); - if (!fp) { - perror(fileName); - exit(EXIT_FAILURE); - } - if (fwrite(imageData, 1, imageSize, fp) != imageSize) { - perror(fileName); - fclose(fp); - exit(EXIT_FAILURE); - } - fclose(fp); + Vector<char> base64; + if (m_encodeBinary) { + base64Encode(static_cast<const char*>(data), size, base64, Base64InsertLFs); + data = base64.data(); + size = base64.size(); + printf("Content-Transfer-Encoding: base64\n"); + } + // Printf formatting for size_t on 32-bit, 64-bit, and on Windows is hard so just cast to an int. + printf("Content-Length: %d\n", static_cast<int>(size)); + if (fwrite(data, 1, size, stdout) != size) { + fprintf(stderr, "Short write to stdout.\n"); + exit(1); } - printf("#MD5:%s\n", actualHash); -} - -void TestShellPrinter::handleTestFooter(bool dumpedAnything) const -{ - if (dumpedAnything) - printf("#EOF\n"); } diff --git a/Tools/DumpRenderTree/chromium/TestEventPrinter.h b/Tools/DumpRenderTree/chromium/TestEventPrinter.h index 374827e18..c1a7e2dcd 100644 --- a/Tools/DumpRenderTree/chromium/TestEventPrinter.h +++ b/Tools/DumpRenderTree/chromium/TestEventPrinter.h @@ -35,18 +35,24 @@ class TestEventPrinter { public: - static PassOwnPtr<TestEventPrinter> createDRTPrinter(); - static PassOwnPtr<TestEventPrinter> createTestShellPrinter(); + TestEventPrinter(); + ~TestEventPrinter(); + void handleTestHeader(const char* url) const; + void handleTimedOut() const; + void handleTextHeader() const; + void handleTextFooter() const; + void handleAudio(const void* audioData, size_t audioSize) const; + void handleAudioFooter() const; + void handleImage(const char* actualHash, const char* expectedHash, const void* imageData, size_t imageSize) const; + void handleTestFooter(bool dumpedAnything) const; - virtual ~TestEventPrinter(); - virtual void handleTestHeader(const char* url) const = 0; - virtual void handleTimedOut() const = 0; - virtual void handleTextHeader() const = 0; - virtual void handleTextFooter() const = 0; - virtual void handleAudioHeader() const = 0; - virtual void handleAudioFooter() const = 0; - virtual void handleImage(const char* actualHash, const char* expectedHash, const unsigned char* imageData, size_t imageSize, const char* fileName) const = 0; - virtual void handleTestFooter(bool dumpedAnything) const = 0; + // Set if binary output data should be encoded in base64. Default is off. + void setEncodeBinary(bool encodeBinary) { m_encodeBinary = encodeBinary; } + +private: + void handleBinary(const void* data, size_t) const; + + bool m_encodeBinary; }; #endif // TestEventPrinter_h diff --git a/Tools/DumpRenderTree/chromium/AccessibilityController.cpp b/Tools/DumpRenderTree/chromium/TestRunner/AccessibilityController.cpp index 860a747aa..c6e4404c2 100644 --- a/Tools/DumpRenderTree/chromium/AccessibilityController.cpp +++ b/Tools/DumpRenderTree/chromium/TestRunner/AccessibilityController.cpp @@ -31,17 +31,15 @@ #include "config.h" #include "AccessibilityController.h" -#include "TestShell.h" #include "WebAccessibilityObject.h" #include "WebFrame.h" -#include "platform/WebString.h" #include "WebView.h" +#include "platform/WebString.h" using namespace WebKit; -AccessibilityController::AccessibilityController(TestShell* shell) +AccessibilityController::AccessibilityController() : m_logAccessibilityEvents(false) - , m_shell(shell) { bindMethod("logAccessibilityEvents", &AccessibilityController::logAccessibilityEventsCallback); @@ -77,14 +75,14 @@ void AccessibilityController::setFocusedElement(const WebAccessibilityObject& fo AccessibilityUIElement* AccessibilityController::getFocusedElement() { if (m_focusedElement.isNull()) - m_focusedElement = m_shell->webView()->accessibilityObject(); + m_focusedElement = m_webView->accessibilityObject(); return m_elements.getOrCreate(m_focusedElement); } AccessibilityUIElement* AccessibilityController::getRootElement() { if (m_rootElement.isNull()) - m_rootElement = m_shell->webView()->accessibilityObject(); + m_rootElement = m_webView->accessibilityObject(); return m_elements.createRoot(m_rootElement); } diff --git a/Tools/DumpRenderTree/chromium/AccessibilityController.h b/Tools/DumpRenderTree/chromium/TestRunner/AccessibilityController.h index 954edb9ca..967259536 100644 --- a/Tools/DumpRenderTree/chromium/AccessibilityController.h +++ b/Tools/DumpRenderTree/chromium/TestRunner/AccessibilityController.h @@ -37,13 +37,12 @@ namespace WebKit { class WebAccessibilityObject; class WebFrame; +class WebView; } -class TestShell; - class AccessibilityController : public CppBoundClass { public: - explicit AccessibilityController(TestShell*); + AccessibilityController(); // Shadow to include accessibility initialization. void bindToJavascript(WebKit::WebFrame*, const WebKit::WebString& classname); @@ -57,6 +56,8 @@ public: void notificationReceived(const WebKit::WebAccessibilityObject& target, const char* notificationName); + void setWebView(WebKit::WebView* webView) { m_webView = webView; } + private: // If true, will log all accessibility notifications. bool m_logAccessibilityEvents; @@ -77,7 +78,7 @@ private: std::vector<CppVariant> m_notificationCallbacks; - TestShell* m_shell; + WebKit::WebView* m_webView; }; #endif // AccessibilityController_h diff --git a/Tools/DumpRenderTree/chromium/AccessibilityUIElement.cpp b/Tools/DumpRenderTree/chromium/TestRunner/AccessibilityUIElement.cpp index 583806585..583806585 100644 --- a/Tools/DumpRenderTree/chromium/AccessibilityUIElement.cpp +++ b/Tools/DumpRenderTree/chromium/TestRunner/AccessibilityUIElement.cpp diff --git a/Tools/DumpRenderTree/chromium/AccessibilityUIElement.h b/Tools/DumpRenderTree/chromium/TestRunner/AccessibilityUIElement.h index 8ae6d412f..8ae6d412f 100644 --- a/Tools/DumpRenderTree/chromium/AccessibilityUIElement.h +++ b/Tools/DumpRenderTree/chromium/TestRunner/AccessibilityUIElement.h diff --git a/Tools/DumpRenderTree/chromium/CppBoundClass.cpp b/Tools/DumpRenderTree/chromium/TestRunner/CppBoundClass.cpp index 9b4a3b646..9b4a3b646 100644 --- a/Tools/DumpRenderTree/chromium/CppBoundClass.cpp +++ b/Tools/DumpRenderTree/chromium/TestRunner/CppBoundClass.cpp diff --git a/Tools/DumpRenderTree/chromium/CppBoundClass.h b/Tools/DumpRenderTree/chromium/TestRunner/CppBoundClass.h index 4fb5361e1..4fb5361e1 100644 --- a/Tools/DumpRenderTree/chromium/CppBoundClass.h +++ b/Tools/DumpRenderTree/chromium/TestRunner/CppBoundClass.h diff --git a/Tools/DumpRenderTree/chromium/CppVariant.cpp b/Tools/DumpRenderTree/chromium/TestRunner/CppVariant.cpp index b587d75aa..b587d75aa 100644 --- a/Tools/DumpRenderTree/chromium/CppVariant.cpp +++ b/Tools/DumpRenderTree/chromium/TestRunner/CppVariant.cpp diff --git a/Tools/DumpRenderTree/chromium/CppVariant.h b/Tools/DumpRenderTree/chromium/TestRunner/CppVariant.h index 60cc6271e..60cc6271e 100644 --- a/Tools/DumpRenderTree/chromium/CppVariant.h +++ b/Tools/DumpRenderTree/chromium/TestRunner/CppVariant.h diff --git a/Tools/DumpRenderTree/chromium/GamepadController.cpp b/Tools/DumpRenderTree/chromium/TestRunner/GamepadController.cpp index b38dfa0c5..cdf1befc3 100644 --- a/Tools/DumpRenderTree/chromium/GamepadController.cpp +++ b/Tools/DumpRenderTree/chromium/TestRunner/GamepadController.cpp @@ -31,11 +31,9 @@ #include "config.h" #include "GamepadController.h" -#include "TestShell.h" - using namespace WebKit; -GamepadController::GamepadController(TestShell*) +GamepadController::GamepadController() { bindMethod("connect", &GamepadController::connect); bindMethod("disconnect", &GamepadController::disconnect); diff --git a/Tools/DumpRenderTree/chromium/GamepadController.h b/Tools/DumpRenderTree/chromium/TestRunner/GamepadController.h index 5a6f40d5d..8cf4cb824 100644 --- a/Tools/DumpRenderTree/chromium/GamepadController.h +++ b/Tools/DumpRenderTree/chromium/TestRunner/GamepadController.h @@ -39,11 +39,9 @@ class WebGamepads; class WebFrame; } -class TestShell; - class GamepadController : public CppBoundClass { public: - explicit GamepadController(TestShell*); + GamepadController(); void bindToJavascript(WebKit::WebFrame*, const WebKit::WebString& classname); void reset(); diff --git a/Tools/DumpRenderTree/chromium/Task.cpp b/Tools/DumpRenderTree/chromium/TestRunner/Task.cpp index d80beef34..d80beef34 100644 --- a/Tools/DumpRenderTree/chromium/Task.cpp +++ b/Tools/DumpRenderTree/chromium/TestRunner/Task.cpp diff --git a/Tools/DumpRenderTree/chromium/Task.h b/Tools/DumpRenderTree/chromium/TestRunner/Task.h index 0b32c472b..0b32c472b 100644 --- a/Tools/DumpRenderTree/chromium/Task.h +++ b/Tools/DumpRenderTree/chromium/TestRunner/Task.h diff --git a/Tools/DumpRenderTree/chromium/TestRunner/TestInterfaces.cpp b/Tools/DumpRenderTree/chromium/TestRunner/TestInterfaces.cpp new file mode 100644 index 000000000..5cfb2c2f8 --- /dev/null +++ b/Tools/DumpRenderTree/chromium/TestRunner/TestInterfaces.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "TestInterfaces.h" + +#include "GamepadController.h" +#include "platform/WebString.h" + +using WebKit::WebFrame; +using WebKit::WebString; + +TestInterfaces::TestInterfaces() +{ + m_gamepadController = adoptPtr(new GamepadController()); +} + +TestInterfaces::~TestInterfaces() +{ +} + +void TestInterfaces::bindTo(WebFrame* frame) +{ + m_gamepadController->bindToJavascript(frame, WebString::fromUTF8("gamepadController")); +} + +void TestInterfaces::resetAll() +{ + m_gamepadController->reset(); +} diff --git a/Tools/DumpRenderTree/chromium/TestRunner/TestInterfaces.h b/Tools/DumpRenderTree/chromium/TestRunner/TestInterfaces.h new file mode 100644 index 000000000..e2404ad6d --- /dev/null +++ b/Tools/DumpRenderTree/chromium/TestRunner/TestInterfaces.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TestInterfaces_h +#define TestInterfaces_h + +#include <wtf/OwnPtr.h> + +namespace WebKit { +class WebFrame; +} + +class GamepadController; + +class TestInterfaces { +public: + TestInterfaces(); + ~TestInterfaces(); + + void bindTo(WebKit::WebFrame*); + void resetAll(); + +private: + OwnPtr<GamepadController> m_gamepadController; +}; + +#endif // TestInterfaces_h diff --git a/Tools/DumpRenderTree/chromium/TextInputController.cpp b/Tools/DumpRenderTree/chromium/TestRunner/TextInputController.cpp index a3637067a..b72a2080d 100644 --- a/Tools/DumpRenderTree/chromium/TextInputController.cpp +++ b/Tools/DumpRenderTree/chromium/TestRunner/TextInputController.cpp @@ -31,28 +31,21 @@ #include "config.h" #include "TextInputController.h" -#include "TestShell.h" #include "WebBindings.h" #include "WebCompositionUnderline.h" #include "WebFrame.h" +#include "WebInputEvent.h" #include "WebRange.h" +#include "WebView.h" #include "platform/WebString.h" #include "platform/WebVector.h" -#include "WebView.h" #include <string> #include <wtf/StringExtras.h> using namespace WebKit; -TestShell* TextInputController::testShell = 0; - -TextInputController::TextInputController(TestShell* shell) +TextInputController::TextInputController() { - // Set static testShell variable. Be careful not to assign testShell to new - // windows which are temporary. - if (!testShell) - testShell = shell; - bindMethod("attributedSubstringFromRange", &TextInputController::attributedSubstringFromRange); bindMethod("characterIndexForPoint", &TextInputController::characterIndexForPoint); bindMethod("conversationIdentifier", &TextInputController::conversationIdentifier); @@ -70,11 +63,6 @@ TextInputController::TextInputController(TestShell* shell) bindMethod("setComposition", &TextInputController::setComposition); } -WebFrame* TextInputController::getMainFrame() -{ - return testShell->webView()->mainFrame(); -} - void TextInputController::insertText(const CppArgumentList& arguments, CppVariant* result) { result->setNull(); @@ -82,14 +70,14 @@ void TextInputController::insertText(const CppArgumentList& arguments, CppVarian if (arguments.size() < 1 || !arguments[0].isString()) return; - testShell->webView()->confirmComposition(WebString::fromUTF8(arguments[0].toString())); + m_webView->confirmComposition(WebString::fromUTF8(arguments[0].toString())); } void TextInputController::doCommand(const CppArgumentList& arguments, CppVariant* result) { result->setNull(); - WebFrame* mainFrame = getMainFrame(); + WebFrame* mainFrame = m_webView->mainFrame(); if (!mainFrame) return; @@ -104,10 +92,10 @@ void TextInputController::setMarkedText(const CppArgumentList& arguments, CppVar if (arguments.size() >= 3 && arguments[0].isString() && arguments[1].isNumber() && arguments[2].isNumber()) { WebVector<WebCompositionUnderline> underlines; - testShell->webView()->setComposition(WebString::fromUTF8(arguments[0].toString()), - underlines, - arguments[1].toInt32(), - arguments[1].toInt32() + arguments[2].toInt32()); + m_webView->setComposition(WebString::fromUTF8(arguments[0].toString()), + underlines, + arguments[1].toInt32(), + arguments[1].toInt32() + arguments[2].toInt32()); } } @@ -115,14 +103,14 @@ void TextInputController::unmarkText(const CppArgumentList&, CppVariant* result) { result->setNull(); - testShell->webView()->confirmComposition(); + m_webView->confirmComposition(); } void TextInputController::hasMarkedText(const CppArgumentList&, CppVariant* result) { result->setNull(); - WebFrame* mainFrame = getMainFrame(); + WebFrame* mainFrame = m_webView->mainFrame(); if (!mainFrame) return; @@ -151,7 +139,7 @@ void TextInputController::markedRange(const CppArgumentList&, CppVariant* result { result->setNull(); - WebFrame* mainFrame = getMainFrame(); + WebFrame* mainFrame = m_webView->mainFrame(); if (!mainFrame) return; @@ -166,7 +154,7 @@ void TextInputController::selectedRange(const CppArgumentList&, CppVariant* resu { result->setNull(); - WebFrame* mainFrame = getMainFrame(); + WebFrame* mainFrame = m_webView->mainFrame(); if (!mainFrame) return; @@ -181,7 +169,7 @@ void TextInputController::firstRectForCharacterRange(const CppArgumentList& argu { result->setNull(); - WebFrame* frame = testShell->webView()->focusedFrame(); + WebFrame* frame = m_webView->focusedFrame(); if (!frame) return; @@ -210,7 +198,7 @@ void TextInputController::validAttributesForMarkedText(const CppArgumentList&, C { result->setNull(); - WebFrame* mainFrame = getMainFrame(); + WebFrame* mainFrame = m_webView->mainFrame(); if (!mainFrame) return; @@ -228,10 +216,6 @@ void TextInputController::setComposition(const CppArgumentList& arguments, CppVa { result->setNull(); - WebView* view = getMainFrame() ? getMainFrame()->view() : 0; - if (!view) - return; - if (arguments.size() < 1) return; @@ -241,9 +225,9 @@ void TextInputController::setComposition(const CppArgumentList& arguments, CppVa keyDown.modifiers = 0; keyDown.windowsKeyCode = 0xE5; // VKEY_PROCESSKEY keyDown.setKeyIdentifierFromWindowsKeyCode(); - view->handleInputEvent(keyDown); + m_webView->handleInputEvent(keyDown); WebVector<WebCompositionUnderline> underlines; WebString text(WebString::fromUTF8(arguments[0].toString())); - view->setComposition(text, underlines, 0, text.length()); + m_webView->setComposition(text, underlines, 0, text.length()); } diff --git a/Tools/DumpRenderTree/chromium/TextInputController.h b/Tools/DumpRenderTree/chromium/TestRunner/TextInputController.h index 3a3907fda..a959aa8b3 100644 --- a/Tools/DumpRenderTree/chromium/TextInputController.h +++ b/Tools/DumpRenderTree/chromium/TestRunner/TextInputController.h @@ -37,15 +37,15 @@ #include "CppBoundClass.h" -class TestShell; - namespace WebKit { -class WebFrame; +class WebView; } class TextInputController : public CppBoundClass { public: - TextInputController(TestShell*); + TextInputController(); + + void setWebView(WebKit::WebView* webView) { m_webView = webView; } void insertText(const CppArgumentList&, CppVariant*); void doCommand(const CppArgumentList&, CppVariant*); @@ -64,11 +64,7 @@ public: void setComposition(const CppArgumentList&, CppVariant*); private: - // Returns the test shell's main WebFrame. - static WebKit::WebFrame* getMainFrame(); - - // Non-owning pointer. The TextInputController is owned by the TestShell. - static TestShell* testShell; + WebKit::WebView* m_webView; }; #endif // TextInputController_h diff --git a/Tools/DumpRenderTree/chromium/TestShell.cpp b/Tools/DumpRenderTree/chromium/TestShell.cpp index 46bde2a90..b4142eacf 100644 --- a/Tools/DumpRenderTree/chromium/TestShell.cpp +++ b/Tools/DumpRenderTree/chromium/TestShell.cpp @@ -105,7 +105,6 @@ TestShell::TestShell() : m_testIsPending(false) , m_testIsPreparing(false) , m_focusedWidget(0) - , m_testShellMode(false) , m_devTools(0) , m_allowExternalPages(false) , m_acceleratedCompositingForVideoEnabled(false) @@ -146,16 +145,14 @@ TestShell::TestShell() void TestShell::initialize() { m_webPermissions = adoptPtr(new WebPermissions(this)); - m_accessibilityController = adoptPtr(new AccessibilityController(this)); - m_gamepadController = adoptPtr(new GamepadController(this)); - + m_accessibilityController = adoptPtr(new AccessibilityController()); + m_testInterfaces = adoptPtr(new TestInterfaces()); m_layoutTestController = adoptPtr(new LayoutTestController(this)); m_eventSender = adoptPtr(new EventSender(this)); - m_textInputController = adoptPtr(new TextInputController(this)); + m_textInputController = adoptPtr(new TextInputController()); #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) m_notificationPresenter = adoptPtr(new NotificationPresenter(this)); #endif - m_printer = m_testShellMode ? TestEventPrinter::createTestShellPrinter() : TestEventPrinter::createDRTPrinter(); #if ENABLE(LINK_PRERENDER) m_prerenderingSupport = adoptPtr(new MockWebPrerenderingSupport()); #endif @@ -176,15 +173,15 @@ void TestShell::createMainWindow() m_drtDevToolsAgent = adoptPtr(new DRTDevToolsAgent); m_webViewHost = adoptPtr(createNewWindow(WebURL(), m_drtDevToolsAgent.get())); m_webView = m_webViewHost->webView(); + m_accessibilityController->setWebView(m_webView); + m_textInputController->setWebView(m_webView); m_drtDevToolsAgent->setWebView(m_webView); } TestShell::~TestShell() { - // Note: DevTools are closed together with all the other windows in the - // windows list. - - // Destroy the WebView before its WebViewHost. + m_accessibilityController->setWebView(0); + m_textInputController->setWebView(0); m_drtDevToolsAgent->setWebView(0); } @@ -266,7 +263,7 @@ void TestShell::runFileTest(const TestParams& params) m_layoutTestController->setShowDebugLayerTree(true); if (m_dumpWhenFinished) - m_printer->handleTestHeader(testUrl.c_str()); + m_printer.handleTestHeader(testUrl.c_str()); loadURL(m_params.testUrl); m_testIsPreparing = false; @@ -296,7 +293,7 @@ void TestShell::resetTestController() resetWebSettings(*webView()); m_webPermissions->reset(); m_accessibilityController->reset(); - m_gamepadController->reset(); + m_testInterfaces->resetAll(); m_layoutTestController->reset(); m_eventSender->reset(); m_webViewHost->reset(); @@ -374,7 +371,7 @@ void TestShell::testFinished() void TestShell::testTimedOut() { - m_printer->handleTimedOut(); + m_printer.handleTimedOut(); testFinished(); } @@ -562,15 +559,10 @@ void TestShell::dump() bool dumpedAnything = false; if (shouldDumpAsAudio) { - m_printer->handleAudioHeader(); - const WebKit::WebArrayBufferView& webArrayBufferView = m_layoutTestController->audioData(); - printf("Content-Length: %d\n", webArrayBufferView.byteLength()); - - if (fwrite(webArrayBufferView.baseAddress(), 1, webArrayBufferView.byteLength(), stdout) != webArrayBufferView.byteLength()) - FATAL("Short write to stdout, disk full?\n"); - m_printer->handleAudioFooter(); - m_printer->handleTestFooter(true); + m_printer.handleAudio(webArrayBufferView.baseAddress(), webArrayBufferView.byteLength()); + m_printer.handleAudioFooter(); + m_printer.handleTestFooter(true); fflush(stdout); fflush(stderr); @@ -579,7 +571,7 @@ void TestShell::dump() if (m_params.dumpTree) { dumpedAnything = true; - m_printer->handleTextHeader(); + m_printer.handleTextHeader(); // Text output: the test page can request different types of output // which we handle here. if (!shouldDumpAsText) { @@ -609,7 +601,7 @@ void TestShell::dump() printf("%s", dumpAllBackForwardLists().c_str()); } if (dumpedAnything && m_params.printSeparators) - m_printer->handleTextFooter(); + m_printer.handleTextFooter(); if (m_params.dumpPixels && shouldGeneratePixelResults) { // Image output: we write the image data to the file given on the @@ -654,7 +646,7 @@ void TestShell::dump() dumpImage(m_webViewHost->canvas()); } - m_printer->handleTestFooter(dumpedAnything); + m_printer.handleTestFooter(dumpedAnything); fflush(stdout); fflush(stderr); } @@ -721,16 +713,16 @@ void TestShell::dumpImage(SkCanvas* canvas) const sourceBitmap.height(), static_cast<int>(sourceBitmap.rowBytes()), discardTransparency, md5hash, &png); #endif - m_printer->handleImage(md5hash.c_str(), m_params.pixelHash.c_str(), &png[0], png.size(), m_params.pixelFileName.c_str()); + m_printer.handleImage(md5hash.c_str(), m_params.pixelHash.c_str(), &png[0], png.size()); } else - m_printer->handleImage(md5hash.c_str(), m_params.pixelHash.c_str(), 0, 0, m_params.pixelFileName.c_str()); + m_printer.handleImage(md5hash.c_str(), m_params.pixelHash.c_str(), 0, 0); } void TestShell::bindJSObjectsToWindow(WebFrame* frame) { WebTestingSupport::injectInternalsObject(frame); m_accessibilityController->bindToJavascript(frame, WebString::fromUTF8("accessibilityController")); - m_gamepadController->bindToJavascript(frame, WebString::fromUTF8("gamepadController")); + m_testInterfaces->bindTo(frame); m_layoutTestController->bindToJavascript(frame, WebString::fromUTF8("layoutTestController")); m_layoutTestController->bindToJavascript(frame, WebString::fromUTF8("testRunner")); m_eventSender->bindToJavascript(frame, WebString::fromUTF8("eventSender")); diff --git a/Tools/DumpRenderTree/chromium/TestShell.h b/Tools/DumpRenderTree/chromium/TestShell.h index 8ae0c2421..7ea579056 100644 --- a/Tools/DumpRenderTree/chromium/TestShell.h +++ b/Tools/DumpRenderTree/chromium/TestShell.h @@ -37,6 +37,7 @@ #include "LayoutTestController.h" #include "NotificationPresenter.h" #include "TestEventPrinter.h" +#include "TestInterfaces.h" #include "TextInputController.h" #include "WebPreferences.h" #include "WebViewHost.h" @@ -69,8 +70,6 @@ struct TestParams { bool debugLayerTree; bool printSeparators; WebKit::WebURL testUrl; - // Resultant image file name. Required only if the test_shell mode. - std::string pixelFileName; std::string pixelHash; TestParams() @@ -95,11 +94,10 @@ public: LayoutTestController* layoutTestController() const { return m_layoutTestController.get(); } EventSender* eventSender() const { return m_eventSender.get(); } AccessibilityController* accessibilityController() const { return m_accessibilityController.get(); } - GamepadController* gamepadController() const { return m_gamepadController.get(); } #if ENABLE(NOTIFICATIONS) NotificationPresenter* notificationPresenter() const { return m_notificationPresenter.get(); } #endif - TestEventPrinter* printer() const { return m_printer.get(); } + const TestEventPrinter* printer() const { return &m_printer; } WebPreferences* preferences() { return &m_prefs; } void applyPreferences() { m_prefs.applyTo(m_webView); } @@ -135,7 +133,6 @@ public: bool allowExternalPages() const { return m_allowExternalPages; } void setAllowExternalPages(bool allowExternalPages) { m_allowExternalPages = allowExternalPages; } - void setTestShellMode(bool testShellMode) { m_testShellMode = testShellMode; } void setAcceleratedCompositingForVideoEnabled(bool enabled) { m_acceleratedCompositingForVideoEnabled = enabled; } void setThreadedCompositingEnabled(bool enabled) { m_threadedCompositingEnabled = enabled; } void setForceCompositingMode(bool enabled) { m_forceCompositingMode = enabled; } @@ -170,6 +167,9 @@ public: void setIsDisplayingModalDialog(bool isDisplayingModalDialog) { m_isDisplayingModalDialog = isDisplayingModalDialog; } bool isDisplayingModalDialog() const { return m_isDisplayingModalDialog; } + // Set whether the binary data output should be encoded in base64 text. + void setEncodeBinary(bool encodeBinary) { m_printer.setEncodeBinary(encodeBinary); } + WebViewHost* createNewWindow(const WebKit::WebURL&); void closeWindow(WebViewHost*); void closeRemainingWindows(); @@ -207,16 +207,15 @@ private: bool m_isLoading; WebKit::WebView* m_webView; WebKit::WebWidget* m_focusedWidget; - bool m_testShellMode; WebViewHost* m_devTools; // Be careful of the destruction order of the following objects. - OwnPtr<TestEventPrinter> m_printer; + TestEventPrinter m_printer; OwnPtr<WebPermissions> m_webPermissions; OwnPtr<DRTDevToolsAgent> m_drtDevToolsAgent; OwnPtr<DRTDevToolsClient> m_drtDevToolsClient; OwnPtr<AccessibilityController> m_accessibilityController; - OwnPtr<GamepadController> m_gamepadController; + OwnPtr<TestInterfaces> m_testInterfaces; OwnPtr<EventSender> m_eventSender; OwnPtr<LayoutTestController> m_layoutTestController; OwnPtr<TextInputController> m_textInputController; diff --git a/Tools/DumpRenderTree/chromium/TestShellAndroid.cpp b/Tools/DumpRenderTree/chromium/TestShellAndroid.cpp index bc0acaad9..5f04fff5b 100644 --- a/Tools/DumpRenderTree/chromium/TestShellAndroid.cpp +++ b/Tools/DumpRenderTree/chromium/TestShellAndroid.cpp @@ -50,7 +50,7 @@ const char fontsDir[] = "/data/drt/fonts/"; const char optionInFIFO[] = "--in-fifo="; const char optionOutFIFO[] = "--out-fifo="; -const char optionErrFile[] = "--err-file="; +const char optionErrFIFO[] = "--err-fifo="; void androidLogError(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2); @@ -78,18 +78,7 @@ void createFIFO(const char* fifoPath) } } -void createFile(const char* filePath) -{ - unlink(filePath); - int fd = creat(filePath, 0600); - if (fd < 0) { - androidLogError("Failed to create file %s: %s\n", filePath, strerror(errno)); - exit(EXIT_FAILURE); - } - close(fd); -} - -void redirectToFile(FILE* stream, const char* path, const char* mode) +void redirect(FILE* stream, const char* path, const char* mode) { if (!freopen(path, mode, stream)) { androidLogError("Failed to redirect stream to file: %s: %s\n", path, strerror(errno)); @@ -106,7 +95,7 @@ void platformInit(int* argc, char*** argv) const char* inFIFO = 0; const char* outFIFO = 0; - const char* errFile = 0; + const char* errFIFO = 0; for (int i = 1; i < *argc; ) { const char* argument = (*argv)[i]; if (strstr(argument, optionInFIFO) == argument) { @@ -117,9 +106,9 @@ void platformInit(int* argc, char*** argv) outFIFO = argument + WTF_ARRAY_LENGTH(optionOutFIFO) - 1; createFIFO(outFIFO); removeArg(i, argc, argv); - } else if (strstr(argument, optionErrFile) == argument) { - errFile = argument + WTF_ARRAY_LENGTH(optionErrFile) - 1; - createFile(errFile); + } else if (strstr(argument, optionErrFIFO) == argument) { + errFIFO = argument + WTF_ARRAY_LENGTH(optionErrFIFO) - 1; + createFIFO(errFIFO); removeArg(i, argc, argv); } else ++i; @@ -127,11 +116,11 @@ void platformInit(int* argc, char*** argv) // The order of createFIFO() and redirectToFIFO() is important to avoid deadlock. if (outFIFO) - redirectToFile(stdout, outFIFO, "w"); + redirect(stdout, outFIFO, "w"); if (inFIFO) - redirectToFile(stdin, inFIFO, "r"); - if (errFile) - redirectToFile(stderr, errFile, "w"); + redirect(stdin, inFIFO, "r"); + if (errFIFO) + redirect(stderr, errFIFO, "w"); else { // Redirect stderr to stdout. dup2(1, 2); diff --git a/Tools/DumpRenderTree/efl/DumpRenderTree.cpp b/Tools/DumpRenderTree/efl/DumpRenderTree.cpp index aace475b5..ee26356ac 100644 --- a/Tools/DumpRenderTree/efl/DumpRenderTree.cpp +++ b/Tools/DumpRenderTree/efl/DumpRenderTree.cpp @@ -50,6 +50,7 @@ #include <unistd.h> #include <wtf/OwnPtr.h> #include <wtf/text/CString.h> +#include <wtf/text/StringBuilder.h> OwnPtr<DumpRenderTreeChrome> browser; Evas_Object* topLoadingFrame = 0; @@ -101,9 +102,40 @@ static String dumpFramesAsText(Evas_Object* frame) return result; } -static void dumpFrameScrollPosition(Evas_Object*) +static void dumpFrameScrollPosition(Evas_Object* frame) { - notImplemented(); + int x, y; + ewk_frame_scroll_pos_get(frame, &x, &y); + if (abs(x) > 0 || abs(y) > 0) { + StringBuilder result; + + Evas_Object* parent = evas_object_smart_parent_get(frame); + + // smart parent of main frame is view object. + if (parent != browser->mainView()) { + result.append("frame '"); + result.append(ewk_frame_name_get(frame)); + result.append("' "); + } + + result.append("scrolled to "); + result.append(WTF::String::number(x)); + result.append(","); + result.append(WTF::String::number(y)); + result.append("\n"); + + printf("%s", result.toString().utf8().data()); + } + + if (gLayoutTestController->dumpChildFrameScrollPositions()) { + Eina_List* children = DumpRenderTreeSupportEfl::frameChildren(frame); + void* iterator; + + EINA_LIST_FREE(children, iterator) { + Evas_Object* currentFrame = static_cast<Evas_Object*>(iterator); + dumpFrameScrollPosition(currentFrame); + } + } } static bool shouldLogFrameLoadDelegates(const String& pathOrURL) @@ -306,7 +338,7 @@ static void dumpFrameContentsAsText(Evas_Object* frame) static bool shouldDumpFrameScrollPosition() { - return gLayoutTestController->dumpAsText() && !gLayoutTestController->dumpDOMAsWebArchive() && !gLayoutTestController->dumpSourceAsWebArchive(); + return !gLayoutTestController->dumpAsText() && !gLayoutTestController->dumpDOMAsWebArchive() && !gLayoutTestController->dumpSourceAsWebArchive(); } static bool shouldDumpPixelsAndCompareWithExpected() diff --git a/Tools/GNUmakefile.am b/Tools/GNUmakefile.am index 14d597a2a..48c70d1fa 100644 --- a/Tools/GNUmakefile.am +++ b/Tools/GNUmakefile.am @@ -47,6 +47,8 @@ libWebCoreInternals_la_SOURCES = \ Source/WebCore/testing/Internals.h \ Source/WebCore/testing/InternalSettings.cpp \ Source/WebCore/testing/InternalSettings.h \ + Source/WebCore/testing/MockPagePopupDriver.cpp \ + Source/WebCore/testing/MockPagePopupDriver.h \ Source/WebCore/testing/js/WebCoreTestSupport.cpp \ Source/WebCore/testing/js/WebCoreTestSupport.h diff --git a/Tools/MiniBrowser/efl/CMakeLists.txt b/Tools/MiniBrowser/efl/CMakeLists.txt index a6fd2d57e..59cfc4fd1 100644 --- a/Tools/MiniBrowser/efl/CMakeLists.txt +++ b/Tools/MiniBrowser/efl/CMakeLists.txt @@ -55,6 +55,8 @@ ADD_CUSTOM_TARGET(forwarding-headerMiniBrowserSoup COMMAND ${PERL_EXECUTABLE} ${WEBKIT2_DIR}/Scripts/generate-forwarding-headers.pl ${MiniBrowser_DIR} ${DERIVED_SOURCES_WEBKIT2_DIR}/include soup ) +ADD_DEFINITIONS(-DTHEME_DIR=\"${THEME_BINARY_DIR}\") + INCLUDE_DIRECTORIES(${MiniBrowser_INCLUDE_DIRECTORIES}) ADD_EXECUTABLE(MiniBrowser ${MiniBrowser_SOURCES}) diff --git a/Tools/MiniBrowser/efl/main.c b/Tools/MiniBrowser/efl/main.c index f1614aa35..a979f5e55 100644 --- a/Tools/MiniBrowser/efl/main.c +++ b/Tools/MiniBrowser/efl/main.c @@ -163,6 +163,7 @@ static MiniBrowser *browserCreate(const char *url) /* Create webview */ app->browser = ewk_view_add(app->evas); + ewk_view_theme_set(app->browser, THEME_DIR"/default.edj"); evas_object_name_set(app->browser, "browser"); evas_object_smart_callback_add(app->browser, "load,error", on_error, app); diff --git a/Tools/MiniBrowser/qt/MiniBrowser.pro b/Tools/MiniBrowser/qt/MiniBrowser.pro index d54efad2f..e4530512c 100644 --- a/Tools/MiniBrowser/qt/MiniBrowser.pro +++ b/Tools/MiniBrowser/qt/MiniBrowser.pro @@ -6,7 +6,13 @@ TEMPLATE = app +WEBKIT += wtf + +INCLUDEPATH += \ + $${ROOT_WEBKIT_DIR}/Tools/DumpRenderTree/qt/ + SOURCES += \ + $${ROOT_WEBKIT_DIR}/Tools/DumpRenderTree/qt/QtInitializeTestFonts.cpp \ BrowserWindow.cpp \ main.cpp \ MiniBrowserApplication.cpp \ @@ -14,6 +20,7 @@ SOURCES += \ utils.cpp \ HEADERS += \ + $${ROOT_WEBKIT_DIR}/Tools/DumpRenderTree/qt/QtInitializeTestFonts.h \ BrowserWindow.h \ MiniBrowserApplication.h \ UrlLoader.h \ @@ -22,6 +29,8 @@ HEADERS += \ TARGET = MiniBrowser DESTDIR = $${ROOT_BUILD_DIR}/bin +contains(DEFINES, HAVE_FONTCONFIG=1): PKGCONFIG += fontconfig + QT += network gui-private quick quick-private webkit webkit-private macx: QT += xml diff --git a/Tools/MiniBrowser/qt/MiniBrowserApplication.cpp b/Tools/MiniBrowser/qt/MiniBrowserApplication.cpp index b85b234e1..f11f90d8c 100644 --- a/Tools/MiniBrowser/qt/MiniBrowserApplication.cpp +++ b/Tools/MiniBrowser/qt/MiniBrowserApplication.cpp @@ -29,6 +29,7 @@ #include "MiniBrowserApplication.h" #include "BrowserWindow.h" +#include "QtInitializeTestFonts.h" #include "private/qquickwebview_p.h" #include "utils.h" #include <QRegExp> @@ -324,6 +325,9 @@ void MiniBrowserApplication::handleUserOptions() m_windowOptions.setRequestedWindowSize(QSize(list.at(0).toInt(), list.at(1).toInt())); } + if (takeOptionFlag(&args, QStringLiteral("--use-test-fonts"))) + WebKit::initializeTestFonts(); + if (args.contains("-r")) { QString listFile = takeOptionValue(&args, "-r"); if (listFile.isEmpty()) diff --git a/Tools/Scripts/build-webkit b/Tools/Scripts/build-webkit index 44a1bbf0f..c37bce7d4 100755 --- a/Tools/Scripts/build-webkit +++ b/Tools/Scripts/build-webkit @@ -54,7 +54,6 @@ my $showHelp = 0; my $clean = 0; my $useGYP = 0; my $minimal = 0; -my $v8 = 0; my $installHeaders; my $installLibs; my $prefixPath; @@ -96,8 +95,6 @@ push @ARGV, split(/ /, $ENV{'BUILD_WEBKIT_ARGS'}) if ($ENV{'BUILD_WEBKIT_ARGS'}) foreach (@ARGV) { if ($_ eq '--minimal') { $minimal = 1; - } elsif ($_ eq '--v8') { - $v8 = 1; } } @@ -128,7 +125,6 @@ Usage: $programName [options] [options to pass to build system] --install-headers=<path> Set installation path for the headers (Qt only) --install-libs=<path> Set installation path for the libraries (Qt only) - --v8 Use V8 as JavaScript engine (Qt only) --prefix=<path> Set installation prefix to the given path (Gtk/Efl/BlackBerry only) --makeargs=<arguments> Optional Makefile flags @@ -152,7 +148,6 @@ my %options = ( 'makeargs=s' => \$makeArgs, 'cmakeargs=s' => \$cmakeArgs, 'minimal' => \$minimal, - 'v8' => \$v8, 'only-webkit' => \$onlyWebKitProject, 'no-webkit2' => \$noWebKit2, 'coverage' => \$coverageSupport, @@ -272,13 +267,6 @@ if (isGtk()) { foreach (@features) { push @options, "DEFINES+=$_->{define}=${$_->{value}}" if $_->{define} && ${$_->{value}} != $_->{default}; } - - if ($v8) { - print "Building WebKit2 with v8 is not supported currently. Disabling WebKit2.\n"; - # FIXME: Deal with this in defaults_pre, once Qt has support for getting at the - # command line arguments at that stage. - push @options, "CONFIG+=v8 CONFIG+=no_webkit2"; - } } # If asked to build just the WebKit project, overwrite the projects diff --git a/Tools/Scripts/generate-win32-export-forwards b/Tools/Scripts/generate-win32-export-forwards index 768b3ba93..e75b430f4 100755 --- a/Tools/Scripts/generate-win32-export-forwards +++ b/Tools/Scripts/generate-win32-export-forwards @@ -27,27 +27,22 @@ import subprocess import sys import re -def exportForwardsForLibrary(library): - dumpBin = subprocess.Popen("dumpbin /directives " + library, stdout=subprocess.PIPE, universal_newlines=True); +dumpBin = subprocess.Popen("dumpbin /directives " + sys.argv[1], stdout=subprocess.PIPE, universal_newlines=True); - output, errors = dumpBin.communicate(); - return output - -libraries = sys.argv[1 : len(sys.argv) - 1] -outputFileName = sys.argv[len(sys.argv) - 1] +output, errors = dumpBin.communicate(); exportedSymbolRegexp = re.compile("\s*(?P<symbol>/EXPORT:.+)"); + symbols = set() -for lib in libraries: - for line in exportForwardsForLibrary(lib).splitlines(): - match = exportedSymbolRegexp.match(line) - if match != None: - symbols.add(match.group("symbol")) +for line in output.splitlines(): + match = exportedSymbolRegexp.match(line) + if match != None: + symbols.add(match.group("symbol")) -print "Forwarding %s symbols from %s" % (len(symbols), " ".join(libraries)) +print "Forwarding %s symbols from static library %s" % (len(symbols), sys.argv[1]) -exportFile = open(outputFileName, "w") +exportFile = open(sys.argv[2], "w") for symbol in symbols: exportFile.write("#pragma comment(linker, \"%s\")\n" % symbol); exportFile.close() diff --git a/Tools/Scripts/webkitdirs.pm b/Tools/Scripts/webkitdirs.pm index 1da09471b..58c55a49c 100755 --- a/Tools/Scripts/webkitdirs.pm +++ b/Tools/Scripts/webkitdirs.pm @@ -335,6 +335,12 @@ sub determineArchitecture $architecture = `arch`; chomp $architecture; } + + if (!$architecture && (isGtk() || isAppleMacWebKit() || isEfl())) { + # Fall back to output of `uname -m', if it is present. + $architecture = `uname -m`; + chomp $architecture; + } } sub determineNumberOfCPUs diff --git a/Tools/Scripts/webkitperl/FeatureList.pm b/Tools/Scripts/webkitperl/FeatureList.pm index ca3b9e3d6..1ca67a0d9 100644 --- a/Tools/Scripts/webkitperl/FeatureList.pm +++ b/Tools/Scripts/webkitperl/FeatureList.pm @@ -53,6 +53,7 @@ my ( $cssBoxDecorationBreakSupport, $cssExclusionsSupport, $cssFiltersSupport, + $cssImageOrientationSupport, $cssImageResolutionSupport, $cssRegionsSupport, $cssShadersSupport, @@ -166,6 +167,9 @@ my @features = ( { option => "css-box-decoration-break", desc => "Toggle CSS box-decoration-break support", define => "ENABLE_CSS_BOX_DECORATION_BREAK", default => 1, value => \$cssBoxDecorationBreakSupport }, + { option => "css-image-orientation", desc => "Toggle CSS image-orientation support", + define => "ENABLE_CSS_IMAGE_ORIENTATION", default => 0, value => \$cssImageOrientationSupport }, + { option => "css-image-resolution", desc => "Toggle CSS image-resolution support", define => "ENABLE_CSS_IMAGE_RESOLUTION", default => 0, value => \$cssImageResolutionSupport }, diff --git a/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer.py b/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer.py index d244045ac..f9767168c 100644 --- a/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer.py +++ b/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer.py @@ -136,17 +136,14 @@ class BaselineOptimizer(object): break # Frowns. We do not appear to be converging. unsatisfied_port_names_by_result = new_unsatisfied_port_names_by_result - self._filter_virtual_ports(new_results_by_directory) return results_by_directory, new_results_by_directory - def _filter_virtual_ports(self, new_results_by_directory): - for port in _VIRTUAL_PORTS: - virtual_directory = _VIRTUAL_PORTS[port][0] - if virtual_directory in new_results_by_directory: - real_directory = _VIRTUAL_PORTS[port][1] - if real_directory not in new_results_by_directory: - new_results_by_directory[real_directory] = new_results_by_directory[virtual_directory] - del new_results_by_directory[virtual_directory] + def _filtered_results_by_port_name(self, results_by_directory): + results_by_port_name = self._results_by_port_name(results_by_directory) + for port_name in _VIRTUAL_PORTS.keys(): + if port_name in results_by_port_name: + del results_by_port_name[port_name] + return results_by_port_name def _move_baselines(self, baseline_name, results_by_directory, new_results_by_directory): data_for_result = {} @@ -178,7 +175,7 @@ class BaselineOptimizer(object): def optimize(self, baseline_name): results_by_directory, new_results_by_directory = self._find_optimal_result_placement(baseline_name) - if self._results_by_port_name(results_by_directory) != self._results_by_port_name(new_results_by_directory): + if self._filtered_results_by_port_name(results_by_directory) != self._filtered_results_by_port_name(new_results_by_directory): return False self._move_baselines(baseline_name, results_by_directory, new_results_by_directory) return True diff --git a/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer_unittest.py b/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer_unittest.py index 9ba6ff1f2..0325991d1 100644 --- a/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer_unittest.py +++ b/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer_unittest.py @@ -45,12 +45,19 @@ class TestBaselineOptimizer(BaselineOptimizer): def _read_results_by_directory(self, baseline_name): return self._mock_results_by_directory + def _move_baselines(self, baseline_name, results_by_directory, new_results_by_directory): + self.new_results_by_directory = new_results_by_directory + class BaselineOptimizerTest(unittest.TestCase): def _assertOptimization(self, results_by_directory, expected_new_results_by_directory): baseline_optimizer = TestBaselineOptimizer(results_by_directory) - _, new_results_by_directory = baseline_optimizer._find_optimal_result_placement('mock-baseline.png') - self.assertEqual(new_results_by_directory, expected_new_results_by_directory) + self.assertTrue(baseline_optimizer.optimize('mock-baseline.png')) + self.assertEqual(baseline_optimizer.new_results_by_directory, expected_new_results_by_directory) + + def _assertOptimizationFailed(self, results_by_directory): + baseline_optimizer = TestBaselineOptimizer(results_by_directory) + self.assertFalse(baseline_optimizer.optimize('mock-baseline.png')) def test_move_baselines(self): host = MockHost() @@ -135,18 +142,13 @@ class BaselineOptimizerTest(unittest.TestCase): }) def test_common_directory_includes_root(self): - # Note: The resulting directories are "wrong" in the sense that - # enacting this plan would change semantics. However, this test case - # demonstrates that we don't throw an exception in this case. :) - self._assertOptimization({ + # This test case checks that we don't throw an exception when we fail + # to optimize. + self._assertOptimizationFailed({ 'LayoutTests/platform/gtk': 'e8608763f6241ddacdd5c1ef1973ba27177d0846', 'LayoutTests/platform/qt': 'bcbd457d545986b7abf1221655d722363079ac87', 'LayoutTests/platform/chromium-win': '3764ac11e1f9fbadd87a90a2e40278319190a0d3', 'LayoutTests/platform/mac': 'e8608763f6241ddacdd5c1ef1973ba27177d0846', - }, { - 'LayoutTests/platform/qt': 'bcbd457d545986b7abf1221655d722363079ac87', - 'LayoutTests/platform/chromium-win': '3764ac11e1f9fbadd87a90a2e40278319190a0d3', - 'LayoutTests': 'e8608763f6241ddacdd5c1ef1973ba27177d0846', }) self._assertOptimization({ @@ -181,3 +183,20 @@ class BaselineOptimizerTest(unittest.TestCase): 'LayoutTests/platform/win-xp': '5b1253ef4d5094530d5f1bc6cdb95c90b446bec7', 'LayoutTests/platform/chromium-linux': 'f52fcdde9e4be8bd5142171cd859230bd4471036' }) + + def test_virtual_ports_filtered(self): + self._assertOptimization({ + 'LayoutTests/platform/chromium-mac': '1', + 'LayoutTests/platform/chromium-mac-snowleopard': '1', + 'LayoutTests/platform/chromium-win': '2', + 'LayoutTests/platform/gtk': '3', + 'LayoutTests/platform/efl': '3', + 'LayoutTests/platform/qt': '4', + 'LayoutTests/platform/mac': '5', + }, { + 'LayoutTests/platform/chromium-mac': '1', + 'LayoutTests/platform/chromium-win': '2', + 'LayoutTests': '3', + 'LayoutTests/platform/qt': '4', + 'LayoutTests/platform/mac': '5', + }) diff --git a/Tools/Scripts/webkitpy/common/config/watchlist b/Tools/Scripts/webkitpy/common/config/watchlist index c11656322..127772c80 100755 --- a/Tools/Scripts/webkitpy/common/config/watchlist +++ b/Tools/Scripts/webkitpy/common/config/watchlist @@ -102,6 +102,17 @@ r"|Source/WebKit2/UIProcess/API/cpp/qt/" r"|Source/WebKit2/UIProcess/API/C/qt/", }, + "QtGraphics": { + "filename": r"Source/WebCore/platform/graphics/qt/" + r"|Source/WebKit2/WebProcess/WebPage/LayerTreeCoordinator/" + r"|Source/WebKit2/UIProcess/WebLayerTreeRenderer(?!\.(h|cpp))", + }, + "TextureMapper": { + "filename": r"Source/WebCore/platform/graphics/texmap/", + }, + "OpenGL": { + "filename": r"Source/WebCore/platform/graphics/opengl/", + }, "QtWebKit2PlatformSpecific": { "filename": r"Source/WebKit2/.*\.(pri|pro)" r"|Source/WebKit2/Platform/qt/" @@ -138,6 +149,24 @@ r"|Tools/DumpRenderTree/efl/" r"|LayoutTests/platform/efl/", }, + "EFLWebKit2PublicAPI": { + "filename": r"Source/WebKit2/UIProcess/API/efl/" + r"|Source/WebKit2/UIProcess/API/C/efl/", + }, + "EFLWebKit2PlatformSpecific": { + "filename": r"Source/WebKit2/.*\.(cmake|txt)" + r"|Source/WebKit2/Platform/efl/" + r"|Source/WebKit2/efl/" + r"|Source/WebKit2/Shared/API/c/efl/" + r"|Source/WebKit2/Shared/efl/" + r"|Source/WebKit2/WebProcess/InjectedBundle/efl/" + r"|Source/WebKit2/WebProcess/WebPage/efl/" + r"|Source/WebKit2/WebProcess/efl/" + r"|Source/WebKit2/WebProcess/Downloads/efl/" + r"|Source/WebKit2/WebProcess/WebCoreSupport/efl/" + r"|Source/WebKit2/UIProcess/efl/" + r"|Source/WebKit2/UIProcess/Launcher/efl/", + }, "CMake": { "filename": r".*CMakeLists\w*\.txt" r"|.*\w+\.cmake" @@ -178,6 +207,12 @@ r"|Tools/DumpRenderTree/blackberry" r"|LayoutTests/platform/blackberry", }, + "NetworkInfo": { + "filename": r"Source/WebCore/Modules/networkinfo", + }, + "Battery": { + "filename": r"Source/WebCore/Modules/battery", + }, }, "CC_RULES": { @@ -185,14 +220,17 @@ # Specifically, levin@chromium.org and levin+threading@chromium.org are # two different accounts as far as bugzilla is concerned. "AppleMacPublicApi": [ "timothy@apple.com" ], + "Battery": [ "gyuyoung.kim@samsung.com" ], "BlackBerry": [ "mifenton@rim.com" ], - "CMake": [ "rakuco@webkit.org", ], + "CMake": [ "rakuco@webkit.org", "gyuyoung.kim@samsung.com" ], "CSS": [ "alexis.menard@openbossa.org", "macpherson@chromium.org", "cmarcelo@webkit.org" ], "ChromiumDumpRenderTree": [ "tkent@chromium.org", ], "ChromiumGraphics": [ "jamesr@chromium.org", "cc-bugs@google.com" ], "ChromiumPublicApi": [ "abarth@webkit.org", "dglazkov@chromium.org", "fishd@chromium.org", "jamesr@chromium.org", "tkent+wkapi@chromium.org" ], "DOMAttributes": [ "cmarcelo@webkit.org", ], - "EFL": [ "rakuco@webkit.org", ], + "EFL": [ "rakuco@webkit.org", "gyuyoung.kim@samsung.com" ], + "EFLWebKit2PlatformSpecific": [ "gyuyoung.kim@samsung.com" ], + "EFLWebKit2PublicAPI": [ "gyuyoung.kim@samsung.com" ], "Editing": [ "mifenton@rim.com" ], "Forms": [ "tkent@chromium.org", "mifenton@rim.com" ], "FrameLoader": [ "abarth@webkit.org", "japhet@chromium.org", "jochen@chromium.org" ], @@ -201,7 +239,10 @@ "Loader": [ "japhet@chromium.org", "jochen@chromium.org" ], "MathML": [ "dbarton@mathscribe.com" ], "Media": [ "feature-media-reviews@chromium.org", "eric.carlson@apple.com" ], + "NetworkInfo": [ "gyuyoung.kim@samsung.com" ], + "OpenGL" : [ "noam.rosenthal@nokia.com" ], "QtBuildSystem" : [ "vestbo@webkit.org", ], + "QtGraphics" : [ "noam.rosenthal@nokia.com" ], "QtWebKit2PlatformSpecific": [ "alexis.menard@openbossa.org", "zoltan@webkit.org", "cmarcelo@webkit.org" ], "QtWebKit2PublicAPI": [ "alexis.menard@openbossa.org", "zoltan@webkit.org", "cmarcelo@webkit.org" ], "Rendering": [ "eric@webkit.org" ], @@ -210,6 +251,7 @@ "SoupNetwork": [ "rakuco@webkit.org", "gns@gnome.org", "mrobinson@webkit.org", "danw@gnome.org" ], "StyleChecker": [ "levin@chromium.org", ], "TestFailures": [ "abarth@webkit.org", "dglazkov@chromium.org" ], + "TextureMapper" : [ "noam.rosenthal@nokia.com" ], "ThreadingFiles|ThreadingUsage": [ "levin+threading@chromium.org", ], "V8Bindings|BindingsScripts": [ "abarth@webkit.org", "japhet@chromium.org", "haraken@chromium.org", "jochen@chromium.org" ], "WatchListScript": [ "levin+watchlist@chromium.org", ], diff --git a/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py b/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py index 7aee0c2fb..0d07d3a68 100644 --- a/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py +++ b/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py @@ -417,19 +417,14 @@ class Manager(object): files = test_files[slice_start:slice_end] - tests_run_msg = 'Running: %d tests (chunk slice [%d:%d] of %d)' % ((slice_end - slice_start), slice_start, slice_end, num_tests) - self._printer.print_expected(tests_run_msg) + _log.debug('chunk slice [%d:%d] of %d is %d tests' % (slice_start, slice_end, num_tests, (slice_end - slice_start))) # If we reached the end and we don't have enough tests, we run some # from the beginning. if slice_end - slice_start < chunk_len: extra = chunk_len - (slice_end - slice_start) - extra_msg = (' last chunk is partial, appending [0:%d]' % extra) - self._printer.print_expected(extra_msg) - tests_run_msg += "\n" + extra_msg + _log.debug(' last chunk is partial, appending [0:%d]' % extra) files.extend(test_files[0:extra]) - tests_run_filename = self._filesystem.join(self._results_directory, "tests_run.txt") - self._filesystem.write_text_file(tests_run_filename, tests_run_msg) len_skip_chunk = int(len(files) * len(skipped) / float(len(self._test_files))) skip_chunk_list = list(skipped)[0:len_skip_chunk] @@ -512,11 +507,7 @@ class Manager(object): (self._options.iterations if self._options.iterations else 1) result_summary = ResultSummary(self._expectations, self._test_files | skipped, iterations) - self._printer.print_expected('Found %s.' % grammar.pluralize('test', num_all_test_files)) - self._print_expected_results_of_type(result_summary, test_expectations.PASS, "passes") - self._print_expected_results_of_type(result_summary, test_expectations.FAIL, "failures") - self._print_expected_results_of_type(result_summary, test_expectations.FLAKY, "flaky") - self._print_expected_results_of_type(result_summary, test_expectations.SKIP, "skipped") + self._printer.print_expected(num_all_test_files, result_summary, self._expectations.get_tests_with_result_type) if self._options.skipped != 'ignore': # Note that we don't actually run the skipped tests (they were @@ -526,15 +517,7 @@ class Manager(object): result = test_results.TestResult(test) result.type = test_expectations.SKIP for iteration in range(iterations): - result_summary.add(result, expected=True) - self._printer.print_expected('') - - if self._options.repeat_each > 1: - self._printer.print_expected('Running each test %d times.' % self._options.repeat_each) - if self._options.iterations > 1: - self._printer.print_expected('Running %d iterations of the tests.' % self._options.iterations) - if iterations > 1: - self._printer.print_expected('') + result_summary.add(result, expected=True, test_is_slow=self._test_is_slow(test)) return result_summary @@ -567,7 +550,13 @@ class Manager(object): def _test_is_slow(self, test_file): return self._expectations.has_modifier(test_file, test_expectations.SLOW) - def _shard_tests(self, test_files, num_workers, fully_parallel): + def _is_ref_test(self, test_input): + if test_input.reference_files is None: + # Lazy initialization. + test_input.reference_files = self._port.reference_files(test_input.test_name) + return bool(test_input.reference_files) + + def _shard_tests(self, test_files, num_workers, fully_parallel, shard_ref_tests): """Groups tests into batches. This helps ensure that tests that depend on each other (aka bad tests!) continue to run together as most cross-tests dependencies tend to @@ -581,30 +570,40 @@ class Manager(object): # own class or module. Consider grouping it with the chunking logic # in prepare_lists as well. if num_workers == 1: - return self._shard_in_two(test_files) + return self._shard_in_two(test_files, shard_ref_tests) elif fully_parallel: return self._shard_every_file(test_files) - return self._shard_by_directory(test_files, num_workers) + return self._shard_by_directory(test_files, num_workers, shard_ref_tests) - def _shard_in_two(self, test_files): + def _shard_in_two(self, test_files, shard_ref_tests): """Returns two lists of shards, one with all the tests requiring a lock and one with the rest. This is used when there's only one worker, to minimize the per-shard overhead.""" locked_inputs = [] + locked_ref_test_inputs = [] unlocked_inputs = [] + unlocked_ref_test_inputs = [] for test_file in test_files: test_input = self._get_test_input_for_file(test_file) if self._test_requires_lock(test_file): - locked_inputs.append(test_input) + if shard_ref_tests and self._is_ref_test(test_input): + locked_ref_test_inputs.append(test_input) + else: + locked_inputs.append(test_input) else: - unlocked_inputs.append(test_input) + if shard_ref_tests and self._is_ref_test(test_input): + unlocked_ref_test_inputs.append(test_input) + else: + unlocked_inputs.append(test_input) + locked_inputs.extend(locked_ref_test_inputs) + unlocked_inputs.extend(unlocked_ref_test_inputs) locked_shards = [] unlocked_shards = [] if locked_inputs: locked_shards = [TestShard('locked_tests', locked_inputs)] if unlocked_inputs: - unlocked_shards = [TestShard('unlocked_tests', unlocked_inputs)] + unlocked_shards.append(TestShard('unlocked_tests', unlocked_inputs)) return locked_shards, unlocked_shards @@ -627,7 +626,7 @@ class Manager(object): return locked_shards, unlocked_shards - def _shard_by_directory(self, test_files, num_workers): + def _shard_by_directory(self, test_files, num_workers, shard_ref_tests): """Returns two lists of shards, each shard containing all the files in a directory. This is the default mode, and gets as much parallelism as we can while @@ -635,13 +634,18 @@ class Manager(object): locked_shards = [] unlocked_shards = [] tests_by_dir = {} + ref_tests_by_dir = {} # FIXME: Given that the tests are already sorted by directory, # we can probably rewrite this to be clearer and faster. for test_file in test_files: directory = self._get_dir_for_test_file(test_file) test_input = self._get_test_input_for_file(test_file) - tests_by_dir.setdefault(directory, []) - tests_by_dir[directory].append(test_input) + if shard_ref_tests and self._is_ref_test(test_input): + ref_tests_by_dir.setdefault(directory, []) + ref_tests_by_dir[directory].append(test_input) + else: + tests_by_dir.setdefault(directory, []) + tests_by_dir[directory].append(test_input) for directory, test_inputs in tests_by_dir.iteritems(): shard = TestShard(directory, test_inputs) @@ -650,6 +654,14 @@ class Manager(object): else: unlocked_shards.append(shard) + for directory, test_inputs in ref_tests_by_dir.iteritems(): + # '~' to place the ref tests after other tests after sorted. + shard = TestShard('~ref:' + directory, test_inputs) + if self._test_requires_lock(directory): + locked_shards.append(shard) + else: + unlocked_shards.append(shard) + # Sort the shards by directory name. locked_shards.sort(key=lambda shard: shard.name) unlocked_shards.sort(key=lambda shard: shard.name) @@ -706,16 +718,6 @@ class Manager(object): extract_and_flatten(some_shards))) return new_shards - def _log_num_workers(self, num_workers, num_shards, num_locked_shards): - driver_name = self._port.driver_name() - if num_workers == 1: - self._printer.print_config("Running 1 %s over %s." % - (driver_name, grammar.pluralize('shard', num_shards))) - else: - self._printer.print_config("Running %d %ss in parallel over %d shards (%d locked)." % - (num_workers, driver_name, num_shards, num_locked_shards)) - self._printer.print_config('') - def _run_tests(self, file_list, result_summary, num_workers): """Runs the tests in the file_list. @@ -740,8 +742,8 @@ class Manager(object): keyboard_interrupted = False interrupted = False - self._printer.print_update('Sharding tests ...') - locked_shards, unlocked_shards = self._shard_tests(file_list, int(self._options.child_processes), self._options.fully_parallel) + self._printer.write_update('Sharding tests ...') + locked_shards, unlocked_shards = self._shard_tests(file_list, int(self._options.child_processes), self._options.fully_parallel, self._options.shard_ref_tests) # FIXME: We don't have a good way to coordinate the workers so that # they don't try to run the shards that need a lock if we don't actually @@ -757,7 +759,7 @@ class Manager(object): self.start_servers_with_lock(2 * min(num_workers, len(locked_shards))) num_workers = min(num_workers, len(all_shards)) - self._log_num_workers(num_workers, len(all_shards), len(locked_shards)) + self._printer.print_workers_and_shards(num_workers, len(all_shards), len(locked_shards)) def worker_factory(worker_connection): return worker.Worker(worker_connection, self.results_directory(), self._options) @@ -765,7 +767,7 @@ class Manager(object): if self._options.dry_run: return (keyboard_interrupted, interrupted, self._worker_stats.values(), self._group_stats, self._all_results) - self._printer.print_update('Starting %s ...' % grammar.pluralize('worker', num_workers)) + self._printer.write_update('Starting %s ...' % grammar.pluralize('worker', num_workers)) try: with message_pool.get(self, worker_factory, num_workers, self._port.worker_startup_delay_secs(), self._port.host) as pool: @@ -793,9 +795,6 @@ class Manager(object): self._filesystem.maybe_make_directory(self._filesystem.join(self._results_directory, 'retries')) return self._filesystem.join(self._results_directory, 'retries') - def update(self): - self.update_summary(self._current_result_summary) - def needs_servers(self): return any(self._test_requires_lock(test_name) for test_name in self._test_files) and self._options.http @@ -809,12 +808,12 @@ class Manager(object): # This must be started before we check the system dependencies, # since the helper may do things to make the setup correct. if self._options.pixel_tests: - self._printer.print_update("Starting pixel test helper ...") + self._printer.write_update("Starting pixel test helper ...") self._port.start_helper() # Check that the system dependencies (themes, fonts, ...) are correct. if not self._options.nocheck_sys_deps: - self._printer.print_update("Checking system dependencies ...") + self._printer.write_update("Checking system dependencies ...") if not self._port.check_sys_deps(self.needs_servers()): self._port.stop_helper() return None @@ -827,7 +826,7 @@ class Manager(object): self._port.setup_test_run() - self._printer.print_update("Preparing tests ...") + self._printer.write_update("Preparing tests ...") result_summary = self.prepare_lists_and_print_output() if not result_summary: return None @@ -882,13 +881,9 @@ class Manager(object): self._look_for_new_crash_logs(retry_summary, start_time) self._clean_up_run() - self._print_timing_statistics(end_time - start_time, thread_timings, test_timings, individual_test_timings, result_summary) - self._print_result_summary(result_summary) - - self._printer.print_one_line_summary(result_summary.total - result_summary.expected_skips, result_summary.expected - result_summary.expected_skips, result_summary.unexpected) - unexpected_results = summarize_results(self._port, self._expectations, result_summary, retry_summary, individual_test_timings, only_unexpected=True, interrupted=interrupted) - self._printer.print_unexpected_results(unexpected_results) + + self._printer.print_results(end_time - start_time, thread_timings, test_timings, individual_test_timings, result_summary, unexpected_results) # Re-raise a KeyboardInterrupt if necessary so the caller can handle it. if keyboard_interrupted: @@ -911,25 +906,25 @@ class Manager(object): return self._port.exit_code_from_summarized_results(unexpected_results) def start_servers_with_lock(self, number_of_servers): - self._printer.print_update('Acquiring http lock ...') + self._printer.write_update('Acquiring http lock ...') self._port.acquire_http_lock() if self._http_tests(): - self._printer.print_update('Starting HTTP server ...') + self._printer.write_update('Starting HTTP server ...') self._port.start_http_server(number_of_servers=number_of_servers) if self._websocket_tests(): - self._printer.print_update('Starting WebSocket server ...') + self._printer.write_update('Starting WebSocket server ...') self._port.start_websocket_server() self._has_http_lock = True def stop_servers_with_lock(self): if self._has_http_lock: if self._http_tests(): - self._printer.print_update('Stopping HTTP server ...') + self._printer.write_update('Stopping HTTP server ...') self._port.stop_http_server() if self._websocket_tests(): - self._printer.print_update('Stopping WebSocket server ...') + self._printer.write_update('Stopping WebSocket server ...') self._port.stop_websocket_server() - self._printer.print_update('Releasing server lock ...') + self._printer.write_update('Releasing server lock ...') self._port.release_http_lock() self._has_http_lock = False @@ -967,17 +962,6 @@ class Manager(object): writer = TestResultWriter(self._port._filesystem, self._port, self._port.results_directory(), test) writer.write_crash_log(crash_log) - def update_summary(self, result_summary): - """Update the summary and print results with any completed tests.""" - while True: - try: - result = test_results.TestResult.loads(self._result_queue.get_nowait()) - except Queue.Empty: - self._printer.print_progress(result_summary, self._retrying, self._test_files_list) - return - - self._update_summary_with_result(result_summary, result) - def _mark_interrupted_tests_as_skipped(self, result_summary): for test_name in self._test_files: if test_name not in result_summary.results: @@ -985,7 +969,7 @@ class Manager(object): # FIXME: We probably need to loop here if there are multiple iterations. # FIXME: Also, these results are really neither expected nor unexpected. We probably # need a third type of result. - result_summary.add(result, expected=False) + result_summary.add(result, expected=False, test_is_slow=self._test_is_slow(test_name)) def _interrupt_if_at_failure_limits(self, result_summary): # Note: The messages in this method are constructed to match old-run-webkit-tests @@ -1010,21 +994,25 @@ class Manager(object): def _update_summary_with_result(self, result_summary, result): if result.type == test_expectations.SKIP: - result_summary.add(result, expected=True) + exp_str = got_str = 'SKIP' + expected = True else: expected = self._expectations.matches_an_expected_result(result.test_name, result.type, self._options.pixel_tests or test_failures.is_reftest_failure(result.failures)) - result_summary.add(result, expected) exp_str = self._expectations.get_expectations_string(result.test_name) got_str = self._expectations.expectation_to_string(result.type) - self._printer.print_test_result(result, expected, exp_str, got_str) - self._printer.print_progress(result_summary, self._retrying, self._test_files_list) + + result_summary.add(result, expected, self._test_is_slow(result.test_name)) + + # FIXME: there's too many arguments to this function. + self._printer.print_finished_test(result, expected, exp_str, got_str, result_summary, self._retrying, self._test_files_list) + self._interrupt_if_at_failure_limits(result_summary) def _clobber_old_results(self): # Just clobber the actual test results directories since the other # files in the results directory are explicitly used for cross-run # tracking. - self._printer.print_update("Clobbering old results in %s" % + self._printer.write_update("Clobbering old results in %s" % self._results_directory) layout_tests_dir = self._port.layout_tests_dir() possible_dirs = self._port.test_dirs() @@ -1105,53 +1093,6 @@ class Manager(object): self._filesystem.remove(times_json_path) self._filesystem.remove(incremental_results_path) - def print_config(self): - """Prints the configuration for the test run.""" - p = self._printer - p.print_config("Using port '%s'" % self._port.name()) - p.print_config("Test configuration: %s" % self._port.test_configuration()) - p.print_config("Placing test results in %s" % self._results_directory) - if self._options.new_baseline: - p.print_config("Placing new baselines in %s" % - self._port.baseline_path()) - - fallback_path = [self._filesystem.split(x)[1] for x in self._port.baseline_search_path()] - p.print_config("Baseline search path: %s -> generic" % " -> ".join(fallback_path)) - - p.print_config("Using %s build" % self._options.configuration) - if self._options.pixel_tests: - p.print_config("Pixel tests enabled") - else: - p.print_config("Pixel tests disabled") - - p.print_config("Regular timeout: %s, slow test timeout: %s" % - (self._options.time_out_ms, - self._options.slow_time_out_ms)) - - p.print_config('Command line: ' + - ' '.join(self._port.driver_cmd_line())) - p.print_config("") - - def _print_expected_results_of_type(self, result_summary, - result_type, result_type_str): - """Print the number of the tests in a given result class. - - Args: - result_summary - the object containing all the results to report on - result_type - the particular result type to report in the summary. - result_type_str - a string description of the result_type. - """ - tests = self._expectations.get_tests_with_result_type(result_type) - now = result_summary.tests_by_timeline[test_expectations.NOW] - wontfix = result_summary.tests_by_timeline[test_expectations.WONTFIX] - - # We use a fancy format string in order to print the data out in a - # nicely-aligned table. - fmtstr = ("Expect: %%5d %%-8s (%%%dd now, %%%dd wontfix)" - % (self._num_digits(now), self._num_digits(wontfix))) - self._printer.print_expected(fmtstr % - (len(tests), result_type_str, len(tests & now), len(tests & wontfix))) - def _num_digits(self, num): """Returns the number of digits needed to represent the length of a sequence.""" @@ -1160,217 +1101,6 @@ class Manager(object): ndigits = int(math.log10(len(num))) + 1 return ndigits - def _print_timing_statistics(self, total_time, thread_timings, - directory_test_timings, individual_test_timings, - result_summary): - """Record timing-specific information for the test run. - - Args: - total_time: total elapsed time (in seconds) for the test run - thread_timings: wall clock time each thread ran for - directory_test_timings: timing by directory - individual_test_timings: timing by file - result_summary: summary object for the test run - """ - self._printer.print_timing("Test timing:") - self._printer.print_timing(" %6.2f total testing time" % total_time) - self._printer.print_timing("") - self._printer.print_timing("Thread timing:") - cuml_time = 0 - for t in thread_timings: - self._printer.print_timing(" %10s: %5d tests, %6.2f secs" % - (t['name'], t['num_tests'], t['total_time'])) - cuml_time += t['total_time'] - self._printer.print_timing(" %6.2f cumulative, %6.2f optimal" % - (cuml_time, cuml_time / int(self._options.child_processes))) - self._printer.print_timing("") - - self._print_aggregate_test_statistics(individual_test_timings) - self._print_individual_test_times(individual_test_timings, - result_summary) - self._print_directory_timings(directory_test_timings) - - def _print_aggregate_test_statistics(self, individual_test_timings): - """Prints aggregate statistics (e.g. median, mean, etc.) for all tests. - Args: - individual_test_timings: List of TestResults for all tests. - """ - times_for_dump_render_tree = [test_stats.test_run_time for test_stats in individual_test_timings] - self._print_statistics_for_test_timings("PER TEST TIME IN TESTSHELL (seconds):", - times_for_dump_render_tree) - - def _print_individual_test_times(self, individual_test_timings, - result_summary): - """Prints the run times for slow, timeout and crash tests. - Args: - individual_test_timings: List of TestStats for all tests. - result_summary: summary object for test run - """ - # Reverse-sort by the time spent in DumpRenderTree. - individual_test_timings.sort(lambda a, b: - cmp(b.test_run_time, a.test_run_time)) - - num_printed = 0 - slow_tests = [] - timeout_or_crash_tests = [] - unexpected_slow_tests = [] - for test_tuple in individual_test_timings: - test_name = test_tuple.test_name - is_timeout_crash_or_slow = False - if self._test_is_slow(test_name): - is_timeout_crash_or_slow = True - slow_tests.append(test_tuple) - - if test_name in result_summary.failures: - result = result_summary.results[test_name].type - if (result == test_expectations.TIMEOUT or - result == test_expectations.CRASH): - is_timeout_crash_or_slow = True - timeout_or_crash_tests.append(test_tuple) - - if (not is_timeout_crash_or_slow and - num_printed < printing.NUM_SLOW_TESTS_TO_LOG): - num_printed = num_printed + 1 - unexpected_slow_tests.append(test_tuple) - - self._printer.print_timing("") - self._print_test_list_timing("%s slowest tests that are not " - "marked as SLOW and did not timeout/crash:" % - printing.NUM_SLOW_TESTS_TO_LOG, unexpected_slow_tests) - self._printer.print_timing("") - self._print_test_list_timing("Tests marked as SLOW:", slow_tests) - self._printer.print_timing("") - self._print_test_list_timing("Tests that timed out or crashed:", - timeout_or_crash_tests) - self._printer.print_timing("") - - def _print_test_list_timing(self, title, test_list): - """Print timing info for each test. - - Args: - title: section heading - test_list: tests that fall in this section - """ - if self._printer.disabled('slowest'): - return - - self._printer.print_timing(title) - for test_tuple in test_list: - test_run_time = round(test_tuple.test_run_time, 1) - self._printer.print_timing(" %s took %s seconds" % (test_tuple.test_name, test_run_time)) - - def _print_directory_timings(self, directory_test_timings): - """Print timing info by directory for any directories that - take > 10 seconds to run. - - Args: - directory_test_timing: time info for each directory - """ - timings = [] - for directory in directory_test_timings: - num_tests, time_for_directory = directory_test_timings[directory] - timings.append((round(time_for_directory, 1), directory, - num_tests)) - timings.sort() - - self._printer.print_timing("Time to process slowest subdirectories:") - min_seconds_to_print = 10 - for timing in timings: - if timing[0] > min_seconds_to_print: - self._printer.print_timing( - " %s took %s seconds to run %s tests." % (timing[1], - timing[0], timing[2])) - self._printer.print_timing("") - - def _print_statistics_for_test_timings(self, title, timings): - """Prints the median, mean and standard deviation of the values in - timings. - - Args: - title: Title for these timings. - timings: A list of floats representing times. - """ - self._printer.print_timing(title) - timings.sort() - - num_tests = len(timings) - if not num_tests: - return - percentile90 = timings[int(.9 * num_tests)] - percentile99 = timings[int(.99 * num_tests)] - - if num_tests % 2 == 1: - median = timings[((num_tests - 1) / 2) - 1] - else: - lower = timings[num_tests / 2 - 1] - upper = timings[num_tests / 2] - median = (float(lower + upper)) / 2 - - mean = sum(timings) / num_tests - - for timing in timings: - sum_of_deviations = math.pow(timing - mean, 2) - - std_deviation = math.sqrt(sum_of_deviations / num_tests) - self._printer.print_timing(" Median: %6.3f" % median) - self._printer.print_timing(" Mean: %6.3f" % mean) - self._printer.print_timing(" 90th percentile: %6.3f" % percentile90) - self._printer.print_timing(" 99th percentile: %6.3f" % percentile99) - self._printer.print_timing(" Standard dev: %6.3f" % std_deviation) - self._printer.print_timing("") - - def _print_result_summary(self, result_summary): - """Print a short summary about how many tests passed. - - Args: - result_summary: information to log - """ - failed = result_summary.total_failures - total = result_summary.total - result_summary.expected_skips - passed = total - failed - pct_passed = 0.0 - if total > 0: - pct_passed = float(passed) * 100 / total - - self._printer.print_actual("") - self._printer.print_actual("=> Results: %d/%d tests passed (%.1f%%)" % - (passed, total, pct_passed)) - self._printer.print_actual("") - self._print_result_summary_entry(result_summary, - test_expectations.NOW, "Tests to be fixed") - - self._printer.print_actual("") - self._print_result_summary_entry(result_summary, - test_expectations.WONTFIX, - "Tests that will only be fixed if they crash (WONTFIX)") - self._printer.print_actual("") - - def _print_result_summary_entry(self, result_summary, timeline, - heading): - """Print a summary block of results for a particular timeline of test. - - Args: - result_summary: summary to print results for - timeline: the timeline to print results for (NOT, WONTFIX, etc.) - heading: a textual description of the timeline - """ - total = len(result_summary.tests_by_timeline[timeline]) - not_passing = (total - - len(result_summary.tests_by_expectation[test_expectations.PASS] & - result_summary.tests_by_timeline[timeline])) - self._printer.print_actual("=> %s (%d):" % (heading, not_passing)) - - for result in TestExpectations.EXPECTATION_ORDER: - if result == test_expectations.PASS: - continue - results = (result_summary.tests_by_expectation[result] & - result_summary.tests_by_timeline[timeline]) - desc = TestExpectations.EXPECTATION_DESCRIPTIONS[result] - if not_passing and len(results): - pct = len(results) * 100.0 / not_passing - self._printer.print_actual(" %5d %-24s (%4.1f%%)" % - (len(results), desc[len(results) != 1], pct)) - def _copy_results_html_file(self): base_dir = self._port.path_from_webkit_base('LayoutTests', 'fast', 'harness') results_file = self._filesystem.join(base_dir, 'results.html') diff --git a/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py b/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py index 27f06a70e..ae20a8a50 100644 --- a/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py +++ b/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py @@ -59,9 +59,16 @@ from webkitpy.common.host_mock import MockHost class ManagerWrapper(Manager): + def __init__(self, ref_tests, **kwargs): + Manager.__init__(self, **kwargs) + self._ref_tests = ref_tests + def _get_test_input_for_file(self, test_file): return test_file + def _is_ref_test(self, test_input): + return test_input in self._ref_tests + class ShardingTests(unittest.TestCase): test_list = [ @@ -77,14 +84,21 @@ class ShardingTests(unittest.TestCase): "perf/object-keys.html", ] - def get_shards(self, num_workers, fully_parallel, test_list=None, max_locked_shards=None): + ref_tests = [ + "http/tests/security/view-source-no-refresh.html", + "http/tests/websocket/tests/websocket-protocol-ignored.html", + "ietestcenter/Javascript/11.1.5_4-4-c-1.html", + "dom/html/level2/html/HTMLAnchorElement06.html", + ] + + def get_shards(self, num_workers, fully_parallel, shard_ref_tests=False, test_list=None, max_locked_shards=None): test_list = test_list or self.test_list host = MockHost() port = host.port_factory.get(port_name='test') port._filesystem = MockFileSystem() options = MockOptions(max_locked_shards=max_locked_shards) - self.manager = ManagerWrapper(port=port, options=options, printer=Mock()) - return self.manager._shard_tests(test_list, num_workers, fully_parallel) + self.manager = ManagerWrapper(self.ref_tests, port=port, options=options, printer=Mock()) + return self.manager._shard_tests(test_list, num_workers, fully_parallel, shard_ref_tests) def test_shard_by_dir(self): locked, unlocked = self.get_shards(num_workers=2, fully_parallel=False) @@ -110,6 +124,31 @@ class ShardingTests(unittest.TestCase): TestShard('ietestcenter/Javascript', ['ietestcenter/Javascript/11.1.5_4-4-c-1.html'])]) + def test_shard_by_dir_sharding_ref_tests(self): + locked, unlocked = self.get_shards(num_workers=2, fully_parallel=False, shard_ref_tests=True) + + # Note that although there are tests in multiple dirs that need locks, + # they are crammed into a single shard in order to reduce the # of + # workers hitting the server at once. + self.assertEquals(locked, + [TestShard('locked_shard_1', + ['http/tests/websocket/tests/unicode.htm', + 'http/tests/xmlhttprequest/supported-xml-content-types.html', + 'perf/object-keys.html', + 'http/tests/security/view-source-no-refresh.html', + 'http/tests/websocket/tests/websocket-protocol-ignored.html'])]) + self.assertEquals(unlocked, + [TestShard('animations', + ['animations/keyframes.html']), + TestShard('dom/html/level2/html', + ['dom/html/level2/html/HTMLAnchorElement03.html']), + TestShard('fast/css', + ['fast/css/display-none-inline-style-change-crash.html']), + TestShard('~ref:dom/html/level2/html', + ['dom/html/level2/html/HTMLAnchorElement06.html']), + TestShard('~ref:ietestcenter/Javascript', + ['ietestcenter/Javascript/11.1.5_4-4-c-1.html'])]) + def test_shard_every_file(self): locked, unlocked = self.get_shards(num_workers=2, fully_parallel=True) self.assertEquals(locked, @@ -142,6 +181,23 @@ class ShardingTests(unittest.TestCase): 'ietestcenter/Javascript/11.1.5_4-4-c-1.html', 'dom/html/level2/html/HTMLAnchorElement06.html'])]) + def test_shard_in_two_sharding_ref_tests(self): + locked, unlocked = self.get_shards(num_workers=1, fully_parallel=False, shard_ref_tests=True) + self.assertEquals(locked, + [TestShard('locked_tests', + ['http/tests/websocket/tests/unicode.htm', + 'http/tests/xmlhttprequest/supported-xml-content-types.html', + 'perf/object-keys.html', + 'http/tests/security/view-source-no-refresh.html', + 'http/tests/websocket/tests/websocket-protocol-ignored.html'])]) + self.assertEquals(unlocked, + [TestShard('unlocked_tests', + ['animations/keyframes.html', + 'fast/css/display-none-inline-style-change-crash.html', + 'dom/html/level2/html/HTMLAnchorElement03.html', + 'ietestcenter/Javascript/11.1.5_4-4-c-1.html', + 'dom/html/level2/html/HTMLAnchorElement06.html'])]) + def test_shard_in_two_has_no_locked_shards(self): locked, unlocked = self.get_shards(num_workers=1, fully_parallel=False, test_list=['animations/keyframe.html']) @@ -200,25 +256,6 @@ class ManagerTest(unittest.TestCase): def get_options(self): return MockOptions(pixel_tests=False, new_baseline=False, time_out_ms=6000, slow_time_out_ms=30000, worker_model='inline') - def get_printer(self): - class FakePrinter(object): - def __init__(self): - self.output = [] - - def print_config(self, msg): - self.output.append(msg) - - return FakePrinter() - - def test_fallback_path_in_config(self): - options = self.get_options() - host = MockHost() - port = host.port_factory.get('test-mac-leopard', options=options) - printer = self.get_printer() - manager = Manager(port, options, printer) - manager.print_config() - self.assertTrue('Baseline search path: test-mac-leopard -> test-mac-snowleopard -> generic' in printer.output) - def test_http_locking(tester): options, args = run_webkit_tests.parse_args(['--platform=test', '--print=nothing', 'http/tests/passes', 'passes']) host = MockHost() @@ -253,6 +290,8 @@ class ManagerTest(unittest.TestCase): manager._options = MockOptions(exit_after_n_failures=None, exit_after_n_crashes_or_timeouts=None) manager._test_files = ['foo/bar.html', 'baz.html'] + manager._test_is_slow = lambda test_name: False + result_summary = ResultSummary(expectations=Mock(), test_files=manager._test_files) result_summary.unexpected_failures = 100 result_summary.unexpected_crashes = 50 @@ -486,29 +525,30 @@ class ResultSummaryTest(unittest.TestCase): if extra_expectations: expectations += extra_expectations + test_is_slow = False paths, rs, exp = self.get_result_summary(port, tests, expectations) if expected: - rs.add(self.get_result('passes/text.html', test_expectations.PASS), expected) - rs.add(self.get_result('failures/expected/timeout.html', test_expectations.TIMEOUT), expected) - rs.add(self.get_result('failures/expected/crash.html', test_expectations.CRASH), expected) + rs.add(self.get_result('passes/text.html', test_expectations.PASS), expected, test_is_slow) + rs.add(self.get_result('failures/expected/timeout.html', test_expectations.TIMEOUT), expected, test_is_slow) + rs.add(self.get_result('failures/expected/crash.html', test_expectations.CRASH), expected, test_is_slow) elif passing: - rs.add(self.get_result('passes/text.html'), expected) - rs.add(self.get_result('failures/expected/timeout.html'), expected) - rs.add(self.get_result('failures/expected/crash.html'), expected) + rs.add(self.get_result('passes/text.html'), expected, test_is_slow) + rs.add(self.get_result('failures/expected/timeout.html'), expected, test_is_slow) + rs.add(self.get_result('failures/expected/crash.html'), expected, test_is_slow) else: - rs.add(self.get_result('passes/text.html', test_expectations.TIMEOUT), expected) - rs.add(self.get_result('failures/expected/timeout.html', test_expectations.CRASH), expected) - rs.add(self.get_result('failures/expected/crash.html', test_expectations.TIMEOUT), expected) + rs.add(self.get_result('passes/text.html', test_expectations.TIMEOUT), expected, test_is_slow) + rs.add(self.get_result('failures/expected/timeout.html', test_expectations.CRASH), expected, test_is_slow) + rs.add(self.get_result('failures/expected/crash.html', test_expectations.TIMEOUT), expected, test_is_slow) for test in extra_tests: - rs.add(self.get_result(test, test_expectations.CRASH), expected) + rs.add(self.get_result(test, test_expectations.CRASH), expected, test_is_slow) retry = rs if flaky: paths, retry, exp = self.get_result_summary(port, tests, expectations) - retry.add(self.get_result('passes/text.html'), True) - retry.add(self.get_result('failures/expected/timeout.html'), True) - retry.add(self.get_result('failures/expected/crash.html'), True) + retry.add(self.get_result('passes/text.html'), True, test_is_slow) + retry.add(self.get_result('failures/expected/timeout.html'), True, test_is_slow) + retry.add(self.get_result('failures/expected/crash.html'), True, test_is_slow) unexpected_results = manager.summarize_results(port, exp, rs, retry, test_timings={}, only_unexpected=True, interrupted=False) expected_results = manager.summarize_results(port, exp, rs, retry, test_timings={}, only_unexpected=False, interrupted=False) return expected_results, unexpected_results diff --git a/Tools/Scripts/webkitpy/layout_tests/controllers/worker.py b/Tools/Scripts/webkitpy/layout_tests/controllers/worker.py index 837aea86b..378826c51 100644 --- a/Tools/Scripts/webkitpy/layout_tests/controllers/worker.py +++ b/Tools/Scripts/webkitpy/layout_tests/controllers/worker.py @@ -83,7 +83,9 @@ class Worker(object): self._caller.post('finished_test_list', test_list_name, len(test_inputs), elapsed_time) def _update_test_input(self, test_input): - test_input.reference_files = self._port.reference_files(test_input.test_name) + if test_input.reference_files is None: + # Lazy initialization. + test_input.reference_files = self._port.reference_files(test_input.test_name) if test_input.reference_files: test_input.should_run_pixel_test = True elif self._options.pixel_tests: diff --git a/Tools/Scripts/webkitpy/layout_tests/models/result_summary.py b/Tools/Scripts/webkitpy/layout_tests/models/result_summary.py index d46703e8f..b0512127f 100644 --- a/Tools/Scripts/webkitpy/layout_tests/models/result_summary.py +++ b/Tools/Scripts/webkitpy/layout_tests/models/result_summary.py @@ -55,8 +55,9 @@ class ResultSummary(object): self.total_tests_by_expectation[expectation] = 0 for timeline in TestExpectations.TIMELINES.values(): self.tests_by_timeline[timeline] = expectations.get_tests_with_timeline(timeline) + self.slow_tests = set() - def add(self, test_result, expected): + def add(self, test_result, expected, test_is_slow): self.total_tests_by_expectation[test_result.type] += 1 self.tests_by_expectation[test_result.type].add(test_result.test_name) self.results[test_result.test_name] = test_result @@ -77,3 +78,5 @@ class ResultSummary(object): self.unexpected_crashes += 1 elif test_result.type == TIMEOUT: self.unexpected_timeouts += 1 + if test_is_slow: + self.slow_tests.add(test_result.test_name) diff --git a/Tools/Scripts/webkitpy/layout_tests/port/base.py b/Tools/Scripts/webkitpy/layout_tests/port/base.py index fbf0b930b..dda129f2f 100755 --- a/Tools/Scripts/webkitpy/layout_tests/port/base.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/base.py @@ -1019,6 +1019,15 @@ class Port(object): def default_configuration(self): return self._config.default_configuration() + def process_kill_time(self): + """ Returns the amount of time in seconds to wait before killing the process. + + Within server_process.stop there is a time delta before the test is explictly + killed. By changing this the time can be extended in case the process needs + more time to cleanly exit on its own. + """ + return 3.0 + # # PROTECTED ROUTINES # diff --git a/Tools/Scripts/webkitpy/layout_tests/port/chromium.py b/Tools/Scripts/webkitpy/layout_tests/port/chromium.py index 24f7efa0f..45298c634 100755 --- a/Tools/Scripts/webkitpy/layout_tests/port/chromium.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/chromium.py @@ -272,9 +272,6 @@ class ChromiumPort(WebKitPort): except AssertionError: return self._build_path(self.get_option('configuration'), 'layout-test-results') - def _driver_class(self): - return ChromiumDriver - def _missing_symbol_to_skipped_tests(self): # FIXME: Should WebKitPort have these definitions also? return { @@ -436,283 +433,3 @@ class ChromiumPort(WebKitPort): if sys.platform == 'cygwin': return cygpath(path) return path - - -class ChromiumDriver(WebKitDriver): - KILL_TIMEOUT_DEFAULT = 3.0 - - def __init__(self, port, worker_number, pixel_tests, no_timeout=False): - WebKitDriver.__init__(self, port, worker_number, pixel_tests, no_timeout) - self._proc = None - self._image_path = None - - # FIXME: Delete all of this driver code once we're satisfied that it's not needed any more. - #if port.host.platform.os_version == 'snowleopard': - # if not hasattr(port._options, 'additional_drt_flag'): - # port._options.additional_drt_flag = [] - # if not '--test-shell' in port._options.additional_drt_flag: - # port._options.additional_drt_flag.append('--test-shell') - - self._test_shell = '--test-shell' in port.get_option('additional_drt_flag', []) - - def _wrapper_options(self, pixel_tests): - cmd = [] - if pixel_tests: - if self._test_shell: - if not self._image_path: - self._image_path = self._port._filesystem.join(self._port.results_directory(), 'png_result%s.png' % self._worker_number) - # See note above in diff_image() for why we need _convert_path(). - cmd.append("--pixel-tests=" + self._port._convert_path(self._image_path)) - else: - cmd.append('--pixel-tests') - - # FIXME: This is not None shouldn't be necessary, unless --js-flags="''" changes behavior somehow? - if self._port.get_option('js_flags') is not None: - cmd.append('--js-flags="' + self._port.get_option('js_flags') + '"') - if self._no_timeout: - cmd.append("--no-timeout") - - # FIXME: We should be able to build this list using only an array of - # option names, the options (optparse.Values) object, and the orignal - # list of options from the main method by looking up the option - # text from the options list if the value is non-None. - # FIXME: How many of these options are still used? - option_mappings = { - 'startup_dialog': '--testshell-startup-dialog', - 'gp_fault_error_box': '--gp-fault-error-box', - 'stress_opt': '--stress-opt', - 'stress_deopt': '--stress-deopt', - 'threaded_compositing': '--enable-threaded-compositing', - 'accelerated_2d_canvas': '--enable-accelerated-2d-canvas', - 'accelerated_painting': '--enable-accelerated-painting', - 'accelerated_video': '--enable-accelerated-video', - 'enable_hardware_gpu': '--enable-hardware-gpu', - 'per_tile_painting': '--enable-per-tile-painting', - } - for nrwt_option, drt_option in option_mappings.items(): - if self._port.get_option(nrwt_option): - cmd.append(drt_option) - - cmd.extend(self._port.get_option('additional_drt_flag', [])) - return cmd - - def cmd_line(self, pixel_tests, per_test_args): - cmd = self._command_wrapper(self._port.get_option('wrapper')) - cmd.append(self._port._path_to_driver()) - cmd.extend(self._wrapper_options(pixel_tests)) - cmd.extend(per_test_args) - - if not self._test_shell: - cmd.append('-') - - return cmd - - def _start(self, pixel_tests, per_test_args): - if not self._test_shell: - return super(ChromiumDriver, self)._start(pixel_tests, per_test_args) - - assert not self._proc - # FIXME: This should use ServerProcess like WebKitDriver does. - # FIXME: We should be reading stderr and stdout separately like how WebKitDriver does. - close_fds = sys.platform != 'win32' - self._proc = subprocess.Popen(self.cmd_line(pixel_tests, per_test_args), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=close_fds) - - def has_crashed(self): - if not self._test_shell: - return super(ChromiumDriver, self).has_crashed() - - if self._proc is None: - return False - return self._proc.poll() is not None - - def _write_command_and_read_line(self, input=None): - """Returns a tuple: (line, did_crash)""" - try: - if input: - if isinstance(input, unicode): - # DRT expects utf-8 - input = input.encode("utf-8") - self._proc.stdin.write(input) - # DumpRenderTree text output is always UTF-8. However some tests - # (e.g. webarchive) may spit out binary data instead of text so we - # don't bother to decode the output. - line = self._proc.stdout.readline() - # We could assert() here that line correctly decodes as UTF-8. - return (line, False) - except IOError, e: - _log.error("IOError communicating w/ DRT: " + str(e)) - return (None, True) - - def _test_shell_command(self, uri, timeoutms, checksum): - cmd = uri - if timeoutms: - cmd += ' ' + str(timeoutms) - if checksum: - cmd += ' ' + checksum - cmd += "\n" - return cmd - - def _output_image(self): - if self._image_path and self._port._filesystem.exists(self._image_path): - return self._port._filesystem.read_binary_file(self._image_path) - return None - - def _output_image_with_retry(self): - # Retry a few more times because open() sometimes fails on Windows, - # raising "IOError: [Errno 13] Permission denied:" - retry_num = 50 - timeout_seconds = 5.0 - for _ in range(retry_num): - try: - return self._output_image() - except IOError, e: - if e.errno != errno.EACCES: - raise e - # FIXME: We should have a separate retry delay. - # This implementation is likely to exceed the timeout before the expected number of retries. - time.sleep(timeout_seconds / retry_num) - return self._output_image() - - def _clear_output_image(self): - if self._image_path and self._port._filesystem.exists(self._image_path): - self._port._filesystem.remove(self._image_path) - - def run_test(self, driver_input): - if not self._test_shell: - return super(ChromiumDriver, self).run_test(driver_input) - - if not self._proc: - self._start(driver_input.should_run_pixel_test, driver_input.args) - - output = [] - error = [] - crash = False - timeout = False - actual_uri = None - actual_checksum = None - self._clear_output_image() - start_time = time.time() - has_audio = False - has_base64 = False - - uri = self.test_to_uri(driver_input.test_name) - cmd = self._test_shell_command(uri, driver_input.timeout, driver_input.image_hash) - line, crash = self._write_command_and_read_line(input=cmd) - - while not crash and line.rstrip() != "#EOF": - # Make sure we haven't crashed. - if line == '' and self._proc.poll() is not None: - # This is hex code 0xc000001d, which is used for abrupt - # termination. This happens if we hit ctrl+c from the prompt - # and we happen to be waiting on DRT. - # sdoyon: Not sure for which OS and in what circumstances the - # above code is valid. What works for me under Linux to detect - # ctrl+c is for the subprocess returncode to be negative - # SIGINT. And that agrees with the subprocess documentation. - if (-1073741510 == self._proc.returncode or - - signal.SIGINT == self._proc.returncode): - raise KeyboardInterrupt - crash = True - break - - # Don't include #URL lines in our output - if line.startswith("#URL:"): - actual_uri = line.rstrip()[5:] - if uri != actual_uri: - # GURL capitalizes the drive letter of a file URL. - if (not re.search("^file:///[a-z]:", uri) or uri.lower() != actual_uri.lower()): - _log.fatal("Test got out of sync:\n|%s|\n|%s|" % (uri, actual_uri)) - raise AssertionError("test out of sync") - elif line.startswith("#MD5:"): - actual_checksum = line.rstrip()[5:] - elif line.startswith("#TEST_TIMED_OUT"): - timeout = True - # Test timed out, but we still need to read until #EOF. - elif line.startswith("Content-Type: audio/wav"): - has_audio = True - elif line.startswith("Content-Transfer-Encoding: base64"): - has_base64 = True - elif line.startswith("Content-Length:"): - pass - elif actual_uri: - output.append(line) - else: - error.append(line) - - line, crash = self._write_command_and_read_line(input=None) - - if crash and line is not None: - error.append(line) - run_time = time.time() - start_time - output_image = self._output_image_with_retry() - - audio_bytes = None - text = None - if has_audio: - if has_base64: - audio_bytes = base64.b64decode(''.join(output)) - else: - audio_bytes = ''.join(output).rstrip() - else: - text = ''.join(output) - if not text: - text = None - - error = ''.join(error) - # Currently the stacktrace is in the text output, not error, so append the two together so - # that we can see stack in the output. See http://webkit.org/b/66806 - # FIXME: We really should properly handle the stderr output separately. - crash_log = '' - crashed_process_name = None - crashed_pid = None - if crash: - crashed_process_name = self._port.driver_name() - if self._proc: - crashed_pid = self._proc.pid - crash_log = self._port._get_crash_log(crashed_process_name, crashed_pid, text, error, newer_than=start_time) - if text: - error = error + text - - return DriverOutput(text, output_image, actual_checksum, audio=audio_bytes, - crash=crash, crashed_process_name=crashed_process_name, crashed_pid=crashed_pid, crash_log=crash_log, - test_time=run_time, timeout=timeout, error=error) - - def start(self, pixel_tests, per_test_args): - if not self._test_shell: - return super(ChromiumDriver, self).start(pixel_tests, per_test_args) - - if not self._proc: - self._start(pixel_tests, per_test_args) - - def stop(self): - if not self._test_shell: - return super(ChromiumDriver, self).stop() - - if not self._proc: - return - self._proc.stdin.close() - self._proc.stdout.close() - if self._proc.stderr: - self._proc.stderr.close() - time_out_ms = self._port.get_option('time_out_ms') - if time_out_ms and not self._no_timeout: - timeout_ratio = float(time_out_ms) / self._port.default_timeout_ms() - kill_timeout_seconds = self.KILL_TIMEOUT_DEFAULT * timeout_ratio if timeout_ratio > 1.0 else self.KILL_TIMEOUT_DEFAULT - else: - kill_timeout_seconds = self.KILL_TIMEOUT_DEFAULT - - # Closing stdin/stdout/stderr hangs sometimes on OS X, - # (see __init__(), above), and anyway we don't want to hang - # the harness if DRT is buggy, so we wait a couple - # seconds to give DRT a chance to clean up, but then - # force-kill the process if necessary. - timeout = time.time() + kill_timeout_seconds - while self._proc.poll() is None and time.time() < timeout: - time.sleep(0.1) - if self._proc.poll() is None: - _log.warning('stopping test driver timed out, killing it') - self._port._executive.kill_process(self._proc.pid) - # FIXME: This is sometime None. What is wrong? assert self._proc.poll() is not None - if self._proc.poll() is not None: - self._proc.wait() - self._proc = None diff --git a/Tools/Scripts/webkitpy/layout_tests/port/chromium_android.py b/Tools/Scripts/webkitpy/layout_tests/port/chromium_android.py index 2240657c1..126b31868 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/chromium_android.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/chromium_android.py @@ -29,15 +29,14 @@ import logging import os -import re -import signal import shlex -import shutil import threading import time from webkitpy.layout_tests.port import chromium from webkitpy.layout_tests.port import factory +from webkitpy.layout_tests.port import server_process +from webkitpy.layout_tests.port import webkit _log = logging.getLogger(__name__) @@ -123,8 +122,7 @@ DEVICE_FONTS_DIR = DEVICE_DRT_DIR + 'fonts/' # 1. as a virtual path in file urls that will be bridged to HTTP. # 2. pointing to some files that are pushed to the device for tests that # don't work on file-over-http (e.g. blob protocol tests). -DEVICE_LAYOUT_TESTS_DIR = (DEVICE_SOURCE_ROOT_DIR + 'third_party/WebKit/LayoutTests/') -FILE_TEST_URI_PREFIX = 'file://' + DEVICE_LAYOUT_TESTS_DIR +DEVICE_LAYOUT_TESTS_DIR = DEVICE_SOURCE_ROOT_DIR + 'third_party/WebKit/LayoutTests/' # Test resources that need to be accessed as files directly. # Each item can be the relative path of a directory or a file. @@ -155,22 +153,22 @@ class ChromiumAndroidPort(chromium.ChromiumPort): ] def __init__(self, host, port_name, **kwargs): - chromium.ChromiumPort.__init__(self, host, port_name, **kwargs) + super(ChromiumAndroidPort, self).__init__(host, port_name, **kwargs) - # FIXME: Stop using test_shell mode: https://bugs.webkit.org/show_bug.cgi?id=88542 if not hasattr(self._options, 'additional_drt_flag'): self._options.additional_drt_flag = [] - if not '--test-shell' in self._options.additional_drt_flag: - self._options.additional_drt_flag.append('--test-shell') + self._options.additional_drt_flag.append('--encode-binary') # The Chromium port for Android always uses the hardware GPU path. self._options.enable_hardware_gpu = True + # Shard ref tests so that they run together to avoid repeatedly driver restarts. + self._options.shard_ref_tests = True + self._operating_system = 'android' self._version = 'icecreamsandwich' self._original_governor = None self._android_base_dir = None - self._read_fifo_proc = None self._host_port = factory.PortFactory(host).get('chromium', **kwargs) @@ -197,7 +195,7 @@ class ChromiumAndroidPort(chromium.ChromiumPort): return self._host_port.check_wdiff(logging) def check_build(self, needs_http): - result = chromium.ChromiumPort.check_build(self, needs_http) + result = super(ChromiumAndroidPort, self).check_build(needs_http) result = self.check_wdiff() and result if not result: _log.error('For complete Android build requirements, please see:') @@ -226,7 +224,7 @@ class ChromiumAndroidPort(chromium.ChromiumPort): # FIXME: This is a temporary measure to reduce the manual work when # updating WebKit. This method should be removed when we merge # test_expectations_android.txt into TestExpectations. - expectations = chromium.ChromiumPort.test_expectations(self) + expectations = super(ChromiumAndroidPort, self).test_expectations() return expectations.replace('LINUX ', 'LINUX ANDROID ') def start_http_server(self, additional_dirs=None, number_of_servers=0): @@ -256,7 +254,7 @@ class ChromiumAndroidPort(chromium.ChromiumPort): self._run_adb_command(['shell', 'rm', '-r', DRT_APP_CACHE_DIR]) # Start the HTTP server so that the device can access the test cases. - chromium.ChromiumPort.start_http_server(self, additional_dirs={TEST_PATH_PREFIX: self.layout_tests_dir()}) + super(ChromiumAndroidPort, self).start_http_server(additional_dirs={TEST_PATH_PREFIX: self.layout_tests_dir()}) _log.debug('Starting forwarder') self._run_adb_command(['shell', '%s %s' % (DEVICE_FORWARDER_PATH, FORWARD_PORTS)]) @@ -273,6 +271,11 @@ class ChromiumAndroidPort(chromium.ChromiumPort): 'canvas/philip', ]) + def create_driver(self, worker_number, no_timeout=False): + # We don't want the default DriverProxy which is not compatible with our driver. + # See comments in ChromiumAndroidDriver.start(). + return ChromiumAndroidDriver(self, worker_number, pixel_tests=self.get_option('pixel_tests'), no_timeout=no_timeout) + # Overridden private functions. def _build_path(self, *comps): @@ -323,7 +326,7 @@ class ChromiumAndroidPort(chromium.ChromiumPort): if not stderr: stderr = '' stderr += '********* Tombstone file:\n' + self._get_last_stacktrace() - return chromium.ChromiumPort._get_crash_log(self, name, pid, stdout, stderr, newer_than) + return super(ChromiumAndroidPort, self)._get_crash_log(name, pid, stdout, stderr, newer_than) # Local private functions. @@ -453,62 +456,57 @@ class ChromiumAndroidPort(chromium.ChromiumPort): self._original_governor = None -class ChromiumAndroidDriver(chromium.ChromiumDriver): - # The controller may start multiple drivers during test, but for now we - # don't support multiple Android activities, so only one driver can be - # started at a time. - _started_driver = None - +class ChromiumAndroidDriver(webkit.WebKitDriver): def __init__(self, port, worker_number, pixel_tests, no_timeout=False): - chromium.ChromiumDriver.__init__(self, port, worker_number, pixel_tests, no_timeout) + webkit.WebKitDriver.__init__(self, port, worker_number, pixel_tests, no_timeout) + self._pixel_tests = pixel_tests self._in_fifo_path = DRT_APP_FILES_DIR + 'DumpRenderTree.in' self._out_fifo_path = DRT_APP_FILES_DIR + 'DumpRenderTree.out' - self._err_file_path = DRT_APP_FILES_DIR + 'DumpRenderTree.err' + self._err_fifo_path = DRT_APP_FILES_DIR + 'DumpRenderTree.err' self._restart_after_killed = False - self._read_fifo_proc = None + self._read_stdout_process = None + self._read_stderr_process = None def _command_wrapper(cls, wrapper_option): # Ignore command wrapper which is not applicable on Android. return [] def cmd_line(self, pixel_tests, per_test_args): - original_cmd = chromium.ChromiumDriver.cmd_line(self, pixel_tests, per_test_args) - cmd = [] - for param in original_cmd: - if param.startswith('--pixel-tests='): - self._device_image_path = DRT_APP_FILES_DIR + self._port.host.filesystem.basename(self._image_path) - param = '--pixel-tests=' + self._device_image_path - cmd.append(param) - - cmd.append('--in-fifo=' + self._in_fifo_path) - cmd.append('--out-fifo=' + self._out_fifo_path) - cmd.append('--err-file=' + self._err_file_path) - return cmd + return self._port._adb_command + ['shell'] def _file_exists_on_device(self, full_file_path): assert full_file_path.startswith('/') return self._port._run_adb_command(['shell', 'ls', full_file_path]).strip() == full_file_path - def _deadlock_detector(self, pids, normal_startup_event): + def _deadlock_detector(self, processes, normal_startup_event): time.sleep(DRT_START_STOP_TIMEOUT_SECS) if not normal_startup_event.is_set(): # If normal_startup_event is not set in time, the main thread must be blocked at # reading/writing the fifo. Kill the fifo reading/writing processes to let the # main thread escape from the deadlocked state. After that, the main thread will # treat this as a crash. - for i in pids: - self._port._executive.kill_process(i) + for i in processes: + i.kill() # Otherwise the main thread has been proceeded normally. This thread just exits silently. - def _start(self, pixel_tests, per_test_args): - if ChromiumAndroidDriver._started_driver: - ChromiumAndroidDriver._started_driver.stop() - - ChromiumAndroidDriver._started_driver = self + def _drt_cmd_line(self, pixel_tests, per_test_args): + return webkit.WebKitDriver.cmd_line(self, pixel_tests, per_test_args) + [ + '--in-fifo=' + self._in_fifo_path, + '--out-fifo=' + self._out_fifo_path, + '--err-fifo=' + self._err_fifo_path, + ] + + def start(self, pixel_tests, per_test_args): + # Only one driver instance is allowed because of the nature of Android activity. + # The single driver needs to switch between pixel test and no pixel test mode by itself. + if pixel_tests != self._pixel_tests: + self.stop() + super(ChromiumAndroidDriver, self).start(pixel_tests, per_test_args) + def _start(self, pixel_tests, per_test_args): retries = 0 while not self._start_once(pixel_tests, per_test_args): - _log.error('Failed to start DumpRenderTree application. Log:\n' + self._port._get_logcat()) + _log.error('Failed to start DumpRenderTree application. Retries=%d. Log:%s' % (retries, self._port._get_logcat())) retries += 1 if retries >= 3: raise AssertionError('Failed to start DumpRenderTree application multiple times. Give up.') @@ -516,8 +514,10 @@ class ChromiumAndroidDriver(chromium.ChromiumDriver): time.sleep(2) def _start_once(self, pixel_tests, per_test_args): + super(ChromiumAndroidDriver, self)._start(pixel_tests, per_test_args) + self._port._run_adb_command(['logcat', '-c']) - self._port._run_adb_command(['shell', 'echo'] + self.cmd_line(pixel_tests, per_test_args) + ['>', COMMAND_LINE_FILE]) + self._port._run_adb_command(['shell', 'echo'] + self._drt_cmd_line(pixel_tests, per_test_args) + ['>', COMMAND_LINE_FILE]) start_result = self._port._run_adb_command(['shell', 'am', 'start', '-e', 'RunInSubThread', '-n', DRT_ACTIVITY_FULL_NAME]) if start_result.find('Exception') != -1: _log.error('Failed to start DumpRenderTree application. Exception:\n' + start_result) @@ -526,57 +526,59 @@ class ChromiumAndroidDriver(chromium.ChromiumDriver): seconds = 0 while (not self._file_exists_on_device(self._in_fifo_path) or not self._file_exists_on_device(self._out_fifo_path) or - not self._file_exists_on_device(self._err_file_path)): + not self._file_exists_on_device(self._err_fifo_path)): time.sleep(1) seconds += 1 if seconds >= DRT_START_STOP_TIMEOUT_SECS: return False - shell_cmd = self._port._adb_command + ['shell'] - executive = self._port._executive - # Start a process to send command through the input fifo of the DumpRenderTree app. - # This process must be run as an interactive adb shell because the normal adb shell doesn't support stdin. - self._proc = executive.popen(shell_cmd, stdin=executive.PIPE, stdout=executive.PIPE, universal_newlines=True) # Read back the shell prompt to ensure adb shell ready. - self._read_prompt() + deadline = time.time() + DRT_START_STOP_TIMEOUT_SECS + self._server_process.start() + self._read_prompt(deadline) _log.debug('Interactive shell started') - # Start a process to read from the output fifo of the DumpRenderTree app and print to stdout. + # Start a process to read from the stdout fifo of the DumpRenderTree app and print to stdout. _log.debug('Redirecting stdout to ' + self._out_fifo_path) - self._read_fifo_proc = executive.popen(shell_cmd + ['cat', self._out_fifo_path], - stdout=executive.PIPE, universal_newlines=True) + self._read_stdout_process = server_process.ServerProcess( + self._port, 'ReadStdout', self._port._adb_command + ['shell', 'cat', self._out_fifo_path], universal_newlines=True) + self._read_stdout_process.start() + + # Start a process to read from the stderr fifo of the DumpRenderTree app and print to stdout. + _log.debug('Redirecting stderr to ' + self._err_fifo_path) + self._read_stderr_process = server_process.ServerProcess( + self._port, 'ReadStderr', self._port._adb_command + ['shell', 'cat', self._err_fifo_path], universal_newlines=True) + self._read_stderr_process.start() _log.debug('Redirecting stdin to ' + self._in_fifo_path) - (line, crash) = self._write_command_and_read_line('cat >%s\n' % self._in_fifo_path) + self._server_process.write('cat >%s\n' % self._in_fifo_path) - # Combine the two unidirectional pipes into one bidirectional pipe to make _write_command_and_read_line() etc - # work with self._proc. - self._proc.stdout.close() - self._proc.stdout = self._read_fifo_proc.stdout + # Combine the stdout and stderr pipes into self._server_process. + self._server_process.replace_outputs(self._read_stdout_process._proc.stdout, self._read_stderr_process._proc.stdout) # Start a thread to kill the pipe reading/writing processes on deadlock of the fifos during startup. normal_startup_event = threading.Event() threading.Thread(target=self._deadlock_detector, - args=([self._proc.pid, self._read_fifo_proc.pid], normal_startup_event)).start() + args=([self._server_process, self._read_stdout_process, self._read_stderr_process], normal_startup_event)).start() output = '' - while not crash and line.rstrip() != '#READY': + line = self._server_process.read_stdout_line(deadline) + while not self._server_process.timed_out and not self.has_crashed() and line.rstrip() != '#READY': output += line - (line, crash) = self._write_command_and_read_line() + line = self._server_process.read_stdout_line(deadline) - if crash: + if self._server_process.timed_out and not self.has_crashed(): # DumpRenderTree crashes during startup, or when the deadlock detector detected # deadlock and killed the fifo reading/writing processes. - _log.error('Failed to start DumpRenderTree: \n%s\nLog:\n%s' % (output, self._port._get_logcat())) - self.stop() - raise AssertionError('Failed to start DumpRenderTree application') + _log.error('Failed to start DumpRenderTree: \n%s' % output) + return False else: # Inform the deadlock detector that the startup is successful without deadlock. normal_startup_event.set() return True def run_test(self, driver_input): - driver_output = chromium.ChromiumDriver.run_test(self, driver_input) + driver_output = super(ChromiumAndroidDriver, self).run_test(driver_input) if driver_output.crash: # When Android is OOM, DRT process may be killed by ActivityManager or system OOM. # It looks like a crash but there is no fatal signal logged. Re-run the test for @@ -595,78 +597,48 @@ class ChromiumAndroidDriver(chromium.ChromiumDriver): return self.run_test(driver_input) self._restart_after_killed = False - driver_output.error += self._get_stderr() return driver_output def stop(self): - if ChromiumAndroidDriver._started_driver != self: - return - ChromiumAndroidDriver._started_driver = None - self._port._run_adb_command(['shell', 'am', 'force-stop', DRT_APP_PACKAGE]) - if self._read_fifo_proc: - self._port._executive.kill_process(self._read_fifo_proc.pid) - self._read_fifo_proc = None - - # Here duplicate some logic in ChromiumDriver.stop() instead of directly calling it, - # because our pipe reading/writing processes won't quit by itself on close of the pipes. - if self._proc: - self._proc.stdin.close() - self._proc.stdout.close() - if self._proc.stderr: - self._proc.stderr.close() - self._port._executive.kill_process(self._proc.pid) - if self._proc.poll() is not None: - self._proc.wait() - self._proc = None + if self._read_stdout_process: + self._read_stdout_process.kill() + self._read_stdout_process = None + + if self._read_stderr_process: + self._read_stderr_process.kill() + self._read_stderr_process = None + + # Stop and kill server_process because our pipe reading/writing processes won't quit + # by itself on close of the pipes. + if self._server_process: + self._server_process.stop(kill_directly=True) + self._server_process = None + super(ChromiumAndroidDriver, self).stop() seconds = 0 while (self._file_exists_on_device(self._in_fifo_path) or self._file_exists_on_device(self._out_fifo_path) or - self._file_exists_on_device(self._err_file_path)): + self._file_exists_on_device(self._err_fifo_path)): time.sleep(1) - self._port._run_adb_command(['shell', 'rm', self._in_fifo_path, self._out_fifo_path, self._err_file_path]) + self._port._run_adb_command(['shell', 'rm', self._in_fifo_path, self._out_fifo_path, self._err_fifo_path]) seconds += 1 if seconds >= DRT_START_STOP_TIMEOUT_SECS: raise AssertionError('Failed to remove fifo files. May be locked.') - def _test_shell_command(self, uri, timeout_ms, checksum): - if uri.startswith('file:///'): - # Convert the host uri to a device uri. See comment of + def _command_from_driver_input(self, driver_input): + command = super(ChromiumAndroidDriver, self)._command_from_driver_input(driver_input) + if command.startswith('/'): + # Convert the host file path to a device file path. See comment of # DEVICE_LAYOUT_TESTS_DIR for details. - # Not overriding Port.filename_to_uri() because we don't want the - # links in the html report point to device paths. - uri = FILE_TEST_URI_PREFIX + self.uri_to_test(uri) - return chromium.ChromiumDriver._test_shell_command(self, uri, timeout_ms, checksum) - - def _write_command_and_read_line(self, input=None): - (line, crash) = chromium.ChromiumDriver._write_command_and_read_line(self, input) - url_marker = '#URL:' - if not crash: - if line.startswith(url_marker) and line.find(FILE_TEST_URI_PREFIX) == len(url_marker): - # Convert the device test uri back to host uri otherwise - # chromium.ChromiumDriver.run_test() will complain. - line = '#URL:file://%s/%s' % (self._port.layout_tests_dir(), line[len(url_marker) + len(FILE_TEST_URI_PREFIX):]) - # chromium.py uses "line == '' and self._proc.poll() is not None" to detect crash, - # but on Android "not line" is enough because self._proc.poll() seems not reliable. - if not line: - crash = True - return (line, crash) - - def _output_image(self): - if self._image_path: - _log.debug('Pulling from device: %s to %s' % (self._device_image_path, self._image_path)) - self._port._pull_from_device(self._device_image_path, self._image_path, ignore_error=True) - return chromium.ChromiumDriver._output_image(self) - - def _get_stderr(self): - return self._port._run_adb_command(['shell', 'cat', self._err_file_path], ignore_error=True) - - def _read_prompt(self): + command = DEVICE_LAYOUT_TESTS_DIR + self._port.relative_test_filename(command) + return command + + def _read_prompt(self, deadline): last_char = '' while True: - current_char = self._proc.stdout.read(1) + current_char = self._server_process.read_stdout(deadline, 1) if current_char == ' ': if last_char == '#': return diff --git a/Tools/Scripts/webkitpy/layout_tests/port/chromium_android_unittest.py b/Tools/Scripts/webkitpy/layout_tests/port/chromium_android_unittest.py index 8544b020c..a3a3aaeb4 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/chromium_android_unittest.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/chromium_android_unittest.py @@ -28,16 +28,17 @@ import optparse import StringIO +import time import unittest from webkitpy.common.system import executive_mock from webkitpy.common.system.executive_mock import MockExecutive2 from webkitpy.common.system.systemhost_mock import MockSystemHost -from webkitpy.thirdparty.mock import Mock from webkitpy.layout_tests.port import chromium_android from webkitpy.layout_tests.port import chromium_port_testcase -from webkitpy.layout_tests.port import Port +from webkitpy.layout_tests.port import driver +from webkitpy.layout_tests.port import webkit_unittest class ChromiumAndroidPortTest(chromium_port_testcase.ChromiumPortTestCase): @@ -124,6 +125,10 @@ class ChromiumAndroidPortTest(chromium_port_testcase.ChromiumPortTestCase): u'STDERR: /data/tombstones/tombstone_03\n' u'STDERR: mock_contents\n')) + def test_driver_cmd_line(self): + # Overriding PortTestCase.test_cmd_line(). Use ChromiumAndroidDriverTest.test_cmd_line() instead. + return + class ChromiumAndroidDriverTest(unittest.TestCase): def setUp(self): @@ -131,34 +136,30 @@ class ChromiumAndroidDriverTest(unittest.TestCase): self.driver = chromium_android.ChromiumAndroidDriver(mock_port, worker_number=0, pixel_tests=True) def test_cmd_line(self): - cmd_line = self.driver.cmd_line(True, ['--a']) + cmd_line = self.driver.cmd_line(True, ['anything']) + self.assertEquals(['adb', 'shell'], cmd_line) + + def test_drt_cmd_line(self): + cmd_line = self.driver._drt_cmd_line(True, ['--a']) self.assertTrue('--a' in cmd_line) self.assertTrue('--in-fifo=' + chromium_android.DRT_APP_FILES_DIR + 'DumpRenderTree.in' in cmd_line) self.assertTrue('--out-fifo=' + chromium_android.DRT_APP_FILES_DIR + 'DumpRenderTree.out' in cmd_line) - self.assertTrue('--err-file=' + chromium_android.DRT_APP_FILES_DIR + 'DumpRenderTree.err' in cmd_line) + self.assertTrue('--err-fifo=' + chromium_android.DRT_APP_FILES_DIR + 'DumpRenderTree.err' in cmd_line) def test_read_prompt(self): - self.driver._proc = Mock() # FIXME: This should use a tighter mock. - self.driver._proc.stdout = StringIO.StringIO("root@android:/ # ") - self.assertEquals(self.driver._read_prompt(), None) - self.driver._proc.stdout = StringIO.StringIO("$ ") - self.assertRaises(AssertionError, self.driver._read_prompt) - - def test_test_shell_command(self): - uri = 'file://%s/test.html' % self.driver._port.layout_tests_dir() - self.assertEquals(uri, 'file:///mock-checkout/LayoutTests/test.html') - expected_command = 'file:///data/local/tmp/third_party/WebKit/LayoutTests/test.html 2 checksum\n' - self.assertEquals(self.driver._test_shell_command(uri, 2, 'checksum'), expected_command) - self.assertEquals(self.driver._test_shell_command('http://test.html', 2, 'checksum'), 'http://test.html 2 checksum\n') - - def test_write_command_and_read_line(self): - self.driver._proc = Mock() # FIXME: This should use a tighter mock. - self.driver._proc.stdout = StringIO.StringIO("#URL:file:///data/local/tmp/third_party/WebKit/LayoutTests/test.html\noutput\n\n") - self.assertEquals(self.driver._write_command_and_read_line(), ('#URL:file:///mock-checkout/LayoutTests/test.html\n', False)) - self.assertEquals(self.driver._write_command_and_read_line(), ('output\n', False)) - self.assertEquals(self.driver._write_command_and_read_line(), ('\n', False)) - # Unexpected EOF is treated as crash. - self.assertEquals(self.driver._write_command_and_read_line(), ('', True)) + self.driver._server_process = webkit_unittest.MockServerProcess(['root@android:/ # ']) + self.assertEquals(self.driver._read_prompt(time.time() + 1), None) + self.driver._server_process = webkit_unittest.MockServerProcess(['$ ']) + self.assertRaises(AssertionError, self.driver._read_prompt, time.time() + 1) + + def test_command_from_driver_input(self): + driver_input = driver.DriverInput('foo/bar/test.html', 10, 'checksum', True) + expected_command = "/data/local/tmp/third_party/WebKit/LayoutTests/foo/bar/test.html'checksum\n" + self.assertEquals(self.driver._command_from_driver_input(driver_input), expected_command) + + driver_input = driver.DriverInput('http/tests/foo/bar/test.html', 10, 'checksum', True) + expected_command = "http://127.0.0.1:8000/foo/bar/test.html'checksum\n" + self.assertEquals(self.driver._command_from_driver_input(driver_input), expected_command) if __name__ == '__main__': diff --git a/Tools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py b/Tools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py index 0c49112ba..87de41c6c 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py @@ -44,141 +44,6 @@ from webkitpy.layout_tests.port import chromium_port_testcase from webkitpy.layout_tests.port.driver import DriverInput -class ChromiumDriverTest(unittest.TestCase): - def setUp(self): - host = MockSystemHost() - options = MockOptions(configuration='Release', additional_drt_flag=['--test-shell']) - config = MockConfig(filesystem=host.filesystem, default_configuration='Release') - self.port = chromium_mac.ChromiumMacPort(host, 'chromium-mac-snowleopard', options=options, config=config) - self.driver = chromium.ChromiumDriver(self.port, worker_number=0, pixel_tests=True) - - def test_test_shell_command(self): - expected_command = "test.html 2 checksum\n" - self.assertEqual(self.driver._test_shell_command("test.html", 2, "checksum"), expected_command) - - def _assert_write_command_and_read_line(self, input=None, expected_line=None, expected_stdin=None, expected_crash=False): - if not expected_stdin: - if input: - expected_stdin = input - else: - # We reset stdin, so we should expect stdin.getValue = "" - expected_stdin = "" - self.driver._proc.stdin = StringIO.StringIO() - line, did_crash = self.driver._write_command_and_read_line(input) - self.assertEqual(self.driver._proc.stdin.getvalue(), expected_stdin) - self.assertEqual(line, expected_line) - self.assertEqual(did_crash, expected_crash) - - def test_write_command_and_read_line(self): - self.driver._proc = Mock() # FIXME: This should use a tighter mock. - # Set up to read 3 lines before we get an IOError - self.driver._proc.stdout = StringIO.StringIO("first\nsecond\nthird\n") - - unicode_input = u"I \u2661 Unicode" - utf8_input = unicode_input.encode("utf-8") - # Test unicode input conversion to utf-8 - self._assert_write_command_and_read_line(input=unicode_input, expected_stdin=utf8_input, expected_line="first\n") - # Test str() input. - self._assert_write_command_and_read_line(input="foo", expected_line="second\n") - # Test input=None - self._assert_write_command_and_read_line(expected_line="third\n") - # Test reading from a closed/empty stream. - # reading from a StringIO does not raise IOError like a real file would, so raise IOError manually. - def mock_readline(): - raise IOError - self.driver._proc.stdout.readline = mock_readline - self._assert_write_command_and_read_line(expected_crash=True) - - def test_crash_log(self): - self.driver._proc = Mock() - - # Simulate a crash by having stdout close unexpectedly. - def mock_readline(): - raise IOError - self.driver._proc.stdout.readline = mock_readline - self.driver._proc.pid = 1234 - - self.driver.test_to_uri = lambda test: 'mocktesturi' - self.driver._port.driver_name = lambda: 'mockdriver' - self.driver._port._get_crash_log = lambda name, pid, out, err, newer_than: 'mockcrashlog' - driver_output = self.driver.run_test(DriverInput(test_name='some/test.html', timeout=1, image_hash=None, should_run_pixel_test=False)) - self.assertTrue(driver_output.crash) - self.assertEqual(driver_output.crashed_process_name, 'mockdriver') - self.assertEqual(driver_output.crashed_pid, 1234) - self.assertEqual(driver_output.crash_log, 'mockcrashlog') - - def test_stop(self): - self.pid = None - self.wait_called = False - self.driver._proc = Mock() # FIXME: This should use a tighter mock. - self.driver._proc.pid = 1 - self.driver._proc.stdin = StringIO.StringIO() - self.driver._proc.stdout = StringIO.StringIO() - self.driver._proc.stderr = StringIO.StringIO() - self.driver._proc.poll = lambda: None - - def fake_wait(): - self.assertTrue(self.pid is not None) - self.wait_called = True - - self.driver._proc.wait = fake_wait - - class FakeExecutive(object): - def kill_process(other, pid): - self.pid = pid - self.driver._proc.poll = lambda: 2 - - self.driver._port._executive = FakeExecutive() - self.driver.KILL_TIMEOUT_DEFAULT = 0.01 - self.driver.stop() - self.assertTrue(self.wait_called) - self.assertEquals(self.pid, 1) - - def test_two_drivers(self): - - class MockDriver(chromium.ChromiumDriver): - def __init__(self, port): - chromium.ChromiumDriver.__init__(self, port, worker_number=0, pixel_tests=False) - - def cmd_line(self, pixel_test, per_test_args): - return 'python' - - # get_option is used to get the timeout (ms) for a process before we kill it. - driver1 = MockDriver(self.port) - driver1._start(False, []) - driver2 = MockDriver(self.port) - driver2._start(False, []) - # It's possible for driver1 to timeout when stopping if it's sharing stdin with driver2. - start_time = time.time() - driver1.stop() - driver2.stop() - self.assertTrue(time.time() - start_time < 20) - - def test_stop_cleans_up_properly(self): - self.driver._test_shell = False - self.driver.start(True, []) - last_tmpdir = self.port._filesystem.last_tmpdir - self.assertNotEquals(last_tmpdir, None) - self.driver.stop() - self.assertFalse(self.port._filesystem.isdir(last_tmpdir)) - - def test_two_starts_cleans_up_properly(self): - # clone the WebKitDriverTest tests here since we override start() and stop() - self.driver._test_shell = False - self.driver.start(True, []) - last_tmpdir = self.port._filesystem.last_tmpdir - self.driver._start(True, []) - self.assertFalse(self.port._filesystem.isdir(last_tmpdir)) - - def test_expectations_dict(self): - self.port._filesystem.write_text_file('/mock-checkout/LayoutTests/platform/chromium/TestExpectations', 'upstream') - self.port._filesystem.write_text_file('/mock-checkout/Source/WebKit/chromium/webkit/tools/layout_tests/test_expectations.txt', 'downstream') - self.assertEquals('\n'.join(self.port.expectations_dict().values()), 'upstream\ndownstream') - - self.port._filesystem.write_text_file(self.port.path_from_chromium_base('skia', 'skia_test_expectations.txt'), 'skia') - self.assertEquals('\n'.join(self.port.expectations_dict().values()), 'upstream\nskia\ndownstream') - - class ChromiumPortLoggingTest(logtesting.LoggingTestCase): # FIXME: put this someplace more useful diff --git a/Tools/Scripts/webkitpy/layout_tests/port/server_process.py b/Tools/Scripts/webkitpy/layout_tests/port/server_process.py index 7e467dc12..e07a804b0 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/server_process.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/server_process.py @@ -61,11 +61,14 @@ class ServerProcess(object): indefinitely. The class also handles transparently restarting processes as necessary to keep issuing commands.""" - def __init__(self, port_obj, name, cmd, env=None): + def __init__(self, port_obj, name, cmd, env=None, universal_newlines=False): self._port = port_obj self._name = name # Should be the command name (e.g. DumpRenderTree, ImageDiff) self._cmd = cmd self._env = env + # Set if the process outputs non-standard newlines like '\r\n' or '\r'. + # Don't set if there will be binary data or the data must be ASCII encoded. + self._universal_newlines = universal_newlines self._host = self._port.host self._pid = None self._reset() @@ -100,7 +103,8 @@ class ServerProcess(object): stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=close_fds, - env=self._env) + env=self._env, + universal_newlines=self._universal_newlines) self._pid = self._proc.pid fd = self._proc.stdout.fileno() if not self._use_win32_apis: @@ -225,9 +229,18 @@ class ServerProcess(object): try: if out_fd in read_fds: - self._output += self._proc.stdout.read() + data = self._proc.stdout.read() + if not data: + _log.warning('unexpected EOF of stdout') + self._crashed = True + self._output += data + if err_fd in read_fds: - self._error += self._proc.stderr.read() + data = self._proc.stderr.read() + if not data: + _log.warning('unexpected EOF of stderr') + self._crashed = True + self._error += data except IOError, e: # We can ignore the IOErrors because we will detect if the subporcess crashed # the next time through the loop in _read() @@ -295,7 +308,7 @@ class ServerProcess(object): if not self._proc: self._start() - def stop(self): + def stop(self, kill_directly=False): if not self._proc: return @@ -307,14 +320,15 @@ class ServerProcess(object): self._proc.stdout.close() if self._proc.stderr: self._proc.stderr.close() - if not self._host.platform.is_win(): + + if kill_directly: + self.kill() + elif not self._host.platform.is_win(): # Closing stdin/stdout/stderr hangs sometimes on OS X, - # (see restart(), above), and anyway we don't want to hang - # the harness if DumpRenderTree is buggy, so we wait a couple - # seconds to give DumpRenderTree a chance to clean up, but then - # force-kill the process if necessary. - KILL_TIMEOUT = 3.0 - timeout = time.time() + KILL_TIMEOUT + # and anyway we don't want to hang the harness if DumpRenderTree + # is buggy, so we wait a couple seconds to give DumpRenderTree a + # chance to clean up, but then force-kill the process if necessary. + timeout = time.time() + self._port.process_kill_time() while self._proc.poll() is None and time.time() < timeout: time.sleep(0.01) if self._proc.poll() is None: @@ -329,3 +343,12 @@ class ServerProcess(object): if self._proc.poll() is not None: self._proc.wait() self._reset() + + def replace_outputs(self, stdout, stderr): + assert self._proc + if stdout: + self._proc.stdout.close() + self._proc.stdout = stdout + if stderr: + self._proc.stderr.close() + self._proc.stderr = stderr diff --git a/Tools/Scripts/webkitpy/layout_tests/port/server_process_unittest.py b/Tools/Scripts/webkitpy/layout_tests/port/server_process_unittest.py index c0426c1cf..db38615e0 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/server_process_unittest.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/server_process_unittest.py @@ -48,6 +48,9 @@ class TrivialMockPort(object): def check_for_leaks(self, process_name, process_pid): pass + def process_kill_time(self): + return 1 + class MockFile(object): def __init__(self, server_process): diff --git a/Tools/Scripts/webkitpy/layout_tests/port/webkit.py b/Tools/Scripts/webkitpy/layout_tests/port/webkit.py index fad6f7a5d..d376e774a 100755 --- a/Tools/Scripts/webkitpy/layout_tests/port/webkit.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/webkit.py @@ -531,7 +531,7 @@ class WebKitDriver(Driver): command = cygpath(command) if driver_input.image_hash: - # FIXME: Why the leading quote? + # "'" is the separator of command fields. command += "'" + driver_input.image_hash return command + "\n" @@ -552,11 +552,12 @@ class WebKitDriver(Driver): def run_test(self, driver_input): start_time = time.time() self.start(driver_input.should_run_pixel_test, driver_input.args) + test_begin_time = time.time() self.error_from_test = str() self.err_seen_eof = False command = self._command_from_driver_input(driver_input) - deadline = start_time + int(driver_input.timeout) / 1000.0 + deadline = test_begin_time + int(driver_input.timeout) / 1000.0 self._server_process.write(command) text, audio = self._read_first_block(deadline) # First block is either text or audio @@ -587,7 +588,7 @@ class WebKitDriver(Driver): self._server_process.kill() return DriverOutput(text, image, actual_image_hash, audio, - crash=self.has_crashed(), test_time=time.time() - start_time, + crash=self.has_crashed(), test_time=time.time() - test_begin_time, timeout=timeout, error=self.error_from_test, crashed_process_name=self._crashed_process_name, crashed_pid=self._crashed_pid, crash_log=crash_log) diff --git a/Tools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py b/Tools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py index cfec29b33..54ad31919 100755 --- a/Tools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py @@ -246,15 +246,30 @@ class MockServerProcess(object): return self.lines.pop(0) + "\n" def read_stdout(self, deadline, size): - # read_stdout doesn't actually function on lines, but this is sufficient for our testing. - line = self.lines.pop(0) - assert len(line) == size - return line + first_line = self.lines[0] + if size > len(first_line): + self.lines.pop(0) + remaining_size = size - len(first_line) - 1 + if not remaining_size: + return first_line + "\n" + return first_line + "\n" + self.read_stdout(deadline, remaining_size) + result = self.lines[0][:size] + self.lines[0] = self.lines[0][size:] + return result def read_either_stdout_or_stderr_line(self, deadline): # FIXME: We should have tests which intermix stderr and stdout lines. return self.read_stdout_line(deadline), None + def start(self): + return + + def stop(self, kill_directly=False): + return + + def kill(self): + return + class WebKitDriverTest(unittest.TestCase): def test_read_block(self): @@ -279,17 +294,35 @@ class WebKitDriverTest(unittest.TestCase): 'ActualHash: actual', 'ExpectedHash: expected', 'Content-Type: image/png', - 'Content-Length: 8', + 'Content-Length: 9', "12345678", "#EOF", ]) content_block = driver._read_block(0) self.assertEquals(content_block.content_type, 'image/png') self.assertEquals(content_block.content_hash, 'actual') - self.assertEquals(content_block.content, '12345678') - self.assertEquals(content_block.decoded_content, '12345678') + self.assertEquals(content_block.content, '12345678\n') + self.assertEquals(content_block.decoded_content, '12345678\n') driver._server_process = None + def test_read_base64_block(self): + port = TestWebKitPort() + driver = WebKitDriver(port, 0, pixel_tests=True) + driver._server_process = MockServerProcess([ + 'ActualHash: actual', + 'ExpectedHash: expected', + 'Content-Type: image/png', + 'Content-Transfer-Encoding: base64', + 'Content-Length: 12', + 'MTIzNDU2NzgK#EOF', + ]) + content_block = driver._read_block(0) + self.assertEquals(content_block.content_type, 'image/png') + self.assertEquals(content_block.content_hash, 'actual') + self.assertEquals(content_block.encoding, 'base64') + self.assertEquals(content_block.content, 'MTIzNDU2NzgK') + self.assertEquals(content_block.decoded_content, '12345678\n') + def test_no_timeout(self): port = TestWebKitPort() driver = WebKitDriver(port, 0, pixel_tests=True, no_timeout=True) diff --git a/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py b/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py index 691c8456b..60db587e0 100755 --- a/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py +++ b/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py @@ -109,9 +109,9 @@ def run(port, options, args, regular_output=sys.stderr, buildbot_output=sys.stdo unexpected_result_count = -1 try: manager = Manager(port, options, printer) - manager.print_config() + printer.print_config() - printer.print_update("Collecting tests ...") + printer.write_update("Collecting tests ...") try: manager.collect_tests(args) except IOError, e: @@ -119,12 +119,12 @@ def run(port, options, args, regular_output=sys.stderr, buildbot_output=sys.stdo return -1 raise - printer.print_update("Checking build ...") + printer.write_update("Checking build ...") if not port.check_build(manager.needs_servers()): _log.error("Build check failed") return -1 - printer.print_update("Parsing expectations ...") + printer.write_update("Parsing expectations ...") manager.parse_expectations() unexpected_result_count = manager.run() @@ -420,6 +420,11 @@ def parse_args(args=None): help="Don't re-try any tests that produce unexpected results."), optparse.make_option("--max-locked-shards", type="int", help="Set the maximum number of locked shards"), + # For chromium-android to reduce the cost of restarting the driver. + # FIXME: Remove the option once per-test arg is supported: + # https://bugs.webkit.org/show_bug.cgi?id=91539. + optparse.make_option("--shard-ref-tests", action="store_true", + help="Run ref tests in dedicated shard(s). Enabled on Android by default."), ])) option_group_definitions.append(("Miscellaneous Options", [ @@ -482,8 +487,10 @@ def main(argv=None): if '__main__' == __name__: try: - sys.exit(main()) + return_code = main() except BaseException, e: if e.__class__ in (KeyboardInterrupt, TestRunInterruptedException): sys.exit(INTERRUPTED_EXIT_STATUS) sys.exit(EXCEPTIONAL_EXIT_STATUS) + + sys.exit(return_code) diff --git a/Tools/Scripts/webkitpy/layout_tests/views/printing.py b/Tools/Scripts/webkitpy/layout_tests/views/printing.py index 2dd909930..1c2fecd7b 100644 --- a/Tools/Scripts/webkitpy/layout_tests/views/printing.py +++ b/Tools/Scripts/webkitpy/layout_tests/views/printing.py @@ -29,10 +29,12 @@ """Package that handles non-debug, non-file output for run-webkit-tests.""" +import math import optparse from webkitpy.tool import grammar from webkitpy.common.net import resultsjsonparser +from webkitpy.layout_tests.models import test_expectations from webkitpy.layout_tests.models.test_expectations import TestExpectations from webkitpy.layout_tests.views.metered_stream import MeteredStream @@ -192,15 +194,313 @@ class Printer(object): def help_printing(self): self._write(HELP_PRINTING) + def print_config(self): + """Prints the configuration for the test run.""" + self._print_config("Using port '%s'" % self._port.name()) + self._print_config("Test configuration: %s" % self._port.test_configuration()) + self._print_config("Placing test results in %s" % self._options.results_directory) + + # FIXME: should these options be in printing_options? + if self._options.new_baseline: + self._print_config("Placing new baselines in %s" % self._port.baseline_path()) + + fs = self._port.host.filesystem + fallback_path = [fs.split(x)[1] for x in self._port.baseline_search_path()] + self._print_config("Baseline search path: %s -> generic" % " -> ".join(fallback_path)) + + self._print_config("Using %s build" % self._options.configuration) + if self._options.pixel_tests: + self._print_config("Pixel tests enabled") + else: + self._print_config("Pixel tests disabled") + + self._print_config("Regular timeout: %s, slow test timeout: %s" % + (self._options.time_out_ms, self._options.slow_time_out_ms)) + + self._print_config('Command line: ' + ' '.join(self._port.driver_cmd_line())) + self._print_config('') + + def print_expected(self, num_all_test_files, result_summary, tests_with_result_type_callback): + self._print_expected('Found %s.' % grammar.pluralize('test', num_all_test_files)) + self._print_expected_results_of_type(result_summary, test_expectations.PASS, "passes", tests_with_result_type_callback) + self._print_expected_results_of_type(result_summary, test_expectations.FAIL, "failures", tests_with_result_type_callback) + self._print_expected_results_of_type(result_summary, test_expectations.FLAKY, "flaky", tests_with_result_type_callback) + self._print_expected_results_of_type(result_summary, test_expectations.SKIP, "skipped", tests_with_result_type_callback) + self._print_expected('') + + if self._options.repeat_each > 1: + self._print_expected('Running each test %d times.' % self._options.repeat_each) + if self._options.iterations > 1: + self._print_expected('Running %d iterations of the tests.' % self._options.iterations) + if self._options.iterations > 1 or self._options.repeat_each > 1: + self._print_expected('') + + def print_workers_and_shards(self, num_workers, num_shards, num_locked_shards): + driver_name = self._port.driver_name() + if num_workers == 1: + self._print_config("Running 1 %s over %s." % + (driver_name, grammar.pluralize('shard', num_shards))) + else: + self._print_config("Running %d %ss in parallel over %d shards (%d locked)." % + (num_workers, driver_name, num_shards, num_locked_shards)) + self._print_config('') + + def _print_expected_results_of_type(self, result_summary, + result_type, result_type_str, tests_with_result_type_callback): + """Print the number of the tests in a given result class. + + Args: + result_summary - the object containing all the results to report on + result_type - the particular result type to report in the summary. + result_type_str - a string description of the result_type. + expectations - populated TestExpectations object for stats + """ + tests = tests_with_result_type_callback(result_type) + now = result_summary.tests_by_timeline[test_expectations.NOW] + wontfix = result_summary.tests_by_timeline[test_expectations.WONTFIX] + + # We use a fancy format string in order to print the data out in a + # nicely-aligned table. + fmtstr = ("Expect: %%5d %%-8s (%%%dd now, %%%dd wontfix)" + % (self._num_digits(now), self._num_digits(wontfix))) + self._print_expected(fmtstr % + (len(tests), result_type_str, len(tests & now), len(tests & wontfix))) + + def _num_digits(self, num): + """Returns the number of digits needed to represent the length of a + sequence.""" + ndigits = 1 + if len(num): + ndigits = int(math.log10(len(num))) + 1 + return ndigits + + def print_results(self, run_time, thread_timings, test_timings, individual_test_timings, result_summary, unexpected_results): + self._print_timing_statistics(run_time, thread_timings, test_timings, individual_test_timings, result_summary) + self._print_result_summary(result_summary) + + self.print_one_line_summary(result_summary.total - result_summary.expected_skips, result_summary.expected - result_summary.expected_skips, result_summary.unexpected) + + self.print_unexpected_results(unexpected_results) + + def _print_timing_statistics(self, total_time, thread_timings, + directory_test_timings, individual_test_timings, + result_summary): + """Record timing-specific information for the test run. + + Args: + total_time: total elapsed time (in seconds) for the test run + thread_timings: wall clock time each thread ran for + directory_test_timings: timing by directory + individual_test_timings: timing by file + result_summary: summary object for the test run + """ + self.print_timing("Test timing:") + self.print_timing(" %6.2f total testing time" % total_time) + self.print_timing("") + self.print_timing("Thread timing:") + cuml_time = 0 + for t in thread_timings: + self.print_timing(" %10s: %5d tests, %6.2f secs" % + (t['name'], t['num_tests'], t['total_time'])) + cuml_time += t['total_time'] + self.print_timing(" %6.2f cumulative, %6.2f optimal" % + (cuml_time, cuml_time / int(self._options.child_processes))) + self.print_timing("") + + self._print_aggregate_test_statistics(individual_test_timings) + self._print_individual_test_times(individual_test_timings, + result_summary) + self._print_directory_timings(directory_test_timings) + + def _print_aggregate_test_statistics(self, individual_test_timings): + """Prints aggregate statistics (e.g. median, mean, etc.) for all tests. + Args: + individual_test_timings: List of TestResults for all tests. + """ + times_for_dump_render_tree = [test_stats.test_run_time for test_stats in individual_test_timings] + self._print_statistics_for_test_timings("PER TEST TIME IN TESTSHELL (seconds):", + times_for_dump_render_tree) + + def _print_individual_test_times(self, individual_test_timings, + result_summary): + """Prints the run times for slow, timeout and crash tests. + Args: + individual_test_timings: List of TestStats for all tests. + result_summary: summary object for test run + """ + # Reverse-sort by the time spent in DumpRenderTree. + individual_test_timings.sort(lambda a, b: + cmp(b.test_run_time, a.test_run_time)) + + num_printed = 0 + slow_tests = [] + timeout_or_crash_tests = [] + unexpected_slow_tests = [] + for test_tuple in individual_test_timings: + test_name = test_tuple.test_name + is_timeout_crash_or_slow = False + if test_name in result_summary.slow_tests: + is_timeout_crash_or_slow = True + slow_tests.append(test_tuple) + + if test_name in result_summary.failures: + result = result_summary.results[test_name].type + if (result == test_expectations.TIMEOUT or + result == test_expectations.CRASH): + is_timeout_crash_or_slow = True + timeout_or_crash_tests.append(test_tuple) + + if (not is_timeout_crash_or_slow and num_printed < NUM_SLOW_TESTS_TO_LOG): + num_printed = num_printed + 1 + unexpected_slow_tests.append(test_tuple) + + self.print_timing("") + self._print_test_list_timing("%s slowest tests that are not " + "marked as SLOW and did not timeout/crash:" % NUM_SLOW_TESTS_TO_LOG, unexpected_slow_tests) + self.print_timing("") + self._print_test_list_timing("Tests marked as SLOW:", slow_tests) + self.print_timing("") + self._print_test_list_timing("Tests that timed out or crashed:", + timeout_or_crash_tests) + self.print_timing("") + + def _print_test_list_timing(self, title, test_list): + """Print timing info for each test. + + Args: + title: section heading + test_list: tests that fall in this section + """ + if self.disabled('slowest'): + return + + self.print_timing(title) + for test_tuple in test_list: + test_run_time = round(test_tuple.test_run_time, 1) + self.print_timing(" %s took %s seconds" % (test_tuple.test_name, test_run_time)) + + def _print_directory_timings(self, directory_test_timings): + """Print timing info by directory for any directories that + take > 10 seconds to run. + + Args: + directory_test_timing: time info for each directory + """ + timings = [] + for directory in directory_test_timings: + num_tests, time_for_directory = directory_test_timings[directory] + timings.append((round(time_for_directory, 1), directory, + num_tests)) + timings.sort() + + self.print_timing("Time to process slowest subdirectories:") + min_seconds_to_print = 10 + for timing in timings: + if timing[0] > min_seconds_to_print: + self.print_timing( + " %s took %s seconds to run %s tests." % (timing[1], + timing[0], timing[2])) + self.print_timing("") + + def _print_statistics_for_test_timings(self, title, timings): + """Prints the median, mean and standard deviation of the values in + timings. + + Args: + title: Title for these timings. + timings: A list of floats representing times. + """ + self.print_timing(title) + timings.sort() + + num_tests = len(timings) + if not num_tests: + return + percentile90 = timings[int(.9 * num_tests)] + percentile99 = timings[int(.99 * num_tests)] + + if num_tests % 2 == 1: + median = timings[((num_tests - 1) / 2) - 1] + else: + lower = timings[num_tests / 2 - 1] + upper = timings[num_tests / 2] + median = (float(lower + upper)) / 2 + + mean = sum(timings) / num_tests + + for timing in timings: + sum_of_deviations = math.pow(timing - mean, 2) + + std_deviation = math.sqrt(sum_of_deviations / num_tests) + self.print_timing(" Median: %6.3f" % median) + self.print_timing(" Mean: %6.3f" % mean) + self.print_timing(" 90th percentile: %6.3f" % percentile90) + self.print_timing(" 99th percentile: %6.3f" % percentile99) + self.print_timing(" Standard dev: %6.3f" % std_deviation) + self.print_timing("") + + def _print_result_summary(self, result_summary): + """Print a short summary about how many tests passed. + + Args: + result_summary: information to log + """ + failed = result_summary.total_failures + total = result_summary.total - result_summary.expected_skips + passed = total - failed + pct_passed = 0.0 + if total > 0: + pct_passed = float(passed) * 100 / total + + self.print_actual("") + self.print_actual("=> Results: %d/%d tests passed (%.1f%%)" % + (passed, total, pct_passed)) + self.print_actual("") + self._print_result_summary_entry(result_summary, + test_expectations.NOW, "Tests to be fixed") + + self.print_actual("") + self._print_result_summary_entry(result_summary, + test_expectations.WONTFIX, + "Tests that will only be fixed if they crash (WONTFIX)") + self.print_actual("") + + def _print_result_summary_entry(self, result_summary, timeline, + heading): + """Print a summary block of results for a particular timeline of test. + + Args: + result_summary: summary to print results for + timeline: the timeline to print results for (NOT, WONTFIX, etc.) + heading: a textual description of the timeline + """ + total = len(result_summary.tests_by_timeline[timeline]) + not_passing = (total - + len(result_summary.tests_by_expectation[test_expectations.PASS] & + result_summary.tests_by_timeline[timeline])) + self.print_actual("=> %s (%d):" % (heading, not_passing)) + + for result in TestExpectations.EXPECTATION_ORDER: + if result == test_expectations.PASS: + continue + results = (result_summary.tests_by_expectation[result] & + result_summary.tests_by_timeline[timeline]) + desc = TestExpectations.EXPECTATION_DESCRIPTIONS[result] + if not_passing and len(results): + pct = len(results) * 100.0 / not_passing + self.print_actual(" %5d %-24s (%4.1f%%)" % + (len(results), desc[len(results) != 1], pct)) + + def print_actual(self, msg): if self.disabled('actual'): return self._buildbot_stream.write("%s\n" % msg) - def print_config(self, msg): + def _print_config(self, msg): self.write(msg, 'config') - def print_expected(self, msg): + def _print_expected(self, msg): self.write(msg, 'expected') def print_timing(self, msg): @@ -235,6 +535,10 @@ class Printer(object): self._write("%s ran as expected, %d didn't%s:" % (grammar.pluralize('test', expected), unexpected, incomplete_str)) self._write("") + def print_finished_test(self, result, expected, exp_str, got_str, result_summary, retrying, test_files_list): + self.print_test_result(result, expected, exp_str, got_str) + self.print_progress(result_summary, retrying, test_files_list) + def print_test_result(self, result, expected, exp_str, got_str): """Print the result of the test as determined by --print. @@ -396,7 +700,7 @@ class Printer(object): if len(unexpected_results['tests']) and self._options.verbose: self._buildbot_stream.write("%s\n" % ("-" * 78)) - def print_update(self, msg): + def write_update(self, msg): if self.disabled('updates'): return self._meter.write_update(msg) diff --git a/Tools/Scripts/webkitpy/layout_tests/views/printing_unittest.py b/Tools/Scripts/webkitpy/layout_tests/views/printing_unittest.py index 1312050e9..f8dd61db7 100644 --- a/Tools/Scripts/webkitpy/layout_tests/views/printing_unittest.py +++ b/Tools/Scripts/webkitpy/layout_tests/views/printing_unittest.py @@ -184,19 +184,30 @@ class Testprinter(unittest.TestCase): # buildbot is expecting. pass + def test_fallback_path_in_config(self): + printer, err, out = self.get_printer(['--print', 'everything']) + # FIXME: it's lame that i have to set these options directly. + printer._options.results_directory = '/tmp' + printer._options.pixel_tests = True + printer._options.new_baseline = True + printer._options.time_out_ms = 6000 + printer._options.slow_time_out_ms = 12000 + printer.print_config() + self.assertTrue('Baseline search path: test-mac-leopard -> test-mac-snowleopard -> generic' in err.getvalue()) + def test_print_config(self): - self.do_switch_tests('print_config', 'config', to_buildbot=False) + self.do_switch_tests('_print_config', 'config', to_buildbot=False) def test_print_expected(self): - self.do_switch_tests('print_expected', 'expected', to_buildbot=False) + self.do_switch_tests('_print_expected', 'expected', to_buildbot=False) def test_print_timing(self): self.do_switch_tests('print_timing', 'timing', to_buildbot=False) - def test_print_update(self): + def test_write_update(self): # Note that there shouldn't be a carriage return here; updates() # are meant to be overwritten. - self.do_switch_tests('print_update', 'updates', to_buildbot=False, + self.do_switch_tests('write_update', 'updates', to_buildbot=False, message='hello', exp_err=['hello']) def test_print_one_line_summary(self): @@ -405,25 +416,26 @@ class Testprinter(unittest.TestCase): all pass on the second run). """ + test_is_slow = False paths, rs, exp = self.get_result_summary(tests, expectations) if expected: - rs.add(self.get_result('passes/text.html', test_expectations.PASS), expected) - rs.add(self.get_result('failures/expected/timeout.html', test_expectations.TIMEOUT), expected) - rs.add(self.get_result('failures/expected/crash.html', test_expectations.CRASH), expected) + rs.add(self.get_result('passes/text.html', test_expectations.PASS), expected, test_is_slow) + rs.add(self.get_result('failures/expected/timeout.html', test_expectations.TIMEOUT), expected, test_is_slow) + rs.add(self.get_result('failures/expected/crash.html', test_expectations.CRASH), expected, test_is_slow) elif passing: - rs.add(self.get_result('passes/text.html'), expected) - rs.add(self.get_result('failures/expected/timeout.html'), expected) - rs.add(self.get_result('failures/expected/crash.html'), expected) + rs.add(self.get_result('passes/text.html'), expected, test_is_slow) + rs.add(self.get_result('failures/expected/timeout.html'), expected, test_is_slow) + rs.add(self.get_result('failures/expected/crash.html'), expected, test_is_slow) else: - rs.add(self.get_result('passes/text.html', test_expectations.TIMEOUT), expected) - rs.add(self.get_result('failures/expected/timeout.html', test_expectations.CRASH), expected) - rs.add(self.get_result('failures/expected/crash.html', test_expectations.TIMEOUT), expected) + rs.add(self.get_result('passes/text.html', test_expectations.TIMEOUT), expected, test_is_slow) + rs.add(self.get_result('failures/expected/timeout.html', test_expectations.CRASH), expected, test_is_slow) + rs.add(self.get_result('failures/expected/crash.html', test_expectations.TIMEOUT), expected, test_is_slow) retry = rs if flaky: paths, retry, exp = self.get_result_summary(tests, expectations) - retry.add(self.get_result('passes/text.html'), True) - retry.add(self.get_result('failures/expected/timeout.html'), True) - retry.add(self.get_result('failures/expected/crash.html'), True) + retry.add(self.get_result('passes/text.html'), True, test_is_slow) + retry.add(self.get_result('failures/expected/timeout.html'), True, test_is_slow) + retry.add(self.get_result('failures/expected/crash.html'), True, test_is_slow) unexpected_results = manager.summarize_results(self._port, exp, rs, retry, test_timings={}, only_unexpected=True, interrupted=False) return unexpected_results diff --git a/Tools/Scripts/webkitpy/style/checkers/cpp.py b/Tools/Scripts/webkitpy/style/checkers/cpp.py index aaad85d5c..ba1153087 100644 --- a/Tools/Scripts/webkitpy/style/checkers/cpp.py +++ b/Tools/Scripts/webkitpy/style/checkers/cpp.py @@ -1161,14 +1161,19 @@ class _FileState(object): self._clean_lines = clean_lines if file_extension in ['m', 'mm']: self._is_objective_c = True + self._is_c = False elif file_extension == 'h': # In the case of header files, it is unknown if the file - # is objective c or not, so set this value to None and then + # is c / objective c or not, so set this value to None and then # if it is requested, use heuristics to guess the value. self._is_objective_c = None + self._is_c = None + elif file_extension == 'c': + self._is_c = True + self._is_objective_c = False else: self._is_objective_c = False - self._is_c = file_extension == 'c' + self._is_c = False def set_did_inside_namespace_indent_warning(self): self._did_inside_namespace_indent_warning = True @@ -1188,9 +1193,21 @@ class _FileState(object): self._is_objective_c = False return self._is_objective_c + def is_c(self): + if self._is_c is None: + for line in self._clean_lines.lines: + # if extern "C" is found, then it is a good indication + # that we have a C header file. + if line.startswith('extern "C"'): + self._is_c = True + break + else: + self._is_c = False + return self._is_c + def is_c_or_objective_c(self): """Return whether the file extension corresponds to C or Objective-C.""" - return self._is_c or self.is_objective_c() + return self.is_c() or self.is_objective_c() def check_for_non_standard_constructs(clean_lines, line_number, diff --git a/Tools/Scripts/webkitpy/test/finder.py b/Tools/Scripts/webkitpy/test/finder.py index 132072d82..fcbb0e9cf 100644 --- a/Tools/Scripts/webkitpy/test/finder.py +++ b/Tools/Scripts/webkitpy/test/finder.py @@ -101,7 +101,7 @@ class Finder(object): return tree.to_module(path) return None - def find_names(self, args, skip_integrationtests, find_all): + def find_names(self, args, skip_integrationtests, find_all, skip_if_parallel=True): suffixes = ['_unittest.py'] if not skip_integrationtests: suffixes.append('_integrationtest.py') @@ -112,7 +112,7 @@ class Finder(object): names.extend(self._find_names_for_arg(arg, suffixes)) return names - return self._default_names(suffixes, find_all) + return self._default_names(suffixes, find_all, skip_if_parallel) def _find_names_for_arg(self, arg, suffixes): realpath = self.filesystem.realpath(arg) @@ -145,7 +145,7 @@ class Finder(object): return tree.find_modules(suffixes, path) return [] - def _default_names(self, suffixes, find_all): + def _default_names(self, suffixes, find_all, skip_if_parallel): modules = [] for tree in self.trees: modules.extend(tree.find_modules(suffixes)) diff --git a/Tools/Scripts/webkitpy/test/finder_unittest.py b/Tools/Scripts/webkitpy/test/finder_unittest.py index 09048b159..386c579c7 100644 --- a/Tools/Scripts/webkitpy/test/finder_unittest.py +++ b/Tools/Scripts/webkitpy/test/finder_unittest.py @@ -47,18 +47,15 @@ class FinderTest(unittest.TestCase): # Here we have to jump through a hoop to make sure test-webkitpy doesn't log # any messages from these tests :(. self.root_logger = logging.getLogger() - self.log_handler = None - for h in self.root_logger.handlers: - if getattr(h, 'name', None) == 'webkitpy.test.printer': - self.log_handler = h - break - if self.log_handler: - self.log_level = self.log_handler.level - self.log_handler.level = logging.CRITICAL + self.log_levels = [] + self.log_handlers = self.root_logger.handlers[:] + for handler in self.log_handlers: + self.log_levels.append(handler.level) + handler.level = logging.CRITICAL def tearDown(self): - if self.log_handler: - self.log_handler.setLevel(self.log_level) + for handler in self.log_handlers: + handler.level = self.log_levels.pop(0) def test_additional_system_paths(self): self.assertEquals(self.finder.additional_paths(['/usr']), diff --git a/Tools/Scripts/webkitpy/test/main.py b/Tools/Scripts/webkitpy/test/main.py index 2048d9e59..abb297b2b 100644 --- a/Tools/Scripts/webkitpy/test/main.py +++ b/Tools/Scripts/webkitpy/test/main.py @@ -63,6 +63,8 @@ class Tester(object): help='do not run the integration tests') parser.add_option('-p', '--pass-through', action='store_true', default=False, help='be debugger friendly by passing captured output through to the system') + parser.add_option('-j', '--child-processes', action='store', type='int', default=1, + help='number of tests to run in parallel') parser.epilog = ('[args...] is an optional list of modules, test_classes, or individual tests. ' 'If no args are given, all the tests will be run.') @@ -75,7 +77,7 @@ class Tester(object): self.finder.clean_trees() - names = self.finder.find_names(args, self._options.skip_integrationtests, self._options.all) + names = self.finder.find_names(args, self._options.skip_integrationtests, self._options.all, self._options.child_processes != 1) if not names: _log.error('No tests to run') return False diff --git a/Tools/Scripts/webkitpy/test/main_unittest.py b/Tools/Scripts/webkitpy/test/main_unittest.py index 2cf6df4a2..61e49a7b9 100644 --- a/Tools/Scripts/webkitpy/test/main_unittest.py +++ b/Tools/Scripts/webkitpy/test/main_unittest.py @@ -41,7 +41,7 @@ class TesterTest(unittest.TestCase): root_logger.handlers = [] tester.printer.stream = errors - tester.finder.find_names = lambda args, skip_integration, run_all: [] + tester.finder.find_names = lambda args, skip_integration, run_all, skip_if_parallel: [] oc = OutputCapture() try: oc.capture_output() diff --git a/Tools/Scripts/webkitpy/test/printer.py b/Tools/Scripts/webkitpy/test/printer.py index 77e28b8d1..042fba13c 100644 --- a/Tools/Scripts/webkitpy/test/printer.py +++ b/Tools/Scripts/webkitpy/test/printer.py @@ -22,10 +22,10 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import logging -import re import StringIO from webkitpy.common.system import outputcapture +from webkitpy.layout_tests.views.metered_stream import MeteredStream _log = logging.getLogger(__name__) @@ -33,12 +33,14 @@ _log = logging.getLogger(__name__) class Printer(object): def __init__(self, stream, options=None): self.stream = stream + self.meter = None self.options = options - self.test_description = re.compile("(\w+) \(([\w.]+)\)") - - def test_name(self, test): - m = self.test_description.match(str(test)) - return "%s.%s" % (m.group(2), m.group(1)) + self.num_tests = 0 + self.num_completed = 0 + self.running_tests = [] + self.completed_tests = [] + if options: + self.configure(options) def configure(self, options): self.options = options @@ -53,6 +55,8 @@ class Printer(object): elif options.verbose == 2: log_level = logging.DEBUG + self.meter = MeteredStream(self.stream, (options.verbose == 2)) + handler = logging.StreamHandler(self.stream) # We constrain the level on the handler rather than on the root # logger itself. This is probably better because the handler is @@ -98,59 +102,65 @@ class Printer(object): if self.options.pass_through: outputcapture.OutputCapture.stream_wrapper = _CaptureAndPassThroughStream - def print_started_test(self, test_name): + def print_started_test(self, source, test_name): + self.running_tests.append(test_name) + if len(self.running_tests) > 1: + suffix = ' (+%d)' % (len(self.running_tests) - 1) + else: + suffix = '' + if self.options.verbose: - self.stream.write(test_name) + write = self.meter.write_update + else: + write = self.meter.write_throttled_update + + write(self._test_line(self.running_tests[0], suffix)) def print_finished_test(self, result, test_name, test_time, failure, err): - timing = '' - if self.options.timing: - timing = ' %.4fs' % test_time - if self.options.verbose: - if failure: - msg = ' failed' - elif err: - msg = ' erred' + write = self.meter.writeln + if failure: + lines = failure[0][1].splitlines() + [''] + suffix = ' failed:' + elif err: + lines = err[0][1].splitlines() + [''] + suffix = ' erred:' + else: + suffix = ' passed' + lines = [] + if self.options.verbose: + write = self.meter.writeln else: - msg = ' passed' - self.stream.write(msg + timing + '\n') + write = self.meter.write_throttled_update + if self.options.timing: + suffix += ' %.4fs' % test_time + + self.num_completed += 1 + + if test_name == self.running_tests[0]: + self.completed_tests.insert(0, [test_name, suffix, lines]) else: - if failure: - msg = 'F' - elif err: - msg = 'E' + self.completed_tests.append([test_name, suffix, lines]) + self.running_tests.remove(test_name) + + for test_name, msg, lines in self.completed_tests: + if lines: + self.meter.writeln(self._test_line(test_name, msg)) + for line in lines: + self.meter.writeln(' ' + line) else: - msg = '.' - self.stream.write(msg) + write(self._test_line(test_name, msg)) + self.completed_tests = [] - def print_result(self, result, run_time): - self.stream.write('\n') - - for (test, err) in result.errors: - self.stream.write("=" * 80 + '\n') - self.stream.write("ERROR: " + self.test_name(test) + '\n') - self.stream.write("-" * 80 + '\n') - for line in err.splitlines(): - self.stream.write(line + '\n') - self.stream.write('\n') - - for (test, failure) in result.failures: - self.stream.write("=" * 80 + '\n') - self.stream.write("FAILURE: " + self.test_name(test) + '\n') - self.stream.write("-" * 80 + '\n') - for line in failure.splitlines(): - self.stream.write(line + '\n') - self.stream.write('\n') - - self.stream.write('-' * 80 + '\n') - self.stream.write('Ran %d test%s in %.3fs\n' % - (result.testsRun, result.testsRun != 1 and "s" or "", run_time)) + def _test_line(self, test_name, suffix): + return '[%d/%d] %s%s' % (self.num_completed, self.num_tests, test_name, suffix) + def print_result(self, result, run_time): + write = self.meter.writeln + write('Ran %d test%s in %.3fs' % (result.testsRun, result.testsRun != 1 and "s" or "", run_time)) if result.wasSuccessful(): - self.stream.write('\nOK\n') + write('\nOK\n') else: - self.stream.write('FAILED (failures=%d, errors=%d)\n' % - (len(result.failures), len(result.errors))) + write('FAILED (failures=%d, errors=%d)\n' % (len(result.failures), len(result.errors))) class _CaptureAndPassThroughStream(object): diff --git a/Tools/Scripts/webkitpy/test/runner.py b/Tools/Scripts/webkitpy/test/runner.py index 9c952075e..fd8af6fe0 100644 --- a/Tools/Scripts/webkitpy/test/runner.py +++ b/Tools/Scripts/webkitpy/test/runner.py @@ -23,18 +23,30 @@ """code to actually run a list of python tests.""" import logging +import re import time import unittest +from webkitpy.common import message_pool _log = logging.getLogger(__name__) +_test_description = re.compile("(\w+) \(([\w.]+)\)") + + +def _test_name(test): + m = _test_description.match(str(test)) + return "%s.%s" % (m.group(2), m.group(1)) + + class Runner(object): def __init__(self, printer, options, loader): self.options = options self.printer = printer self.loader = loader + self.result = unittest.TestResult() + self.worker_factory = lambda caller: _Worker(caller, self.loader) def all_test_names(self, suite): names = [] @@ -42,34 +54,48 @@ class Runner(object): for t in suite._tests: names.extend(self.all_test_names(t)) else: - names.append(self.printer.test_name(suite)) + names.append(_test_name(suite)) return names def run(self, suite): run_start_time = time.time() all_test_names = self.all_test_names(suite) + self.printer.num_tests = len(all_test_names) + + with message_pool.get(self, self.worker_factory, int(self.options.child_processes)) as pool: + pool.run(('test', test_name) for test_name in all_test_names) + + self.printer.print_result(self.result, time.time() - run_start_time) + return self.result + + def handle(self, message_name, source, test_name, delay=None, result=None): + if message_name == 'started_test': + self.printer.print_started_test(source, test_name) + return + + self.result.testsRun += 1 + self.result.errors.extend(result.errors) + self.result.failures.extend(result.failures) + self.printer.print_finished_test(source, test_name, delay, result.failures, result.errors) + + +class _Worker(object): + def __init__(self, caller, loader): + self._caller = caller + self._loader = loader + + def handle(self, message_name, source, test_name): + assert message_name == 'test' result = unittest.TestResult() - stop = run_start_time - for test_name in all_test_names: - self.printer.print_started_test(test_name) - num_failures = len(result.failures) - num_errors = len(result.errors) - - start = time.time() - # FIXME: it's kinda lame that we re-load the test suites for each - # test, and this may slow things down, but this makes implementing - # the logging easy and will also allow us to parallelize nicely. - self.loader.loadTestsFromName(test_name, None).run(result) - stop = time.time() - - err = None - failure = None - if len(result.failures) > num_failures: - failure = result.failures[num_failures][1] - elif len(result.errors) > num_errors: - err = result.errors[num_errors][1] - self.printer.print_finished_test(result, test_name, stop - start, failure, err) - - self.printer.print_result(result, stop - run_start_time) - - return result + start = time.time() + self._caller.post('started_test', test_name) + self._loader.loadTestsFromName(test_name, None).run(result) + + # The tests in the TestResult contain file objects and other unpicklable things; we only + # care about the test name, so we rewrite the result to replace the test with the test name. + # FIXME: We need an automated test for this, but I don't know how to write an automated + # test that will fail in this case that doesn't get picked up by test-webkitpy normally :(. + result.failures = [(_test_name(failure[0]), failure[1]) for failure in result.failures] + result.errors = [(_test_name(error[0]), error[1]) for error in result.errors] + + self._caller.post('finished_test', test_name, time.time() - start, result) diff --git a/Tools/Scripts/webkitpy/test/runner_unittest.py b/Tools/Scripts/webkitpy/test/runner_unittest.py index 1cf0146fb..07c5c31ea 100644 --- a/Tools/Scripts/webkitpy/test/runner_unittest.py +++ b/Tools/Scripts/webkitpy/test/runner_unittest.py @@ -20,13 +20,14 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import logging import re import StringIO import unittest from webkitpy.tool.mocktool import MockOptions from webkitpy.test.printer import Printer -from webkitpy.test.runner import Runner +from webkitpy.test.runner import Runner, _Worker class FakeModuleSuite(object): @@ -69,44 +70,42 @@ class FakeLoader(object): class RunnerTest(unittest.TestCase): - def test_regular(self): - options = MockOptions(verbose=0, timing=False) + def setUp(self): + # Here we have to jump through a hoop to make sure test-webkitpy doesn't log + # any messages from these tests :(. + self.root_logger = logging.getLogger() + self.log_levels = [] + self.log_handlers = self.root_logger.handlers[:] + for handler in self.log_handlers: + self.log_levels.append(handler.level) + handler.level = logging.CRITICAL + + def tearDown(self): + for handler in self.log_handlers: + handler.level = self.log_levels.pop(0) + + def assert_run(self, verbose=0, timing=False, child_processes=1, quiet=False): + options = MockOptions(verbose=verbose, timing=timing, child_processes=child_processes, quiet=quiet, pass_through=False) stream = StringIO.StringIO() loader = FakeLoader(('test1 (Foo)', '.', ''), ('test2 (Foo)', 'F', 'test2\nfailed'), ('test3 (Foo)', 'E', 'test3\nerred')) - result = Runner(Printer(stream, options), options, loader).run(loader.top_suite()) + runner = Runner(Printer(stream, options), options, loader) + result = runner.run(loader.top_suite()) self.assertFalse(result.wasSuccessful()) self.assertEquals(result.testsRun, 3) self.assertEquals(len(result.failures), 1) self.assertEquals(len(result.errors), 1) # FIXME: check the output from the test + def test_regular(self): + self.assert_run() + def test_verbose(self): - options = MockOptions(verbose=1, timing=False) - stream = StringIO.StringIO() - loader = FakeLoader(('test1 (Foo)', '.', ''), - ('test2 (Foo)', 'F', 'test2\nfailed'), - ('test3 (Foo)', 'E', 'test3\nerred')) - result = Runner(Printer(stream, options), options, loader).run(loader.top_suite()) - self.assertFalse(result.wasSuccessful()) - self.assertEquals(result.testsRun, 3) - self.assertEquals(len(result.failures), 1) - self.assertEquals(len(result.errors), 1) - # FIXME: check the output from the test + self.assert_run(verbose=1) def test_timing(self): - options = MockOptions(verbose=0, timing=True) - stream = StringIO.StringIO() - loader = FakeLoader(('test1 (Foo)', '.', ''), - ('test2 (Foo)', 'F', 'test2\nfailed'), - ('test3 (Foo)', 'E', 'test3\nerred')) - result = Runner(Printer(stream, options), options, loader).run(loader.top_suite()) - self.assertFalse(result.wasSuccessful()) - self.assertEquals(result.testsRun, 3) - self.assertEquals(len(result.failures), 1) - self.assertEquals(len(result.errors), 1) - # FIXME: check the output from the test + self.assert_run(timing=True) if __name__ == '__main__': diff --git a/Tools/Scripts/webkitpy/webkitpy.pyproj b/Tools/Scripts/webkitpy/webkitpy.pyproj new file mode 100644 index 000000000..72135a8d4 --- /dev/null +++ b/Tools/Scripts/webkitpy/webkitpy.pyproj @@ -0,0 +1,540 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{59b0a791-93fe-40f8-a52b-ba19b73e8fa6}</ProjectGuid> + <ProjectHome>.</ProjectHome> + <StartupFile>layout_tests\run_webkit_tests.py</StartupFile> + <SearchPath> + </SearchPath> + <WorkingDirectory>../</WorkingDirectory> + <OutputPath>.</OutputPath> + <Name>webkitpy</Name> + <RootNamespace>webkitpy</RootNamespace> + <IsWindowsApplication>False</IsWindowsApplication> + <LaunchProvider>Standard Python launcher</LaunchProvider> + <CommandLineArguments>--platform=mock --no-pixel-tests --no-retry-failures</CommandLineArguments> + <InterpreterPath /> + <InterpreterArguments /> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> + <DebugSymbols>true</DebugSymbols> + <EnableUnmanagedDebugging>false</EnableUnmanagedDebugging> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)' == 'Release' "> + <DebugSymbols>true</DebugSymbols> + <EnableUnmanagedDebugging>false</EnableUnmanagedDebugging> + </PropertyGroup> + <ItemGroup> + <Compile Include="bindings\main.py" /> + <Compile Include="bindings\__init__.py" /> + <Compile Include="common\checkout\baselineoptimizer.py" /> + <Compile Include="common\checkout\baselineoptimizer_unittest.py" /> + <Compile Include="common\checkout\changelog.py" /> + <Compile Include="common\checkout\changelog_unittest.py" /> + <Compile Include="common\checkout\checkout.py" /> + <Compile Include="common\checkout\checkout_mock.py" /> + <Compile Include="common\checkout\checkout_unittest.py" /> + <Compile Include="common\checkout\commitinfo.py" /> + <Compile Include="common\checkout\commitinfo_unittest.py" /> + <Compile Include="common\checkout\deps.py" /> + <Compile Include="common\checkout\deps_mock.py" /> + <Compile Include="common\checkout\diff_parser.py" /> + <Compile Include="common\checkout\diff_parser_unittest.py" /> + <Compile Include="common\checkout\diff_test_data.py" /> + <Compile Include="common\checkout\scm\commitmessage.py" /> + <Compile Include="common\checkout\scm\detection.py" /> + <Compile Include="common\checkout\scm\detection_unittest.py" /> + <Compile Include="common\checkout\scm\git.py" /> + <Compile Include="common\checkout\scm\scm.py" /> + <Compile Include="common\checkout\scm\scm_mock.py" /> + <Compile Include="common\checkout\scm\scm_unittest.py" /> + <Compile Include="common\checkout\scm\svn.py" /> + <Compile Include="common\checkout\scm\__init__.py" /> + <Compile Include="common\checkout\__init__.py" /> + <Compile Include="common\checksvnconfigfile.py" /> + <Compile Include="common\config\build.py" /> + <Compile Include="common\config\build_unittest.py" /> + <Compile Include="common\config\committers.py" /> + <Compile Include="common\config\committers_unittest.py" /> + <Compile Include="common\config\committervalidator.py" /> + <Compile Include="common\config\committervalidator_unittest.py" /> + <Compile Include="common\config\contributionareas.py" /> + <Compile Include="common\config\contributionareas_unittest.py" /> + <Compile Include="common\config\irc.py" /> + <Compile Include="common\config\ports.py" /> + <Compile Include="common\config\ports_mock.py" /> + <Compile Include="common\config\ports_unittest.py" /> + <Compile Include="common\config\urls.py" /> + <Compile Include="common\config\urls_unittest.py" /> + <Compile Include="common\config\__init__.py" /> + <Compile Include="common\editdistance.py" /> + <Compile Include="common\editdistance_unittest.py" /> + <Compile Include="common\find_files.py" /> + <Compile Include="common\find_files_unittest.py" /> + <Compile Include="common\host.py" /> + <Compile Include="common\host_mock.py" /> + <Compile Include="common\lru_cache.py" /> + <Compile Include="common\lru_cache_unittest.py" /> + <Compile Include="common\memoized.py" /> + <Compile Include="common\memoized_unittest.py" /> + <Compile Include="common\message_pool.py" /> + <Compile Include="common\net\bugzilla\attachment.py" /> + <Compile Include="common\net\bugzilla\bug.py" /> + <Compile Include="common\net\bugzilla\bugzilla.py" /> + <Compile Include="common\net\bugzilla\bugzilla_mock.py" /> + <Compile Include="common\net\bugzilla\bugzilla_unittest.py" /> + <Compile Include="common\net\bugzilla\bug_unittest.py" /> + <Compile Include="common\net\bugzilla\__init__.py" /> + <Compile Include="common\net\buildbot\buildbot.py" /> + <Compile Include="common\net\buildbot\buildbot_mock.py" /> + <Compile Include="common\net\buildbot\buildbot_unittest.py" /> + <Compile Include="common\net\buildbot\chromiumbuildbot.py" /> + <Compile Include="common\net\buildbot\__init__.py" /> + <Compile Include="common\net\credentials.py" /> + <Compile Include="common\net\credentials_unittest.py" /> + <Compile Include="common\net\failuremap.py" /> + <Compile Include="common\net\failuremap_unittest.py" /> + <Compile Include="common\net\file_uploader.py" /> + <Compile Include="common\net\htdigestparser.py" /> + <Compile Include="common\net\htdigestparser_unittest.py" /> + <Compile Include="common\net\irc\ircbot.py" /> + <Compile Include="common\net\irc\ircproxy.py" /> + <Compile Include="common\net\irc\ircproxy_unittest.py" /> + <Compile Include="common\net\irc\irc_mock.py" /> + <Compile Include="common\net\irc\__init__.py" /> + <Compile Include="common\net\layouttestresults.py" /> + <Compile Include="common\net\layouttestresults_unittest.py" /> + <Compile Include="common\net\networktransaction.py" /> + <Compile Include="common\net\networktransaction_unittest.py" /> + <Compile Include="common\net\omahaproxy.py" /> + <Compile Include="common\net\omahaproxy_unittest.py" /> + <Compile Include="common\net\regressionwindow.py" /> + <Compile Include="common\net\resultsjsonparser.py" /> + <Compile Include="common\net\resultsjsonparser_unittest.py" /> + <Compile Include="common\net\statusserver.py" /> + <Compile Include="common\net\statusserver_mock.py" /> + <Compile Include="common\net\statusserver_unittest.py" /> + <Compile Include="common\net\unittestresults.py" /> + <Compile Include="common\net\unittestresults_unittest.py" /> + <Compile Include="common\net\web.py" /> + <Compile Include="common\net\web_mock.py" /> + <Compile Include="common\net\__init__.py" /> + <Compile Include="common\newstringio.py" /> + <Compile Include="common\newstringio_unittest.py" /> + <Compile Include="common\prettypatch.py" /> + <Compile Include="common\prettypatch_unittest.py" /> + <Compile Include="common\read_checksum_from_png.py" /> + <Compile Include="common\read_checksum_from_png_unittest.py" /> + <Compile Include="common\system\autoinstall.py" /> + <Compile Include="common\system\crashlogs.py" /> + <Compile Include="common\system\crashlogs_unittest.py" /> + <Compile Include="common\system\deprecated_logging.py" /> + <Compile Include="common\system\deprecated_logging_unittest.py" /> + <Compile Include="common\system\environment.py" /> + <Compile Include="common\system\environment_unittest.py" /> + <Compile Include="common\system\executive.py" /> + <Compile Include="common\system\executive_mock.py" /> + <Compile Include="common\system\executive_unittest.py" /> + <Compile Include="common\system\fileset.py" /> + <Compile Include="common\system\filesystem.py" /> + <Compile Include="common\system\filesystem_mock.py" /> + <Compile Include="common\system\filesystem_mock_unittest.py" /> + <Compile Include="common\system\filesystem_unittest.py" /> + <Compile Include="common\system\file_lock.py" /> + <Compile Include="common\system\file_lock_integrationtest.py" /> + <Compile Include="common\system\logtesting.py" /> + <Compile Include="common\system\logutils.py" /> + <Compile Include="common\system\logutils_unittest.py" /> + <Compile Include="common\system\outputcapture.py" /> + <Compile Include="common\system\outputcapture_unittest.py" /> + <Compile Include="common\system\path.py" /> + <Compile Include="common\system\path_unittest.py" /> + <Compile Include="common\system\platforminfo.py" /> + <Compile Include="common\system\platforminfo_mock.py" /> + <Compile Include="common\system\platforminfo_unittest.py" /> + <Compile Include="common\system\stack_utils.py" /> + <Compile Include="common\system\stack_utils_unittest.py" /> + <Compile Include="common\system\systemhost.py" /> + <Compile Include="common\system\systemhost_mock.py" /> + <Compile Include="common\system\urlfetcher.py" /> + <Compile Include="common\system\urlfetcher_mock.py" /> + <Compile Include="common\system\user.py" /> + <Compile Include="common\system\user_mock.py" /> + <Compile Include="common\system\user_unittest.py" /> + <Compile Include="common\system\workspace.py" /> + <Compile Include="common\system\workspace_mock.py" /> + <Compile Include="common\system\workspace_unittest.py" /> + <Compile Include="common\system\zipfileset.py" /> + <Compile Include="common\system\zipfileset_mock.py" /> + <Compile Include="common\system\zipfileset_unittest.py" /> + <Compile Include="common\system\zip_mock.py" /> + <Compile Include="common\system\__init__.py" /> + <Compile Include="common\thread\messagepump.py" /> + <Compile Include="common\thread\messagepump_unittest.py" /> + <Compile Include="common\thread\threadedmessagequeue.py" /> + <Compile Include="common\thread\threadedmessagequeue_unittest.py" /> + <Compile Include="common\thread\__init__.py" /> + <Compile Include="common\version_check.py" /> + <Compile Include="common\watchlist\amountchangedpattern.py" /> + <Compile Include="common\watchlist\amountchangedpattern_unittest.py" /> + <Compile Include="common\watchlist\changedlinepattern.py" /> + <Compile Include="common\watchlist\changedlinepattern_unittest.py" /> + <Compile Include="common\watchlist\filenamepattern.py" /> + <Compile Include="common\watchlist\filenamepattern_unittest.py" /> + <Compile Include="common\watchlist\watchlist.py" /> + <Compile Include="common\watchlist\watchlistloader.py" /> + <Compile Include="common\watchlist\watchlistloader_unittest.py" /> + <Compile Include="common\watchlist\watchlistparser.py" /> + <Compile Include="common\watchlist\watchlistparser_unittest.py" /> + <Compile Include="common\watchlist\watchlistrule.py" /> + <Compile Include="common\watchlist\watchlistrule_unittest.py" /> + <Compile Include="common\watchlist\watchlist_mock.py" /> + <Compile Include="common\watchlist\watchlist_unittest.py" /> + <Compile Include="common\watchlist\__init__.py" /> + <Compile Include="common\webkitunittest.py" /> + <Compile Include="common\__init__.py" /> + <Compile Include="layout_tests\controllers\manager.py" /> + <Compile Include="layout_tests\controllers\manager_unittest.py" /> + <Compile Include="layout_tests\controllers\single_test_runner.py" /> + <Compile Include="layout_tests\controllers\test_expectations_editor.py" /> + <Compile Include="layout_tests\controllers\test_expectations_editor_unittest.py" /> + <Compile Include="layout_tests\controllers\test_result_writer.py" /> + <Compile Include="layout_tests\controllers\test_result_writer_unittest.py" /> + <Compile Include="layout_tests\controllers\worker.py" /> + <Compile Include="layout_tests\controllers\__init__.py" /> + <Compile Include="layout_tests\layout_package\json_layout_results_generator.py" /> + <Compile Include="layout_tests\layout_package\json_results_generator.py" /> + <Compile Include="layout_tests\layout_package\json_results_generator_unittest.py" /> + <Compile Include="layout_tests\layout_package\__init__.py" /> + <Compile Include="layout_tests\models\result_summary.py" /> + <Compile Include="layout_tests\models\test_configuration.py" /> + <Compile Include="layout_tests\models\test_configuration_unittest.py" /> + <Compile Include="layout_tests\models\test_expectations.py" /> + <Compile Include="layout_tests\models\test_expectations_unittest.py" /> + <Compile Include="layout_tests\models\test_failures.py" /> + <Compile Include="layout_tests\models\test_failures_unittest.py" /> + <Compile Include="layout_tests\models\test_input.py" /> + <Compile Include="layout_tests\models\test_results.py" /> + <Compile Include="layout_tests\models\test_results_unittest.py" /> + <Compile Include="layout_tests\models\__init__.py" /> + <Compile Include="layout_tests\port\apple.py" /> + <Compile Include="layout_tests\port\base.py" /> + <Compile Include="layout_tests\port\base_unittest.py" /> + <Compile Include="layout_tests\port\builders.py" /> + <Compile Include="layout_tests\port\builders_unittest.py" /> + <Compile Include="layout_tests\port\chromium.py" /> + <Compile Include="layout_tests\port\chromium_android.py" /> + <Compile Include="layout_tests\port\chromium_android_unittest.py" /> + <Compile Include="layout_tests\port\chromium_linux.py" /> + <Compile Include="layout_tests\port\chromium_linux_unittest.py" /> + <Compile Include="layout_tests\port\chromium_mac.py" /> + <Compile Include="layout_tests\port\chromium_mac_unittest.py" /> + <Compile Include="layout_tests\port\chromium_port_testcase.py" /> + <Compile Include="layout_tests\port\chromium_unittest.py" /> + <Compile Include="layout_tests\port\chromium_win.py" /> + <Compile Include="layout_tests\port\chromium_win_unittest.py" /> + <Compile Include="layout_tests\port\config.py" /> + <Compile Include="layout_tests\port\config_mock.py" /> + <Compile Include="layout_tests\port\config_standalone.py" /> + <Compile Include="layout_tests\port\config_unittest.py" /> + <Compile Include="layout_tests\port\driver.py" /> + <Compile Include="layout_tests\port\driver_unittest.py" /> + <Compile Include="layout_tests\port\efl.py" /> + <Compile Include="layout_tests\port\efl_unittest.py" /> + <Compile Include="layout_tests\port\factory.py" /> + <Compile Include="layout_tests\port\factory_unittest.py" /> + <Compile Include="layout_tests\port\gtk.py" /> + <Compile Include="layout_tests\port\gtk_unittest.py" /> + <Compile Include="layout_tests\port\http_lock.py" /> + <Compile Include="layout_tests\port\http_lock_unittest.py" /> + <Compile Include="layout_tests\port\leakdetector.py" /> + <Compile Include="layout_tests\port\leakdetector_unittest.py" /> + <Compile Include="layout_tests\port\mac.py" /> + <Compile Include="layout_tests\port\mac_unittest.py" /> + <Compile Include="layout_tests\port\mock_drt.py" /> + <Compile Include="layout_tests\port\mock_drt_unittest.py" /> + <Compile Include="layout_tests\port\port_testcase.py" /> + <Compile Include="layout_tests\port\pulseaudio_sanitizer.py" /> + <Compile Include="layout_tests\port\qt.py" /> + <Compile Include="layout_tests\port\qt_unittest.py" /> + <Compile Include="layout_tests\port\server_process.py" /> + <Compile Include="layout_tests\port\server_process_unittest.py" /> + <Compile Include="layout_tests\port\test.py" /> + <Compile Include="layout_tests\port\webkit.py" /> + <Compile Include="layout_tests\port\webkit_unittest.py" /> + <Compile Include="layout_tests\port\win.py" /> + <Compile Include="layout_tests\port\win_unittest.py" /> + <Compile Include="layout_tests\port\xvfbdriver.py" /> + <Compile Include="layout_tests\port\__init__.py" /> + <Compile Include="layout_tests\reftests\extract_reference_link.py" /> + <Compile Include="layout_tests\reftests\extract_reference_link_unittest.py" /> + <Compile Include="layout_tests\reftests\__init__.py" /> + <Compile Include="layout_tests\run_webkit_tests.py" /> + <Compile Include="layout_tests\run_webkit_tests_integrationtest.py" /> + <Compile Include="layout_tests\servers\apache_http_server.py" /> + <Compile Include="layout_tests\servers\apache_http_server_unittest.py" /> + <Compile Include="layout_tests\servers\http_server.py" /> + <Compile Include="layout_tests\servers\http_server_base.py" /> + <Compile Include="layout_tests\servers\http_server_integrationtest.py" /> + <Compile Include="layout_tests\servers\http_server_unittest.py" /> + <Compile Include="layout_tests\servers\websocket_server.py" /> + <Compile Include="layout_tests\servers\__init__.py" /> + <Compile Include="layout_tests\views\metered_stream.py" /> + <Compile Include="layout_tests\views\metered_stream_unittest.py" /> + <Compile Include="layout_tests\views\printing.py" /> + <Compile Include="layout_tests\views\printing_unittest.py" /> + <Compile Include="layout_tests\views\__init__.py" /> + <Compile Include="layout_tests\__init__.py" /> + <Compile Include="performance_tests\perftest.py" /> + <Compile Include="performance_tests\perftestsrunner.py" /> + <Compile Include="performance_tests\perftestsrunner_unittest.py" /> + <Compile Include="performance_tests\perftest_unittest.py" /> + <Compile Include="performance_tests\__init__.py" /> + <Compile Include="style\checker.py" /> + <Compile Include="style\checkers\changelog.py" /> + <Compile Include="style\checkers\changelog_unittest.py" /> + <Compile Include="style\checkers\common.py" /> + <Compile Include="style\checkers\common_unittest.py" /> + <Compile Include="style\checkers\cpp.py" /> + <Compile Include="style\checkers\cpp_unittest.py" /> + <Compile Include="style\checkers\jsonchecker.py" /> + <Compile Include="style\checkers\jsonchecker_unittest.py" /> + <Compile Include="style\checkers\png.py" /> + <Compile Include="style\checkers\png_unittest.py" /> + <Compile Include="style\checkers\python.py" /> + <Compile Include="style\checkers\python_unittest.py" /> + <Compile Include="style\checkers\python_unittest_input.py" /> + <Compile Include="style\checkers\test_expectations.py" /> + <Compile Include="style\checkers\test_expectations_unittest.py" /> + <Compile Include="style\checkers\text.py" /> + <Compile Include="style\checkers\text_unittest.py" /> + <Compile Include="style\checkers\watchlist.py" /> + <Compile Include="style\checkers\watchlist_unittest.py" /> + <Compile Include="style\checkers\xcodeproj.py" /> + <Compile Include="style\checkers\xcodeproj_unittest.py" /> + <Compile Include="style\checkers\xml.py" /> + <Compile Include="style\checkers\xml_unittest.py" /> + <Compile Include="style\checkers\__init__.py" /> + <Compile Include="style\checker_unittest.py" /> + <Compile Include="style\error_handlers.py" /> + <Compile Include="style\error_handlers_unittest.py" /> + <Compile Include="style\filereader.py" /> + <Compile Include="style\filereader_unittest.py" /> + <Compile Include="style\filter.py" /> + <Compile Include="style\filter_unittest.py" /> + <Compile Include="style\main.py" /> + <Compile Include="style\main_unittest.py" /> + <Compile Include="style\optparser.py" /> + <Compile Include="style\optparser_unittest.py" /> + <Compile Include="style\patchreader.py" /> + <Compile Include="style\patchreader_unittest.py" /> + <Compile Include="style\__init__.py" /> + <Compile Include="test\finder.py" /> + <Compile Include="test\finder_unittest.py" /> + <Compile Include="test\main.py" /> + <Compile Include="test\main_unittest.py" /> + <Compile Include="test\printer.py" /> + <Compile Include="test\runner.py" /> + <Compile Include="test\runner_unittest.py" /> + <Compile Include="test\skip.py" /> + <Compile Include="test\skip_unittest.py" /> + <Compile Include="test\__init__.py" /> + <Compile Include="thirdparty\BeautifulSoup.py" /> + <Compile Include="thirdparty\mock.py" /> + <Compile Include="thirdparty\mod_pywebsocket\common.py" /> + <Compile Include="thirdparty\mod_pywebsocket\dispatch.py" /> + <Compile Include="thirdparty\mod_pywebsocket\extensions.py" /> + <Compile Include="thirdparty\mod_pywebsocket\handshake\draft75.py" /> + <Compile Include="thirdparty\mod_pywebsocket\handshake\hybi.py" /> + <Compile Include="thirdparty\mod_pywebsocket\handshake\hybi00.py" /> + <Compile Include="thirdparty\mod_pywebsocket\handshake\_base.py" /> + <Compile Include="thirdparty\mod_pywebsocket\handshake\__init__.py" /> + <Compile Include="thirdparty\mod_pywebsocket\headerparserhandler.py" /> + <Compile Include="thirdparty\mod_pywebsocket\http_header_util.py" /> + <Compile Include="thirdparty\mod_pywebsocket\memorizingfile.py" /> + <Compile Include="thirdparty\mod_pywebsocket\msgutil.py" /> + <Compile Include="thirdparty\mod_pywebsocket\standalone.py" /> + <Compile Include="thirdparty\mod_pywebsocket\stream.py" /> + <Compile Include="thirdparty\mod_pywebsocket\util.py" /> + <Compile Include="thirdparty\mod_pywebsocket\_stream_base.py" /> + <Compile Include="thirdparty\mod_pywebsocket\_stream_hixie75.py" /> + <Compile Include="thirdparty\mod_pywebsocket\_stream_hybi.py" /> + <Compile Include="thirdparty\mod_pywebsocket\__init__.py" /> + <Compile Include="thirdparty\ordered_dict.py" /> + <Compile Include="thirdparty\__init__.py" /> + <Compile Include="thirdparty\__init___unittest.py" /> + <Compile Include="tool\bot\botinfo.py" /> + <Compile Include="tool\bot\botinfo_unittest.py" /> + <Compile Include="tool\bot\commitqueuetask.py" /> + <Compile Include="tool\bot\commitqueuetask_unittest.py" /> + <Compile Include="tool\bot\earlywarningsystemtask.py" /> + <Compile Include="tool\bot\expectedfailures.py" /> + <Compile Include="tool\bot\expectedfailures_unittest.py" /> + <Compile Include="tool\bot\feeders.py" /> + <Compile Include="tool\bot\feeders_unittest.py" /> + <Compile Include="tool\bot\flakytestreporter.py" /> + <Compile Include="tool\bot\flakytestreporter_unittest.py" /> + <Compile Include="tool\bot\irc_command.py" /> + <Compile Include="tool\bot\irc_command_unittest.py" /> + <Compile Include="tool\bot\layouttestresultsreader.py" /> + <Compile Include="tool\bot\layouttestresultsreader_unittest.py" /> + <Compile Include="tool\bot\patchanalysistask.py" /> + <Compile Include="tool\bot\queueengine.py" /> + <Compile Include="tool\bot\queueengine_unittest.py" /> + <Compile Include="tool\bot\sheriff.py" /> + <Compile Include="tool\bot\sheriffircbot.py" /> + <Compile Include="tool\bot\sheriffircbot_unittest.py" /> + <Compile Include="tool\bot\sheriff_unittest.py" /> + <Compile Include="tool\bot\stylequeuetask.py" /> + <Compile Include="tool\bot\__init__.py" /> + <Compile Include="tool\commands\abstractlocalservercommand.py" /> + <Compile Include="tool\commands\abstractsequencedcommand.py" /> + <Compile Include="tool\commands\adduserstogroups.py" /> + <Compile Include="tool\commands\analyzechangelog.py" /> + <Compile Include="tool\commands\analyzechangelog_unittest.py" /> + <Compile Include="tool\commands\applywatchlistlocal.py" /> + <Compile Include="tool\commands\applywatchlistlocal_unittest.py" /> + <Compile Include="tool\commands\bugfortest.py" /> + <Compile Include="tool\commands\bugsearch.py" /> + <Compile Include="tool\commands\chromechannels.py" /> + <Compile Include="tool\commands\chromechannels_unittest.py" /> + <Compile Include="tool\commands\commandtest.py" /> + <Compile Include="tool\commands\download.py" /> + <Compile Include="tool\commands\download_unittest.py" /> + <Compile Include="tool\commands\earlywarningsystem.py" /> + <Compile Include="tool\commands\earlywarningsystem_unittest.py" /> + <Compile Include="tool\commands\expectations.py" /> + <Compile Include="tool\commands\findusers.py" /> + <Compile Include="tool\commands\gardenomatic.py" /> + <Compile Include="tool\commands\openbugs.py" /> + <Compile Include="tool\commands\openbugs_unittest.py" /> + <Compile Include="tool\commands\prettydiff.py" /> + <Compile Include="tool\commands\queries.py" /> + <Compile Include="tool\commands\queries_unittest.py" /> + <Compile Include="tool\commands\queues.py" /> + <Compile Include="tool\commands\queuestest.py" /> + <Compile Include="tool\commands\queues_unittest.py" /> + <Compile Include="tool\commands\rebaseline.py" /> + <Compile Include="tool\commands\rebaselineserver.py" /> + <Compile Include="tool\commands\rebaseline_unittest.py" /> + <Compile Include="tool\commands\roll.py" /> + <Compile Include="tool\commands\roll_unittest.py" /> + <Compile Include="tool\commands\sheriffbot.py" /> + <Compile Include="tool\commands\sheriffbot_unittest.py" /> + <Compile Include="tool\commands\stepsequence.py" /> + <Compile Include="tool\commands\suggestnominations.py" /> + <Compile Include="tool\commands\suggestnominations_unittest.py" /> + <Compile Include="tool\commands\upload.py" /> + <Compile Include="tool\commands\upload_unittest.py" /> + <Compile Include="tool\commands\__init__.py" /> + <Compile Include="tool\comments.py" /> + <Compile Include="tool\grammar.py" /> + <Compile Include="tool\grammar_unittest.py" /> + <Compile Include="tool\main.py" /> + <Compile Include="tool\mocktool.py" /> + <Compile Include="tool\mocktool_unittest.py" /> + <Compile Include="tool\multicommandtool.py" /> + <Compile Include="tool\multicommandtool_unittest.py" /> + <Compile Include="tool\servers\gardeningserver.py" /> + <Compile Include="tool\servers\gardeningserver_unittest.py" /> + <Compile Include="tool\servers\rebaselineserver.py" /> + <Compile Include="tool\servers\rebaselineserver_unittest.py" /> + <Compile Include="tool\servers\reflectionhandler.py" /> + <Compile Include="tool\servers\__init__.py" /> + <Compile Include="tool\steps\abstractstep.py" /> + <Compile Include="tool\steps\addsvnmimetypeforpng.py" /> + <Compile Include="tool\steps\addsvnmimetypeforpng_unittest.py" /> + <Compile Include="tool\steps\applypatch.py" /> + <Compile Include="tool\steps\applypatchwithlocalcommit.py" /> + <Compile Include="tool\steps\applywatchlist.py" /> + <Compile Include="tool\steps\applywatchlist_unittest.py" /> + <Compile Include="tool\steps\attachtobug.py" /> + <Compile Include="tool\steps\build.py" /> + <Compile Include="tool\steps\checkstyle.py" /> + <Compile Include="tool\steps\cleanworkingdirectory.py" /> + <Compile Include="tool\steps\cleanworkingdirectorywithlocalcommits.py" /> + <Compile Include="tool\steps\cleanworkingdirectory_unittest.py" /> + <Compile Include="tool\steps\closebug.py" /> + <Compile Include="tool\steps\closebugforlanddiff.py" /> + <Compile Include="tool\steps\closebugforlanddiff_unittest.py" /> + <Compile Include="tool\steps\closepatch.py" /> + <Compile Include="tool\steps\commit.py" /> + <Compile Include="tool\steps\commit_unittest.py" /> + <Compile Include="tool\steps\confirmdiff.py" /> + <Compile Include="tool\steps\createbug.py" /> + <Compile Include="tool\steps\editchangelog.py" /> + <Compile Include="tool\steps\ensurebugisopenandassigned.py" /> + <Compile Include="tool\steps\ensurelocalcommitifneeded.py" /> + <Compile Include="tool\steps\metastep.py" /> + <Compile Include="tool\steps\obsoletepatches.py" /> + <Compile Include="tool\steps\options.py" /> + <Compile Include="tool\steps\postdiff.py" /> + <Compile Include="tool\steps\postdiffforcommit.py" /> + <Compile Include="tool\steps\postdiffforrevert.py" /> + <Compile Include="tool\steps\preparechangelog.py" /> + <Compile Include="tool\steps\preparechangelogfordepsroll.py" /> + <Compile Include="tool\steps\preparechangelogforrevert.py" /> + <Compile Include="tool\steps\preparechangelogforrevert_unittest.py" /> + <Compile Include="tool\steps\preparechangelog_unittest.py" /> + <Compile Include="tool\steps\promptforbugortitle.py" /> + <Compile Include="tool\steps\reopenbugafterrollout.py" /> + <Compile Include="tool\steps\revertrevision.py" /> + <Compile Include="tool\steps\runtests.py" /> + <Compile Include="tool\steps\runtests_unittest.py" /> + <Compile Include="tool\steps\steps_unittest.py" /> + <Compile Include="tool\steps\suggestreviewers.py" /> + <Compile Include="tool\steps\suggestreviewers_unittest.py" /> + <Compile Include="tool\steps\update.py" /> + <Compile Include="tool\steps\updatechangelogswithreviewer.py" /> + <Compile Include="tool\steps\updatechangelogswithreview_unittest.py" /> + <Compile Include="tool\steps\updatechromiumdeps.py" /> + <Compile Include="tool\steps\update_unittest.py" /> + <Compile Include="tool\steps\validatechangelogs.py" /> + <Compile Include="tool\steps\validatechangelogs_unittest.py" /> + <Compile Include="tool\steps\validatereviewer.py" /> + <Compile Include="tool\steps\__init__.py" /> + <Compile Include="tool\__init__.py" /> + <Compile Include="to_be_moved\update_webgl_conformance_tests.py" /> + <Compile Include="to_be_moved\update_webgl_conformance_tests_unittest.py" /> + <Compile Include="to_be_moved\__init__.py" /> + <Compile Include="__init__.py" /> + </ItemGroup> + <ItemGroup> + <Folder Include="bindings\" /> + <Folder Include="common\" /> + <Folder Include="common\checkout\" /> + <Folder Include="common\checkout\scm\" /> + <Folder Include="common\config\" /> + <Folder Include="common\net\" /> + <Folder Include="common\net\bugzilla\" /> + <Folder Include="common\net\buildbot\" /> + <Folder Include="common\net\irc\" /> + <Folder Include="common\system\" /> + <Folder Include="common\thread\" /> + <Folder Include="common\watchlist\" /> + <Folder Include="layout_tests\" /> + <Folder Include="layout_tests\controllers\" /> + <Folder Include="layout_tests\layout_package\" /> + <Folder Include="layout_tests\models\" /> + <Folder Include="layout_tests\port\" /> + <Folder Include="layout_tests\reftests\" /> + <Folder Include="layout_tests\servers\" /> + <Folder Include="layout_tests\views\" /> + <Folder Include="performance_tests\" /> + <Folder Include="style\" /> + <Folder Include="style\checkers\" /> + <Folder Include="test\" /> + <Folder Include="thirdparty\" /> + <Folder Include="thirdparty\mod_pywebsocket\" /> + <Folder Include="thirdparty\mod_pywebsocket\handshake\" /> + <Folder Include="tool\" /> + <Folder Include="tool\bot\" /> + <Folder Include="tool\commands\" /> + <Folder Include="tool\servers\" /> + <Folder Include="tool\steps\" /> + <Folder Include="to_be_moved\" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" /> +</Project>
\ No newline at end of file diff --git a/Tools/Scripts/webkitpy/webkitpy.sln b/Tools/Scripts/webkitpy/webkitpy.sln new file mode 100644 index 000000000..7648387b8 --- /dev/null +++ b/Tools/Scripts/webkitpy/webkitpy.sln @@ -0,0 +1,18 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "webkitpy", "webkitpy.pyproj", "{59B0A791-93FE-40F8-A52B-BA19B73E8FA6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {59B0A791-93FE-40F8-A52B-BA19B73E8FA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {59B0A791-93FE-40F8-A52B-BA19B73E8FA6}.Release|Any CPU.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj index 50045f3bb..26384e3bb 100644 --- a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj +++ b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj @@ -79,6 +79,8 @@ 9B26FCCA159D16DE00CC3765 /* HTMLFormCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B26FCB4159D15E700CC3765 /* HTMLFormCollectionNamedItem.html */; }; 9B4F8FA4159D52B1002D9F94 /* HTMLCollectionNamedItem.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9B4F8FA3159D52B1002D9F94 /* HTMLCollectionNamedItem.mm */; }; 9B4F8FA7159D52DD002D9F94 /* HTMLCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */; }; + A5E2027315B2181900C13E14 /* WindowlessWebViewWithMedia.mm in Sources */ = {isa = PBXBuildFile; fileRef = A5E2027215B2181900C13E14 /* WindowlessWebViewWithMedia.mm */; }; + A5E2027515B21F6E00C13E14 /* WindowlessWebViewWithMedia.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = A5E2027015B2180600C13E14 /* WindowlessWebViewWithMedia.html */; }; A7A966DB140ECCC8005EF9B4 /* CheckedArithmeticOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7A966DA140ECCC8005EF9B4 /* CheckedArithmeticOperations.cpp */; }; B55F11A01516834F00915916 /* AttributedString.mm in Sources */ = {isa = PBXBuildFile; fileRef = B55F119F1516834F00915916 /* AttributedString.mm */; }; B55F11B71517D03300915916 /* attributedStringCustomFont.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = B55F11B01517A2C400915916 /* attributedStringCustomFont.html */; }; @@ -203,6 +205,7 @@ 9B26FCCA159D16DE00CC3765 /* HTMLFormCollectionNamedItem.html in Copy Resources */, E1220DCA155B28AA0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html in Copy Resources */, 517E7E04151119C100D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.html in Copy Resources */, + A5E2027515B21F6E00C13E14 /* WindowlessWebViewWithMedia.html in Copy Resources */, 379028B914FAC24C007E6B43 /* acceptsFirstMouse.html in Copy Resources */, 33DC8912141955FE00747EF7 /* simple-iframe.html in Copy Resources */, 1A9E52C913E65EF4006917F5 /* 18-characters.html in Copy Resources */, @@ -302,6 +305,8 @@ 9B26FCB4159D15E700CC3765 /* HTMLFormCollectionNamedItem.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = HTMLFormCollectionNamedItem.html; sourceTree = "<group>"; }; 9B4F8FA3159D52B1002D9F94 /* HTMLCollectionNamedItem.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HTMLCollectionNamedItem.mm; sourceTree = "<group>"; }; 9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = HTMLCollectionNamedItem.html; sourceTree = "<group>"; }; + A5E2027015B2180600C13E14 /* WindowlessWebViewWithMedia.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = WindowlessWebViewWithMedia.html; sourceTree = "<group>"; }; + A5E2027215B2181900C13E14 /* WindowlessWebViewWithMedia.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WindowlessWebViewWithMedia.mm; sourceTree = "<group>"; }; A7A966DA140ECCC8005EF9B4 /* CheckedArithmeticOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CheckedArithmeticOperations.cpp; path = WTF/CheckedArithmeticOperations.cpp; sourceTree = "<group>"; }; B55F119F1516834F00915916 /* AttributedString.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AttributedString.mm; sourceTree = "<group>"; }; B55F11B01517A2C400915916 /* attributedStringCustomFont.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = attributedStringCustomFont.html; sourceTree = "<group>"; }; @@ -704,6 +709,7 @@ 37A6895D148A9B50005100FA /* SubresourceErrorCrash.mm */, E490296714E2E3A4002BEDD1 /* TypingStyleCrash.mm */, 51FBBB4C1513D4E900822738 /* WebViewCanPasteURL.mm */, + A5E2027215B2181900C13E14 /* WindowlessWebViewWithMedia.mm */, ); path = mac; sourceTree = "<group>"; @@ -724,6 +730,7 @@ 517E7E031511187500D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.html */, C07E6CB113FD738A0038B22B /* devicePixelRatio.html */, C540F783152E5A7800A40C8C /* verboseMarkup.html */, + A5E2027015B2180600C13E14 /* WindowlessWebViewWithMedia.html */, ); name = Resources; sourceTree = "<group>"; @@ -937,6 +944,7 @@ F660AA1315A619C9003A1243 /* InjectedBundleInitializationUserDataCallbackWins.cpp in Sources */, 0F17BBD615AF6C4D007AB753 /* WebCoreStatisticsWithNoWebProcess.cpp in Sources */, 261516D615B0E60500A2C201 /* SetAndUpdateCacheModel.mm in Sources */, + A5E2027315B2181900C13E14 /* WindowlessWebViewWithMedia.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Tools/TestWebKitAPI/Tests/mac/WindowlessWebViewWithMedia.html b/Tools/TestWebKitAPI/Tests/mac/WindowlessWebViewWithMedia.html new file mode 100644 index 000000000..db064fb05 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/mac/WindowlessWebViewWithMedia.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<body> + We want to make sure the page sends its onload event even if it has media in a windowless WebView. + <audio src="invalid.mp3"></audio> + <script> + var didTriggerLoad = false; + window.addEventListener('load', function(event) { + didTriggerLoad = true; + }, false); + </script> +</body> +</html> diff --git a/Tools/TestWebKitAPI/Tests/mac/WindowlessWebViewWithMedia.mm b/Tools/TestWebKitAPI/Tests/mac/WindowlessWebViewWithMedia.mm new file mode 100644 index 000000000..bf593e6ef --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/mac/WindowlessWebViewWithMedia.mm @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JavaScriptTest.h" +#include "PlatformUtilities.h" +#include <wtf/RetainPtr.h> + + +static bool didFinishLoad; + +@interface WindowlessWebViewWithMediaFrameLoadDelegate : NSObject +@end + +@implementation WindowlessWebViewWithMediaFrameLoadDelegate + +- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame +{ + didFinishLoad = true; +} + +@end + + +namespace TestWebKitAPI { + +static void spinLoop(NSTimeInterval timeout, BOOL (^block)()) +{ + if (timeout <= 0) + return; + + NSTimeInterval end = [[NSDate date] timeIntervalSinceReferenceDate] + timeout; + NSDate *endDate = [NSDate dateWithTimeIntervalSinceReferenceDate:end]; + + while (!block()) { + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:endDate]; + if ([[NSDate date] timeIntervalSinceReferenceDate] > end) + break; + } +} + +TEST(WebKit1, WindowlessWebViewWithMedia) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + RetainPtr<WebView> webView(AdoptNS, [[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); + RetainPtr<WindowlessWebViewWithMediaFrameLoadDelegate> testController(AdoptNS, [WindowlessWebViewWithMediaFrameLoadDelegate new]); + webView.get().frameLoadDelegate = testController.get(); + [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"WindowlessWebViewWithMedia" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; + + EXPECT_EQ(nil, [webView.get() window]); + + Util::run(&didFinishLoad); + + spinLoop(0.25, ^{ + return [[webView.get() stringByEvaluatingJavaScriptFromString:@"window.didTriggerLoad"] isEqualToString:@"true"]; + }); + + EXPECT_JS_EQ(webView.get(), "window.didTriggerLoad", "true"); + + [pool drain]; +} + +} // namespace TestWebKitAPI diff --git a/Tools/Tools.pro b/Tools/Tools.pro index 68922d2bf..6cb07d899 100644 --- a/Tools/Tools.pro +++ b/Tools/Tools.pro @@ -21,13 +21,8 @@ CONFIG += ordered SUBDIRS += MiniBrowser/qt/raw/MiniBrowserRaw.pro } -# FIXME: with Qt 5 the test plugin cause some trouble during layout tests. -# See: https://bugs.webkit.org/show_bug.cgi?id=86620 -# Reenable it after we have a fix for this issue. -!haveQt(5) { - !win32:contains(DEFINES, ENABLE_NETSCAPE_PLUGIN_API=1) { - SUBDIRS += DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro - } +!win32:contains(DEFINES, ENABLE_NETSCAPE_PLUGIN_API=1) { + SUBDIRS += DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro } OTHER_FILES = \ diff --git a/Tools/WebKitTestRunner/GNUmakefile.am b/Tools/WebKitTestRunner/GNUmakefile.am index 546961331..a255f67e3 100644 --- a/Tools/WebKitTestRunner/GNUmakefile.am +++ b/Tools/WebKitTestRunner/GNUmakefile.am @@ -94,6 +94,7 @@ Libraries_libTestRunnerInjectedBundle_la_SOURCES = \ Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h \ Tools/WebKitTestRunner/InjectedBundle/GCController.cpp \ Tools/WebKitTestRunner/InjectedBundle/GCController.h \ + Tools/WebKitTestRunner/InjectedBundle/gtk/AccessibilityUIElementGtk.cpp \ Tools/WebKitTestRunner/InjectedBundle/gtk/ActivateFontsGtk.cpp \ Tools/WebKitTestRunner/InjectedBundle/gtk/InjectedBundleGtk.cpp \ Tools/WebKitTestRunner/InjectedBundle/gtk/LayoutTestControllerGtk.cpp \ diff --git a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp index 7c06237ee..42e25711c 100644 --- a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp +++ b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp @@ -54,7 +54,7 @@ bool AccessibilityUIElement::isValid() const } // Unsupported methods on various platforms. As they're implemented on other platforms this list should be modified. -#if !PLATFORM(MAC) +#if !PLATFORM(MAC) && !PLATFORM(GTK) AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement) { } AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement&) { } AccessibilityUIElement::~AccessibilityUIElement() { } diff --git a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h index 697918f33..551f59174 100644 --- a/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h +++ b/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h @@ -243,6 +243,9 @@ private: void getLinkedUIElements(Vector<RefPtr<AccessibilityUIElement> >&); void getDocumentLinks(Vector<RefPtr<AccessibilityUIElement> >&); +#endif + +#if PLATFORM(MAC) || PLATFORM(GTK) void getChildren(Vector<RefPtr<AccessibilityUIElement> >&); void getChildrenWithRange(Vector<RefPtr<AccessibilityUIElement> >&, unsigned location, unsigned length); #endif diff --git a/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl b/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl index a1e8a062c..312a1e328 100644 --- a/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl +++ b/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl @@ -28,6 +28,10 @@ module WTR { interface AccessibilityUIElement { boolean isEqual(in AccessibilityUIElement otherElement); + // Document information + readonly attribute DOMString documentEncoding; + readonly attribute DOMString documentURI; + // Element access. AccessibilityUIElement elementAtPoint(in int x, in int y); AccessibilityUIElement childAtIndex(in unsigned long index); diff --git a/Tools/WebKitTestRunner/InjectedBundle/gtk/AccessibilityUIElementGtk.cpp b/Tools/WebKitTestRunner/InjectedBundle/gtk/AccessibilityUIElementGtk.cpp new file mode 100644 index 000000000..e83b784b2 --- /dev/null +++ b/Tools/WebKitTestRunner/InjectedBundle/gtk/AccessibilityUIElementGtk.cpp @@ -0,0 +1,971 @@ +/* + * Copyright (C) 2011 Apple Inc. All Rights Reserved. + * Copyright (C) 2012 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "AccessibilityUIElement.h" + +#include "InjectedBundle.h" +#include "InjectedBundlePage.h" +#include <JavaScriptCore/JSStringRef.h> +#include <atk/atk.h> +#include <gtk/gtk.h> +#include <wtf/Assertions.h> +#include <wtf/gobject/GOwnPtr.h> +#include <wtf/gobject/GRefPtr.h> + +namespace WTR { + +static gchar* attributeSetToString(AtkAttributeSet* attributeSet) +{ + GString* str = g_string_new(0); + for (GSList* attributes = attributeSet; attributes; attributes = attributes->next) { + AtkAttribute* attribute = static_cast<AtkAttribute*>(attributes->data); + GOwnPtr<gchar> attributeData(g_strconcat(attribute->name, ":", attribute->value, NULL)); + g_string_append(str, attributeData.get()); + if (attributes->next) + g_string_append(str, ", "); + } + + return g_string_free(str, FALSE); +} + +static bool checkElementState(PlatformUIElement element, AtkStateType stateType) +{ + if (!ATK_IS_OBJECT(element)) + return false; + + GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(element))); + return atk_state_set_contains_state(stateSet.get(), stateType); +} + +static JSStringRef indexRangeInTable(PlatformUIElement element, bool isRowRange) +{ + GOwnPtr<gchar> rangeString(g_strdup("{0, 0}")); + + if (!element || !ATK_IS_OBJECT(element)) + return JSStringCreateWithUTF8CString(rangeString.get()); + + AtkObject* axTable = atk_object_get_parent(ATK_OBJECT(element)); + if (!axTable || !ATK_IS_TABLE(axTable)) + return JSStringCreateWithUTF8CString(rangeString.get()); + + // Look for the cell in the table. + gint indexInParent = atk_object_get_index_in_parent(ATK_OBJECT(element)); + if (indexInParent == -1) + return JSStringCreateWithUTF8CString(rangeString.get()); + + int row = -1; + int column = -1; + row = atk_table_get_row_at_index(ATK_TABLE(axTable), indexInParent); + column = atk_table_get_column_at_index(ATK_TABLE(axTable), indexInParent); + + // Get the actual values, if row and columns are valid values. + if (row != -1 && column != -1) { + int base = 0; + int length = 0; + if (isRowRange) { + base = row; + length = atk_table_get_row_extent_at(ATK_TABLE(axTable), row, column); + } else { + base = column; + length = atk_table_get_column_extent_at(ATK_TABLE(axTable), row, column); + } + rangeString.set(g_strdup_printf("{%d, %d}", base, length)); + } + + return JSStringCreateWithUTF8CString(rangeString.get()); +} + +static void alterCurrentValue(PlatformUIElement element, int factor) +{ + if (!element || !ATK_IS_VALUE(element)) + return; + + GValue currentValue = G_VALUE_INIT; + atk_value_get_current_value(ATK_VALUE(element), ¤tValue); + + GValue increment = G_VALUE_INIT; + atk_value_get_minimum_increment(ATK_VALUE(element), &increment); + + GValue newValue = G_VALUE_INIT; + g_value_init(&newValue, G_TYPE_DOUBLE); + + g_value_set_float(&newValue, g_value_get_float(¤tValue) + factor * g_value_get_float(&increment)); + atk_value_set_current_value(ATK_VALUE(element), &newValue); + + g_value_unset(&newValue); + g_value_unset(&increment); + g_value_unset(¤tValue); +} + +AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element) + : m_element(element) +{ +} + +AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other) + : JSWrappable() + , m_element(other.m_element) +{ +} + +AccessibilityUIElement::~AccessibilityUIElement() +{ +} + +bool AccessibilityUIElement::isEqual(AccessibilityUIElement* otherElement) +{ + return m_element == otherElement->platformUIElement(); +} + +void AccessibilityUIElement::getChildren(Vector<RefPtr<AccessibilityUIElement> >& children) +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return; + + int count = childrenCount(); + for (int i = 0; i < count; i++) { + AtkObject* child = atk_object_ref_accessible_child(ATK_OBJECT(m_element), i); + children.append(AccessibilityUIElement::create(child)); + } +} + +void AccessibilityUIElement::getChildrenWithRange(Vector<RefPtr<AccessibilityUIElement> >& children, unsigned location, unsigned length) +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return; + unsigned end = location + length; + for (unsigned i = location; i < end; i++) { + AtkObject* child = atk_object_ref_accessible_child(ATK_OBJECT(m_element), i); + children.append(AccessibilityUIElement::create(child)); + } +} + +int AccessibilityUIElement::childrenCount() +{ + Vector<RefPtr<AccessibilityUIElement> > children; + getChildren(children); + return children.size(); +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::elementAtPoint(int x, int y) +{ + // FIXME: implement + return 0; +} + +unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element) +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return 0; + + Vector<RefPtr<AccessibilityUIElement> > children; + getChildren(children); + + unsigned count = children.size(); + for (unsigned i = 0; i < count; i++) + if (children[i]->isEqual(element)) + return i; + + return 0; +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::childAtIndex(unsigned index) +{ + Vector<RefPtr<AccessibilityUIElement> > children; + getChildrenWithRange(children, index, 1); + + if (children.size() == 1) + return children[0]; + + return 0; +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::linkedUIElementAtIndex(unsigned index) +{ + // FIXME: implement + return 0; +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index) +{ + // FIXME: implement + return 0; +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index) +{ + // FIXME: implement + return 0; +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedRowAtIndex(unsigned index) +{ + // FIXME: implement + return 0; +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::rowAtIndex(unsigned index) +{ + // FIXME: implement + return 0; +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedChildAtIndex(unsigned index) const +{ + // FIXME: implement + return 0; +} + +unsigned AccessibilityUIElement::selectedChildrenCount() const +{ + // FIXME: implement + return 0; +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedRowAtIndex(unsigned index) +{ + // FIXME: implement + return 0; +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::titleUIElement() +{ + // FIXME: implement + return 0; +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::parentElement() +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return 0; + + AtkObject* parent = atk_object_get_parent(ATK_OBJECT(m_element)); + return parent ? AccessibilityUIElement::create(parent) : 0; +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedByRow() +{ + // FIXME: implement + return 0; +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfLinkedUIElements() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfDocumentLinks() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfChildren() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::allAttributes() +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return JSStringCreateWithCharacters(0, 0); + + GOwnPtr<gchar> attributeData(attributeSetToString(atk_object_get_attributes(ATK_OBJECT(m_element)))); + return JSStringCreateWithUTF8CString(attributeData.get()); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::stringAttributeValue(JSStringRef attribute) +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +double AccessibilityUIElement::numberAttributeValue(JSStringRef attribute) +{ + // FIXME: implement + return 0.0f; +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementAttributeValue(JSStringRef attribute) const +{ + // FIXME: implement + return 0; +} + +bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute) +{ + // FIXME: implement + return false; +} + +bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute) +{ + // FIXME: implement + return false; +} + +bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute) +{ + // FIXME: implement + return false; +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::parameterizedAttributeNames() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::role() +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return JSStringCreateWithCharacters(0, 0); + + AtkRole role = atk_object_get_role(ATK_OBJECT(m_element)); + if (!role) + return JSStringCreateWithCharacters(0, 0); + + const gchar* roleName = atk_role_get_name(role); + GOwnPtr<gchar> axRole(g_strdup_printf("AXRole: %s", roleName)); + + return JSStringCreateWithUTF8CString(axRole.get()); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::subrole() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::roleDescription() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::title() +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return JSStringCreateWithCharacters(0, 0); + + const gchar* name = atk_object_get_name(ATK_OBJECT(m_element)); + if (!name) + return JSStringCreateWithCharacters(0, 0); + + GOwnPtr<gchar> axTitle(g_strdup_printf("AXTitle: %s", name)); + + return JSStringCreateWithUTF8CString(axTitle.get()); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::description() +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return JSStringCreateWithCharacters(0, 0); + + const gchar* description = atk_object_get_description(ATK_OBJECT(m_element)); + if (!description) + return JSStringCreateWithCharacters(0, 0); + + GOwnPtr<gchar> axDesc(g_strdup_printf("AXDescription: %s", description)); + + return JSStringCreateWithUTF8CString(axDesc.get()); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::orientation() const +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::stringValue() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::language() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::helpText() const +{ + // FIXME: implement + // We need a way to call WebCore::AccessibilityObject::helpText() + // from here, probably a new helper class in WebProcess/WebCoreSupport. + return JSStringCreateWithCharacters(0, 0); +} + +double AccessibilityUIElement::x() +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return 0.0f; + + int x, y; + atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_SCREEN); + return x; +} + +double AccessibilityUIElement::y() +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return 0.0f; + + int x, y; + atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_SCREEN); + return y; +} + +double AccessibilityUIElement::width() +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return 0.0f; + + int width, height; + atk_component_get_size(ATK_COMPONENT(m_element), &width, &height); + return width; +} + +double AccessibilityUIElement::height() +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return 0.0f; + + int width, height; + atk_component_get_size(ATK_COMPONENT(m_element), &width, &height); + return height; +} + +double AccessibilityUIElement::clickPointX() +{ + // FIXME: implement + return 0.0f; +} + +double AccessibilityUIElement::clickPointY() +{ + // FIXME: implement + return 0.0f; +} + +double AccessibilityUIElement::intValue() const +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return 0.0f; + + GValue value = G_VALUE_INIT; + atk_value_get_current_value(ATK_VALUE(m_element), &value); + if (!G_VALUE_HOLDS_FLOAT(&value)) + return 0.0f; + + return g_value_get_float(&value); +} + +double AccessibilityUIElement::minValue() +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return 0.0f; + + GValue value = G_VALUE_INIT; + atk_value_get_minimum_value(ATK_VALUE(m_element), &value); + if (!G_VALUE_HOLDS_FLOAT(&value)) + return 0.0f; + + return g_value_get_float(&value); +} + +double AccessibilityUIElement::maxValue() +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return 0.0f; + + GValue value = G_VALUE_INIT; + atk_value_get_maximum_value(ATK_VALUE(m_element), &value); + if (!G_VALUE_HOLDS_FLOAT(&value)) + return 0.0f; + + return g_value_get_float(&value); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::valueDescription() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +int AccessibilityUIElement::insertionPointLineNumber() +{ + // FIXME: implement + return -1; +} + +bool AccessibilityUIElement::isActionSupported(JSStringRef action) +{ + // FIXME: implement + return false; +} + +bool AccessibilityUIElement::isEnabled() +{ + return checkElementState(m_element, ATK_STATE_ENABLED); +} + +bool AccessibilityUIElement::isRequired() const +{ + // FIXME: implement + return false; +} + +bool AccessibilityUIElement::isFocused() const +{ + return checkElementState(m_element, ATK_STATE_FOCUSED); +} + +bool AccessibilityUIElement::isSelected() const +{ + return checkElementState(m_element, ATK_STATE_SELECTED); +} + +bool AccessibilityUIElement::isExpanded() const +{ + return checkElementState(m_element, ATK_STATE_EXPANDED); +} + +bool AccessibilityUIElement::isChecked() const +{ + return checkElementState(m_element, ATK_STATE_CHECKED); +} + +int AccessibilityUIElement::hierarchicalLevel() const +{ + // FIXME: implement + return 0; +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::speak() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +bool AccessibilityUIElement::ariaIsGrabbed() const +{ + // FIXME: implement + return false; +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::ariaDropEffects() const +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +// parameterized attributes +int AccessibilityUIElement::lineForIndex(int index) +{ + // FIXME: implement + return 0; +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForLine(int line) +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForPosition(int x, int y) +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::boundsForRange(unsigned location, unsigned length) +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForRange(unsigned location, unsigned length) +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForRange(unsigned location, unsigned length) +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location, unsigned length) +{ + // FIXME: implement + return false; +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(AccessibilityUIElement* startElement, bool isDirectionNext, JSStringRef searchKey, JSStringRef searchText) +{ + // FIXME: implement + return 0; +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumnHeaders() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRowHeaders() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumns() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRows() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfVisibleCells() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfHeader() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +int AccessibilityUIElement::rowCount() +{ + if (!m_element || !ATK_IS_TABLE(m_element)) + return 0; + + return atk_table_get_n_rows(ATK_TABLE(m_element)); +} + +int AccessibilityUIElement::columnCount() +{ + if (!m_element || !ATK_IS_TABLE(m_element)) + return 0; + + return atk_table_get_n_columns(ATK_TABLE(m_element)); +} + +int AccessibilityUIElement::indexInTable() +{ + // FIXME: implement + return -1; +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::rowIndexRange() +{ + // Range in table for rows. + return indexRangeInTable(m_element, true); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::columnIndexRange() +{ + // Range in table for columns. + return indexRangeInTable(m_element, false); +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row) +{ + if (!m_element || !ATK_IS_TABLE(m_element)) + return 0; + + AtkObject* foundCell = atk_table_ref_at(ATK_TABLE(m_element), row, col); + return foundCell ? AccessibilityUIElement::create(foundCell) : 0; +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::horizontalScrollbar() const +{ + // FIXME: implement + return 0; +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::verticalScrollbar() const +{ + // FIXME: implement + return 0; +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::selectedTextRange() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length) +{ + // FIXME: implement +} + +void AccessibilityUIElement::increment() +{ + alterCurrentValue(m_element, 1); +} + +void AccessibilityUIElement::decrement() +{ + alterCurrentValue(m_element, -1); +} + +void AccessibilityUIElement::showMenu() +{ + // FIXME: implement +} + +void AccessibilityUIElement::press() +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return; + + if (!ATK_IS_ACTION(m_element)) + return; + + // Only one action per object is supported so far. + atk_action_do_action(ATK_ACTION(m_element), 0); +} + +void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement* element) const +{ + // FIXME: implement +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::accessibilityValue() const +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::documentEncoding() +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return JSStringCreateWithCharacters(0, 0); + + AtkRole role = atk_object_get_role(ATK_OBJECT(m_element)); + if (role != ATK_ROLE_DOCUMENT_FRAME) + return JSStringCreateWithCharacters(0, 0); + + return JSStringCreateWithUTF8CString(atk_document_get_attribute_value(ATK_DOCUMENT(m_element), "Encoding")); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::documentURI() +{ + if (!m_element || !ATK_IS_OBJECT(m_element)) + return JSStringCreateWithCharacters(0, 0); + + AtkRole role = atk_object_get_role(ATK_OBJECT(m_element)); + if (role != ATK_ROLE_DOCUMENT_FRAME) + return JSStringCreateWithCharacters(0, 0); + + return JSStringCreateWithUTF8CString(atk_document_get_attribute_value(ATK_DOCUMENT(m_element), "URI")); +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::url() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +bool AccessibilityUIElement::addNotificationListener(JSValueRef functionCallback) +{ + // FIXME: implement + return true; +} + +bool AccessibilityUIElement::removeNotificationListener() +{ + // FIXME: implement + return true; +} + +bool AccessibilityUIElement::isFocusable() const +{ + return checkElementState(m_element, ATK_STATE_FOCUSABLE); +} + +bool AccessibilityUIElement::isSelectable() const +{ + return checkElementState(m_element, ATK_STATE_SELECTABLE); +} + +bool AccessibilityUIElement::isMultiSelectable() const +{ + return checkElementState(m_element, ATK_STATE_MULTISELECTABLE); +} + +bool AccessibilityUIElement::isVisible() const +{ + return checkElementState(m_element, ATK_STATE_VISIBLE); +} + +bool AccessibilityUIElement::isOffScreen() const +{ + // FIXME: implement + return false; +} + +bool AccessibilityUIElement::isCollapsed() const +{ + // FIXME: implement + return false; +} + +bool AccessibilityUIElement::isIgnored() const +{ + // FIXME: implement + return false; +} + +bool AccessibilityUIElement::hasPopup() const +{ + // FIXME: implement + return false; +} + +void AccessibilityUIElement::takeFocus() +{ + // FIXME: implement +} + +void AccessibilityUIElement::takeSelection() +{ + // FIXME: implement +} + +void AccessibilityUIElement::addSelection() +{ + // FIXME: implement +} + +void AccessibilityUIElement::removeSelection() +{ + // FIXME: implement +} + +// Text markers +PassRefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement* element) +{ + // FIXME: implement + return 0; +} + +int AccessibilityUIElement::textMarkerRangeLength(AccessibilityTextMarkerRange* range) +{ + // FIXME: implement + return 0; +} + +PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousTextMarker(AccessibilityTextMarker* textMarker) +{ + // FIXME: implement + return 0; +} + +PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextTextMarker(AccessibilityTextMarker* textMarker) +{ + // FIXME: implement + return 0; +} + +JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForTextMarkerRange(AccessibilityTextMarkerRange* markerRange) +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +PassRefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker) +{ + // FIXME: implement + return 0; +} + +PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range) +{ + // FIXME: implement + return 0; +} + +PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range) +{ + // FIXME: implement + return 0; +} + +PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForPoint(int x, int y) +{ + // FIXME: implement + return 0; +} + +PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::accessibilityElementForTextMarker(AccessibilityTextMarker* marker) +{ + // FIXME: implement + return 0; +} + +bool AccessibilityUIElement::attributedStringForTextMarkerRangeContainsAttribute(JSStringRef attribute, AccessibilityTextMarkerRange* range) +{ + // FIXME: implement + return false; +} + +int AccessibilityUIElement::indexForTextMarker(AccessibilityTextMarker* marker) +{ + // FIXME: implement + return -1; +} + +bool AccessibilityUIElement::isTextMarkerValid(AccessibilityTextMarker* textMarker) +{ + // FIXME: implement + return false; +} + +PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForIndex(int textIndex) +{ + // FIXME: implement + return 0; +} + + +} // namespace WTR diff --git a/Tools/WebKitTestRunner/PlatformEfl.cmake b/Tools/WebKitTestRunner/PlatformEfl.cmake index e43febd1a..942c003f2 100644 --- a/Tools/WebKitTestRunner/PlatformEfl.cmake +++ b/Tools/WebKitTestRunner/PlatformEfl.cmake @@ -26,6 +26,7 @@ LIST(APPEND WebKitTestRunner_SOURCES LIST(APPEND WebKitTestRunner_INCLUDE_DIRECTORIES ${TOOLS_DIR}/DumpRenderTree/efl/ + ${WEBKIT2_DIR}/UIProcess/API/efl "${WTF_DIR}/wtf/gobject" ${CAIRO_INCLUDE_DIRS} @@ -56,4 +57,4 @@ LIST(APPEND WebKitTestRunnerInjectedBundle_SOURCES # structure. See <https://bugs.webkit.org/show_bug.cgi?id=81475>. ADD_DEFINITIONS(-DFONTS_CONF_DIR="${TOOLS_DIR}/DumpRenderTree/gtk/fonts" -DDOWNLOADED_FONTS_DIR="${CMAKE_SOURCE_DIR}/WebKitBuild/Dependencies/Source/webkitgtk-test-fonts-0.0.3" - -DDATA_DIR="${THEME_BINARY_DIR}") + -DTHEME_DIR="${THEME_BINARY_DIR}") diff --git a/Tools/WebKitTestRunner/TestController.cpp b/Tools/WebKitTestRunner/TestController.cpp index 3c10ac170..c47c47536 100644 --- a/Tools/WebKitTestRunner/TestController.cpp +++ b/Tools/WebKitTestRunner/TestController.cpp @@ -324,7 +324,8 @@ void TestController::initialize(int argc, const char* argv[]) }; WKContextSetInjectedBundleClient(m_context.get(), &injectedBundleClient); - WKContextSetAdditionalPluginsDirectory(m_context.get(), testPluginDirectory()); + if (testPluginDirectory()) + WKContextSetAdditionalPluginsDirectory(m_context.get(), testPluginDirectory()); m_mainWebView = adoptPtr(new PlatformWebView(m_context.get(), m_pageGroup.get())); diff --git a/Tools/WebKitTestRunner/efl/PlatformWebViewEfl.cpp b/Tools/WebKitTestRunner/efl/PlatformWebViewEfl.cpp index f17820d91..c3c0863c8 100644 --- a/Tools/WebKitTestRunner/efl/PlatformWebViewEfl.cpp +++ b/Tools/WebKitTestRunner/efl/PlatformWebViewEfl.cpp @@ -20,6 +20,7 @@ #include "config.h" #include "PlatformWebView.h" +#include "EWebKit2.h" #include "WebKit2/WKAPICast.h" #include <Ecore_Evas.h> @@ -46,6 +47,8 @@ PlatformWebView::PlatformWebView(WKContextRef context, WKPageGroupRef pageGroup) m_window = initEcoreEvas(); Evas* evas = ecore_evas_get(m_window); m_view = toImpl(WKViewCreate(evas, context, pageGroup)); + + ewk_view_theme_set(m_view, THEME_DIR"/default.edj"); m_windowIsKey = false; } diff --git a/Tools/WebKitTestRunner/efl/TestControllerEfl.cpp b/Tools/WebKitTestRunner/efl/TestControllerEfl.cpp index fbb36508a..87537f682 100644 --- a/Tools/WebKitTestRunner/efl/TestControllerEfl.cpp +++ b/Tools/WebKitTestRunner/efl/TestControllerEfl.cpp @@ -23,6 +23,7 @@ #include <Ecore.h> #include <stdio.h> #include <stdlib.h> +#include <unistd.h> #include <wtf/Platform.h> #include <wtf/text/WTFString.h> diff --git a/Tools/WebKitTestRunner/qt/TestControllerQt.cpp b/Tools/WebKitTestRunner/qt/TestControllerQt.cpp index 158e8089a..4a4cbec14 100644 --- a/Tools/WebKitTestRunner/qt/TestControllerQt.cpp +++ b/Tools/WebKitTestRunner/qt/TestControllerQt.cpp @@ -104,7 +104,10 @@ void TestController::initializeInjectedBundlePath() void TestController::initializeTestPluginDirectory() { - m_testPluginDirectory = WKStringCreateWithUTF8CString(qgetenv("QTWEBKIT_PLUGIN_PATH").constData()); + // FIXME: the test plugin cause some trouble for us, so we don't load it for the time being. + // See: https://bugs.webkit.org/show_bug.cgi?id=86620 + + // m_testPluginDirectory = WKStringCreateWithUTF8CString(qgetenv("QTWEBKIT_PLUGIN_PATH").constData()); } void TestController::platformInitializeContext() diff --git a/Tools/qmake/mkspecs/features/default_post.prf b/Tools/qmake/mkspecs/features/default_post.prf index 767e56372..78a0a82b4 100644 --- a/Tools/qmake/mkspecs/features/default_post.prf +++ b/Tools/qmake/mkspecs/features/default_post.prf @@ -95,6 +95,8 @@ contains(TEMPLATE, derived) { output = $$eval($${generator}.output) input = $$eval($${generator}.input) input_files = $$eval($$input) + output_variable = $$eval($${generator}.variable_out) + isEmpty(output_variable): output_variable = SOURCES isEmpty($${generator}.output_function) { prependEach(output, $${GENERATED_SOURCES_DESTDIR}/) @@ -104,13 +106,13 @@ contains(TEMPLATE, derived) { base ~= s/\\..+// output_file = $$replace(output,\\$\\{QMAKE_FILE_BASE\\}, $$base) - SOURCES += $$output_file + eval($$output_variable += $$output_file) } } else { function = $$eval($${generator}.output_function) for(input_file, input_files) { eval(output_file = \$\$$$function\($$input_file\)) - SOURCES += $$output_file + eval($$output_variable += $$output_file) } } diff --git a/Tools/qmake/mkspecs/features/features.pri b/Tools/qmake/mkspecs/features/features.pri index cb866b517..f4df61674 100644 --- a/Tools/qmake/mkspecs/features/features.pri +++ b/Tools/qmake/mkspecs/features/features.pri @@ -24,6 +24,7 @@ FEATURE_DEFAULTS = \ ENABLE_CSS_EXCLUSIONS=1 \ ENABLE_CSS_FILTERS=1 \ ENABLE_CSS_GRID_LAYOUT=0 \ + ENABLE_CSS_IMAGE_ORIENTATION=0 \ ENABLE_CSS_IMAGE_RESOLUTION=0 \ ENABLE_CSS_REGIONS=1 \ ENABLE_CSS_SHADERS=0 \ diff --git a/Tools/qmake/mkspecs/features/win32/default_post.prf b/Tools/qmake/mkspecs/features/win32/default_post.prf index 116556701..d45d0455e 100644 --- a/Tools/qmake/mkspecs/features/win32/default_post.prf +++ b/Tools/qmake/mkspecs/features/win32/default_post.prf @@ -25,21 +25,16 @@ load(default_post) shared:contains(TEMPLATE, lib) { for(target, POST_TARGETDEPS) { libdep = $$find(target, .*\\.lib) - !isEmpty(libdep): LIBSWITHEXPORTS += $$libdep + exists($$libdep): LIBSWITHEXPORTS += $$libdep } } !isEmpty(LIBSWITHEXPORTS) { - suffix = - CONFIG(debug, debug|release) { - win32: suffix = d - mac: suffix = _debug - } - forwarded_exports.target = forwarded-exports$${suffix}.cpp - forwarded_exports.commands = python $${ROOT_WEBKIT_DIR}$${QMAKE_DIR_SEP}Tools$${QMAKE_DIR_SEP}Scripts$${QMAKE_DIR_SEP}generate-win32-export-forwards $$LIBSWITHEXPORTS $$forwarded_exports.target - forwarded_exports.depends = $$LIBSWITHEXPORTS - QMAKE_EXTRA_TARGETS += forwarded_exports - GENERATED_SOURCES += $$forwarded_exports.target + exportgen.input = LIBSWITHEXPORTS + exportgen.output = exports_${QMAKE_FILE_BASE}.cpp + exportgen.commands = python $${ROOT_WEBKIT_DIR}$${QMAKE_DIR_SEP}Tools$${QMAKE_DIR_SEP}Scripts$${QMAKE_DIR_SEP}generate-win32-export-forwards ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} + exportgen.variable_out = SOURCES + QMAKE_EXTRA_COMPILERS += exportgen } # To ensure the Qt export macros are set to dllexport diff --git a/WebKit.pro b/WebKit.pro index 8d4cbbb56..ef25ea511 100644 --- a/WebKit.pro +++ b/WebKit.pro @@ -20,11 +20,9 @@ WTF.file = Source/WTF/WTF.pro WTF.makefile = Makefile.WTF SUBDIRS += WTF -!v8 { - JavaScriptCore.file = Source/JavaScriptCore/JavaScriptCore.pro - JavaScriptCore.makefile = Makefile.JavaScriptCore - SUBDIRS += JavaScriptCore -} +JavaScriptCore.file = Source/JavaScriptCore/JavaScriptCore.pro +JavaScriptCore.makefile = Makefile.JavaScriptCore +SUBDIRS += JavaScriptCore WebCore.file = Source/WebCore/WebCore.pro WebCore.makefile = Makefile.WebCore diff --git a/configure.ac b/configure.ac index c91bd2305..44ffb4646 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.60) m4_define([webkit_major_version], [1]) m4_define([webkit_minor_version], [9]) -m4_define([webkit_micro_version], [4]) +m4_define([webkit_micro_version], [5]) # This is the version we'll be using as part of our User-Agent string # e.g., AppleWebKit/$(webkit_user_agent_version) ... @@ -35,13 +35,13 @@ AC_CONFIG_SRCDIR([Source/WebCore/config.h]) dnl # Libtool library version, not to confuse with API version dnl # see http://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html -LIBWEBKITGTK_VERSION=14:0:14 +LIBWEBKITGTK_VERSION=15:0:15 AC_SUBST([LIBWEBKITGTK_VERSION]) -LIBJAVASCRIPTCOREGTK_VERSION=13:3:13 +LIBJAVASCRIPTCOREGTK_VERSION=13:4:13 AC_SUBST([LIBJAVASCRIPTCOREGTK_VERSION]) -LIBWEBKIT2GTK_VERSION=15:0:15 +LIBWEBKIT2GTK_VERSION=16:0:16 AC_SUBST([LIBWEBKIT2GTK_VERSION]) AM_INIT_AUTOMAKE([foreign subdir-objects dist-xz no-dist-gzip tar-ustar]) |