diff options
author | Steve Block <steveblock@google.com> | 2010-09-29 17:32:26 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-09-29 17:35:08 +0100 |
commit | 68513a70bcd92384395513322f1b801e7bf9c729 (patch) | |
tree | 161b50f75a5921d61731bb25e730005994fcec85 /WebCore/platform | |
parent | fd5c6425ce58eb75211be7718d5dee960842a37e (diff) | |
download | external_webkit-68513a70bcd92384395513322f1b801e7bf9c729.zip external_webkit-68513a70bcd92384395513322f1b801e7bf9c729.tar.gz external_webkit-68513a70bcd92384395513322f1b801e7bf9c729.tar.bz2 |
Merge WebKit at r67908: Initial merge by Git
Change-Id: I43a553e7b3299b28cb6ee8aa035ed70fe342b972
Diffstat (limited to 'WebCore/platform')
188 files changed, 4990 insertions, 3547 deletions
diff --git a/WebCore/platform/AsyncFileStream.h b/WebCore/platform/AsyncFileStream.h index 3abda01..a555a24 100644 --- a/WebCore/platform/AsyncFileStream.h +++ b/WebCore/platform/AsyncFileStream.h @@ -31,7 +31,7 @@ #ifndef AsyncFileStream_h #define AsyncFileStream_h -#if ENABLE(BLOB) || ENABLE(FILE_WRITER) +#if ENABLE(BLOB) || ENABLE(FILE_SYSTEM) #include "FileStreamClient.h" #include <wtf/Forward.h> @@ -69,6 +69,6 @@ private: } // namespace WebCore -#endif // ENABLE(BLOB) || ENABLE(FILE_WRITER) +#endif // ENABLE(BLOB) || ENABLE(FILE_SYSTEM) #endif // AsyncFileStream_h diff --git a/WebCore/platform/DragImage.cpp b/WebCore/platform/DragImage.cpp index aff4aba..5fcafc1 100644 --- a/WebCore/platform/DragImage.cpp +++ b/WebCore/platform/DragImage.cpp @@ -69,7 +69,7 @@ DragImageRef createDragImageForSelection(Frame* frame) { DragImageRef image = frame->dragImageForSelection(); if (image) - dissolveDragImageToFraction(image, DragController::DragImageAlpha); + image = dissolveDragImageToFraction(image, DragController::DragImageAlpha); return image; } diff --git a/WebCore/platform/DragImage.h b/WebCore/platform/DragImage.h index e825798..a371821 100644 --- a/WebCore/platform/DragImage.h +++ b/WebCore/platform/DragImage.h @@ -48,7 +48,7 @@ class wxDragImage; #elif PLATFORM(CHROMIUM) #include "DragImageRef.h" #elif PLATFORM(GTK) -typedef struct _GdkPixbuf GdkPixbuf; +typedef struct _cairo_surface cairo_surface_t; #elif PLATFORM(HAIKU) class BBitmap; #elif PLATFORM(BREWMP) @@ -75,7 +75,7 @@ namespace WebCore { #elif PLATFORM(WX) typedef wxDragImage* DragImageRef; #elif PLATFORM(GTK) - typedef GdkPixbuf* DragImageRef; + typedef cairo_surface_t* DragImageRef; #elif PLATFORM(HAIKU) typedef BBitmap* DragImageRef; #elif PLATFORM(BREWMP) diff --git a/WebCore/platform/FileStream.cpp b/WebCore/platform/FileStream.cpp index 45f435e..5c77e08 100644 --- a/WebCore/platform/FileStream.cpp +++ b/WebCore/platform/FileStream.cpp @@ -30,7 +30,7 @@ #include "config.h" -#if ENABLE(BLOB) || ENABLE(FILE_WRITER) +#if ENABLE(BLOB) || ENABLE(FILE_SYSTEM) #include "FileStream.h" @@ -147,4 +147,4 @@ bool FileStream::truncate(long long) } // namespace WebCore -#endif // ENABLE(BLOB) || ENABLE(FILE_WRITER) +#endif // ENABLE(BLOB) || ENABLE(FILE_SYSTEM) diff --git a/WebCore/platform/FileStream.h b/WebCore/platform/FileStream.h index 6c3a221..c369eb0 100644 --- a/WebCore/platform/FileStream.h +++ b/WebCore/platform/FileStream.h @@ -31,7 +31,7 @@ #ifndef FileStream_h #define FileStream_h -#if ENABLE(BLOB) || ENABLE(FILE_WRITER) +#if ENABLE(BLOB) || ENABLE(FILE_SYSTEM) #include "FileSystem.h" #include <wtf/Forward.h> @@ -95,6 +95,6 @@ private: } // namespace WebCore -#endif // ENABLE(BLOB) || ENABLE(FILE_WRITER) +#endif // ENABLE(BLOB) || ENABLE(FILE_SYSTEM) #endif // FileStream_h diff --git a/WebCore/platform/FileStreamClient.h b/WebCore/platform/FileStreamClient.h index b3d1fff..4066d9f 100644 --- a/WebCore/platform/FileStreamClient.h +++ b/WebCore/platform/FileStreamClient.h @@ -31,7 +31,7 @@ #ifndef FileStreamClient_h #define FileStreamClient_h -#if ENABLE(BLOB) || ENABLE(FILE_WRITER) +#if ENABLE(BLOB) || ENABLE(FILE_SYSTEM) namespace WebCore { @@ -58,6 +58,6 @@ protected: } // namespace WebCore -#endif // ENABLE(BLOB) || ENABLE(FILE_WRITER) +#endif // ENABLE(BLOB) || ENABLE(FILE_SYSTEM) #endif // FileStreamClient_h diff --git a/WebCore/platform/LinkHash.cpp b/WebCore/platform/LinkHash.cpp index 86b4c8a..ac3aa3c 100644 --- a/WebCore/platform/LinkHash.cpp +++ b/WebCore/platform/LinkHash.cpp @@ -31,36 +31,36 @@ namespace WebCore { -static inline size_t findSlashDotDotSlash(const UChar* characters, size_t length) +static inline size_t findSlashDotDotSlash(const UChar* characters, size_t length, size_t position) { if (length < 4) return notFound; - unsigned loopLimit = length - 3; - for (unsigned i = 0; i < loopLimit; ++i) { + size_t loopLimit = length - 3; + for (size_t i = position; i < loopLimit; ++i) { if (characters[i] == '/' && characters[i + 1] == '.' && characters[i + 2] == '.' && characters[i + 3] == '/') return i; } return notFound; } -static inline size_t findSlashSlash(const UChar* characters, size_t length, int position) +static inline size_t findSlashSlash(const UChar* characters, size_t length, size_t position) { if (length < 2) return notFound; - unsigned loopLimit = length - 1; - for (unsigned i = position; i < loopLimit; ++i) { + size_t loopLimit = length - 1; + for (size_t i = position; i < loopLimit; ++i) { if (characters[i] == '/' && characters[i + 1] == '/') return i; } return notFound; } -static inline size_t findSlashDotSlash(const UChar* characters, size_t length) +static inline size_t findSlashDotSlash(const UChar* characters, size_t length, size_t position) { if (length < 3) return notFound; - unsigned loopLimit = length - 2; - for (unsigned i = 0; i < loopLimit; ++i) { + size_t loopLimit = length - 2; + for (size_t i = position; i < loopLimit; ++i) { if (characters[i] == '/' && characters[i + 1] == '.' && characters[i + 2] == '/') return i; } @@ -79,38 +79,90 @@ static inline bool containsColonSlashSlash(const UChar* characters, unsigned len return false; } -static inline void cleanPath(Vector<UChar, 512>& path) +static inline void squeezeOutNullCharacters(Vector<UChar, 512>& string) { - // FIXME: Should not do this in the query or anchor part. - size_t pos; - while ((pos = findSlashDotDotSlash(path.data(), path.size())) != notFound) { - size_t prev = reverseFind(path.data(), path.size(), '/', pos - 1); - // don't remove the host, i.e. http://foo.org/../foo.html - if (prev == notFound || (prev > 3 && path[prev - 2] == ':' && path[prev - 1] == '/')) - path.remove(pos, 3); - else - path.remove(prev, pos - prev + 3); + size_t size = string.size(); + size_t i = 0; + for (i = 0; i < size; ++i) { + if (!string[i]) + break; } + if (i == size) + return; + size_t j = i; + for (++i; i < size; ++i) { + if (UChar character = string[i]) + string[j++] = character; + } + ASSERT(j < size); + string.shrink(j); +} - // FIXME: Should not do this in the query part. - pos = 0; - if ((pos = findSlashSlash(path.data(), path.size(), pos)) != notFound) { - size_t refPos = find(path.data(), path.size(), '#'); - while (refPos == 0 || refPos == notFound || pos < refPos) { - if (pos == 0 || path[pos - 1] != ':') - path.remove(pos); - else - pos += 2; - if ((pos = findSlashSlash(path.data(), path.size(), pos)) == notFound) - break; +static void cleanSlashDotDotSlashes(Vector<UChar, 512>& path, size_t firstSlash) +{ + size_t slash = firstSlash; + do { + size_t previousSlash = slash ? reverseFind(path.data(), path.size(), '/', slash - 1) : notFound; + // Don't remove the host, i.e. http://foo.org/../foo.html + if (previousSlash == notFound || (previousSlash > 3 && path[previousSlash - 2] == ':' && path[previousSlash - 1] == '/')) { + path[slash] = 0; + path[slash + 1] = 0; + path[slash + 2] = 0; + } else { + for (size_t i = previousSlash; i < slash + 3; ++i) + path[i] = 0; } + slash += 3; + } while ((slash = findSlashDotDotSlash(path.data(), path.size(), slash)) != notFound); + squeezeOutNullCharacters(path); +} + +static void mergeDoubleSlashes(Vector<UChar, 512>& path, size_t firstSlash) +{ + size_t refPos = find(path.data(), path.size(), '#'); + if (!refPos || refPos == notFound) + refPos = path.size(); + + size_t slash = firstSlash; + while (slash < refPos) { + if (!slash || path[slash - 1] != ':') + path[slash++] = 0; + else + slash += 2; + if ((slash = findSlashSlash(path.data(), path.size(), slash)) == notFound) + break; } + squeezeOutNullCharacters(path); +} - // FIXME: Should not do this in the query or anchor part. - while ((pos = findSlashDotSlash(path.data(), path.size())) != notFound) - path.remove(pos, 2); +static void cleanSlashDotSlashes(Vector<UChar, 512>& path, size_t firstSlash) +{ + size_t slash = firstSlash; + do { + path[slash] = 0; + path[slash + 1] = 0; + slash += 2; + } while ((slash = findSlashDotSlash(path.data(), path.size(), slash)) != notFound); + squeezeOutNullCharacters(path); } +static inline void cleanPath(Vector<UChar, 512>& path) +{ + // FIXME: Should not do this in the query or anchor part of the URL. + size_t firstSlash = findSlashDotDotSlash(path.data(), path.size(), 0); + if (firstSlash != notFound) + cleanSlashDotDotSlashes(path, firstSlash); + + // FIXME: Should not do this in the query part. + firstSlash = findSlashSlash(path.data(), path.size(), 0); + if (firstSlash != notFound) + mergeDoubleSlashes(path, firstSlash); + + // FIXME: Should not do this in the query or anchor part. + firstSlash = findSlashDotSlash(path.data(), path.size(), 0); + if (firstSlash != notFound) + cleanSlashDotSlashes(path, firstSlash); +} static inline bool matchLetter(UChar c, UChar lowercaseLetter) { diff --git a/WebCore/platform/MIMETypeRegistry.cpp b/WebCore/platform/MIMETypeRegistry.cpp index 5c20e08..a99c448 100644 --- a/WebCore/platform/MIMETypeRegistry.cpp +++ b/WebCore/platform/MIMETypeRegistry.cpp @@ -104,9 +104,12 @@ static void initializeSupportedImageMIMETypes() continue; #endif String mimeType = MIMETypeRegistry::getMIMETypeForExtension(formats.at(i).constData()); - supportedImageMIMETypes->add(mimeType); - supportedImageResourceMIMETypes->add(mimeType); + if (!mimeType.isEmpty()) { + supportedImageMIMETypes->add(mimeType); + supportedImageResourceMIMETypes->add(mimeType); + } } +<<<<<<< HEAD supportedImageMIMETypes->remove("application/octet-stream"); supportedImageResourceMIMETypes->remove("application/octet-stream"); @@ -132,6 +135,8 @@ static void initializeSupportedImageMIMETypes() #if !ENABLE(XSLT) supportedNonImageMIMETypes->remove("text/xsl"); #endif +======= +>>>>>>> webkit.org at r67908 #else // assume that all implementations at least support the following standard // image types: @@ -176,10 +181,9 @@ static void initializeSupportedImageMIMETypesForEncoding() QList<QByteArray> formats = QImageWriter::supportedImageFormats(); for (int i = 0; i < formats.size(); ++i) { String mimeType = MIMETypeRegistry::getMIMETypeForExtension(formats.at(i).constData()); - supportedImageMIMETypesForEncoding->add(mimeType); + if (!mimeType.isEmpty()) + supportedImageMIMETypesForEncoding->add(mimeType); } - - supportedImageMIMETypesForEncoding->remove("application/octet-stream"); #elif PLATFORM(GTK) supportedImageMIMETypesForEncoding->add("image/png"); supportedImageMIMETypesForEncoding->add("image/jpeg"); diff --git a/WebCore/platform/Pasteboard.h b/WebCore/platform/Pasteboard.h index 7773624..7c50737 100644 --- a/WebCore/platform/Pasteboard.h +++ b/WebCore/platform/Pasteboard.h @@ -79,6 +79,7 @@ class HitTestResult; class KURL; class Node; class Range; +class ArchiveResource; class Pasteboard : public Noncopyable { public: @@ -118,6 +119,8 @@ private: #if PLATFORM(MAC) Pasteboard(NSPasteboard *); RetainPtr<NSPasteboard> m_pasteboard; + PassRefPtr<DocumentFragment> documentFragmentWithImageResource(Frame* frame, PassRefPtr<ArchiveResource> resource); + PassRefPtr<DocumentFragment> documentFragmentWithRtf(Frame* frame, NSString* pboardType); #endif #if PLATFORM(WIN) diff --git a/WebCore/platform/ScrollAnimator.cpp b/WebCore/platform/ScrollAnimator.cpp index c863c1d..583e833 100644 --- a/WebCore/platform/ScrollAnimator.cpp +++ b/WebCore/platform/ScrollAnimator.cpp @@ -36,7 +36,7 @@ namespace WebCore { -#if !OS(WINDOWS) +#if !ENABLE(SMOOTH_SCROLLING) ScrollAnimator* ScrollAnimator::create(ScrollbarClient* client) { return new ScrollAnimator(client); diff --git a/WebCore/platform/ScrollAnimatorWin.cpp b/WebCore/platform/ScrollAnimatorWin.cpp index 8b7d0f6..025aa71 100644 --- a/WebCore/platform/ScrollAnimatorWin.cpp +++ b/WebCore/platform/ScrollAnimatorWin.cpp @@ -29,6 +29,9 @@ */ #include "config.h" + +#if ENABLE(SMOOTH_SCROLLING) + #include "ScrollAnimatorWin.h" #include "ScrollbarClient.h" @@ -128,7 +131,7 @@ bool ScrollAnimatorWin::scroll(ScrollbarOrientation orientation, ScrollGranulari // velocity needed to stay smoothly in sync with the user's actions; for // events that come slower, we'll scroll one increment and then pause until // the next event fires. - float animationStep = abs(newPos - *data->m_currentPos); + float animationStep = fabs(newPos - *data->m_currentPos); // If a key is held down (or the wheel continually spun), then once we have // reached a velocity close to the steady-state velocity, we're likely to // hit the desired position at around the same time we'd expect the next @@ -275,7 +278,7 @@ void ScrollAnimatorWin::animateScroll(PerAxisData* data) } // Now update the scroll position based on the distance traveled. - if (distanceTraveled >= abs(data->m_desiredPos - *data->m_currentPos)) { + if (distanceTraveled >= fabs(data->m_desiredPos - *data->m_currentPos)) { // We've traveled far enough to reach the desired position. Stop smooth // scrolling. *data->m_currentPos = data->m_desiredPos; @@ -294,3 +297,5 @@ void ScrollAnimatorWin::animateScroll(PerAxisData* data) } } // namespace WebCore + +#endif // ENABLE(SMOOTH_SCROLLING) diff --git a/WebCore/platform/ScrollAnimatorWin.h b/WebCore/platform/ScrollAnimatorWin.h index 002a454..7043634 100644 --- a/WebCore/platform/ScrollAnimatorWin.h +++ b/WebCore/platform/ScrollAnimatorWin.h @@ -31,6 +31,8 @@ #ifndef ScrollAnimatorWin_h #define ScrollAnimatorWin_h +#if ENABLE(SMOOTH_SCROLLING) + #include "ScrollAnimator.h" #include "Timer.h" @@ -68,4 +70,7 @@ private: }; } + +#endif // ENABLE(SMOOTH_SCROLLING) + #endif diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp index 43badd0..0273807 100644 --- a/WebCore/platform/ScrollView.cpp +++ b/WebCore/platform/ScrollView.cpp @@ -340,6 +340,15 @@ void ScrollView::valueChanged(Scrollbar* scrollbar) scrollContents(scrollDelta); } +void ScrollView::valueChanged(const IntSize& scrollDelta) +{ + if (scrollbarsSuppressed()) + return; + + repaintFixedElementsAfterScrolling(); + scrollContents(scrollDelta); +} + void ScrollView::setScrollPosition(const IntPoint& scrollPoint) { if (prohibitsScrolling()) @@ -524,7 +533,7 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset) IntSize scrollDelta = scroll - m_scrollOffset; if (scrollDelta != IntSize()) { m_scrollOffset = scroll; - scrollContents(scrollDelta); + valueChanged(scrollDelta); } m_inUpdateScrollbars = false; diff --git a/WebCore/platform/ScrollView.h b/WebCore/platform/ScrollView.h index a55fed4..751b276 100644 --- a/WebCore/platform/ScrollView.h +++ b/WebCore/platform/ScrollView.h @@ -62,6 +62,7 @@ public: virtual int scrollSize(ScrollbarOrientation orientation) const; virtual void setScrollOffsetFromAnimation(const IntPoint&); virtual void valueChanged(Scrollbar*); + virtual void valueChanged(const IntSize&); // The window thats hosts the ScrollView. The ScrollView will communicate scrolls and repaints to the // host window in the window's coordinate space. diff --git a/WebCore/platform/animation/Animation.h b/WebCore/platform/animation/Animation.h index 9130415..1541b4d 100644 --- a/WebCore/platform/animation/Animation.h +++ b/WebCore/platform/animation/Animation.h @@ -84,7 +84,7 @@ public: double delay() const { return m_delay; } enum AnimationDirection { AnimationDirectionNormal, AnimationDirectionAlternate }; - AnimationDirection direction() const { return m_direction; } + AnimationDirection direction() const { return static_cast<AnimationDirection>(m_direction); } unsigned fillMode() const { return m_fillMode; } @@ -131,7 +131,7 @@ private: double m_delay; double m_duration; RefPtr<TimingFunction> m_timingFunction; - AnimationDirection m_direction : 1; + unsigned m_direction : 1; // AnimationDirection unsigned m_fillMode : 2; unsigned m_playState : 2; diff --git a/WebCore/platform/audio/AudioFileReader.h b/WebCore/platform/audio/AudioFileReader.h new file mode 100644 index 0000000..3c02490 --- /dev/null +++ b/WebCore/platform/audio/AudioFileReader.h @@ -0,0 +1,54 @@ +/* + * 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: + * + * 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. + * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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 AudioFileReader_h +#define AudioFileReader_h + +#include <stdlib.h> +#include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> + +namespace WebCore { + +class AudioBus; + +// For both create functions: +// Pass in 0.0 for sampleRate to use the file's sample-rate, otherwise a sample-rate conversion to the requested +// sampleRate will be made (if it doesn't already match the file's sample-rate). +// The created buffer will have its sample-rate set correctly to the result. + +PassOwnPtr<AudioBus> createBusFromInMemoryAudioFile(const void* data, size_t dataSize, bool mixToMono, double sampleRate); + +PassOwnPtr<AudioBus> createBusFromAudioFile(const char* filePath, bool mixToMono, double sampleRate); + +// May pass in 0.0 for sampleRate in which case it will use the AudioBus's sampleRate +void writeBusToAudioFile(AudioBus* bus, const char* filePath, double fileSampleRate); + +} // namespace WebCore + +#endif // AudioFileReader_h diff --git a/WebCore/platform/audio/mac/AudioFileReaderMac.cpp b/WebCore/platform/audio/mac/AudioFileReaderMac.cpp new file mode 100644 index 0000000..9dad611 --- /dev/null +++ b/WebCore/platform/audio/mac/AudioFileReaderMac.cpp @@ -0,0 +1,257 @@ +/* + * 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: + * + * 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. + * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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(WEB_AUDIO) + +#include "AudioFileReaderMac.h" + +#include "AudioBus.h" +#include "AudioFileReader.h" +#include <CoreFoundation/CoreFoundation.h> + +namespace WebCore { + +static AudioBufferList* createAudioBufferList(size_t numberOfBuffers) +{ + size_t bufferListSize = sizeof(AudioBufferList) - sizeof(AudioBuffer); + bufferListSize += numberOfBuffers * sizeof(AudioBuffer); + + AudioBufferList* bufferList = static_cast<AudioBufferList*>(calloc(1, bufferListSize)); + if (bufferList) + bufferList->mNumberBuffers = numberOfBuffers; + + return bufferList; +} + +static void destroyAudioBufferList(AudioBufferList* bufferList) +{ + free(bufferList); +} + +AudioFileReader::AudioFileReader(const char* filePath) + : m_data(0) + , m_dataSize(0) + , m_filePath(filePath) + , m_audioFileID(0) + , m_extAudioFileRef(0) +{ + FSRef fsref; + OSStatus result = FSPathMakeRef((UInt8*)filePath, &fsref, 0); + if (result != noErr) + return; + + CFURLRef urlRef = CFURLCreateFromFSRef(0, &fsref); + if (!urlRef) + return; + + ExtAudioFileOpenURL(urlRef, &m_extAudioFileRef); + + if (urlRef) + CFRelease(urlRef); +} + +AudioFileReader::AudioFileReader(const void* data, size_t dataSize) + : m_data(data) + , m_dataSize(dataSize) + , m_filePath(0) + , m_audioFileID(0) + , m_extAudioFileRef(0) +{ + OSStatus result = AudioFileOpenWithCallbacks(this, readProc, 0, getSizeProc, 0, 0, &m_audioFileID); + + if (result != noErr) + return; + + result = ExtAudioFileWrapAudioFileID(m_audioFileID, false, &m_extAudioFileRef); + if (result != noErr) + m_extAudioFileRef = 0; +} + +AudioFileReader::~AudioFileReader() +{ + if (m_extAudioFileRef) + ExtAudioFileDispose(m_extAudioFileRef); + + m_extAudioFileRef = 0; + + if (m_audioFileID) + AudioFileClose(m_audioFileID); + + m_audioFileID = 0; +} + +OSStatus AudioFileReader::readProc(void* clientData, SInt64 position, UInt32 requestCount, void* buffer, UInt32* actualCount) +{ + AudioFileReader* audioFileReader = static_cast<AudioFileReader*>(clientData); + + size_t dataSize = audioFileReader->dataSize(); + const void* data = audioFileReader->data(); + size_t bytesToRead = 0; + + if (static_cast<UInt64>(position) < dataSize) { + size_t bytesAvailable = dataSize - static_cast<size_t>(position); + bytesToRead = requestCount <= bytesAvailable ? requestCount : bytesAvailable; + memcpy(buffer, static_cast<const char*>(data) + position, bytesToRead); + } else + bytesToRead = 0; + + if (actualCount) + *actualCount = bytesToRead; + + return noErr; +} + +SInt64 AudioFileReader::getSizeProc(void* clientData) +{ + AudioFileReader* audioFileReader = static_cast<AudioFileReader*>(clientData); + return audioFileReader->dataSize(); +} + +PassOwnPtr<AudioBus> AudioFileReader::createBus(double sampleRate, bool mixToMono) +{ + if (!m_extAudioFileRef) + return 0; + + // Get file's data format + UInt32 size = sizeof(m_fileDataFormat); + OSStatus result = ExtAudioFileGetProperty(m_extAudioFileRef, kExtAudioFileProperty_FileDataFormat, &size, &m_fileDataFormat); + if (result != noErr) + return 0; + + // Number of channels + size_t numberOfChannels = m_fileDataFormat.mChannelsPerFrame; + + // Number of frames + SInt64 numberOfFrames64 = 0; + size = sizeof(numberOfFrames64); + result = ExtAudioFileGetProperty(m_extAudioFileRef, kExtAudioFileProperty_FileLengthFrames, &size, &numberOfFrames64); + if (result != noErr) + return 0; + + // Sample-rate + double fileSampleRate = m_fileDataFormat.mSampleRate; + + // Make client format same number of channels as file format, but tweak a few things. + // Client format will be linear PCM (canonical), and potentially change sample-rate. + m_clientDataFormat = m_fileDataFormat; + + m_clientDataFormat.mFormatID = kAudioFormatLinearPCM; + m_clientDataFormat.mFormatFlags = kAudioFormatFlagsCanonical; + m_clientDataFormat.mBitsPerChannel = 8 * sizeof(AudioSampleType); + m_clientDataFormat.mChannelsPerFrame = numberOfChannels; + m_clientDataFormat.mFramesPerPacket = 1; + m_clientDataFormat.mBytesPerPacket = sizeof(AudioSampleType); + m_clientDataFormat.mBytesPerFrame = sizeof(AudioSampleType); + m_clientDataFormat.mFormatFlags |= kAudioFormatFlagIsNonInterleaved; + + if (sampleRate) + m_clientDataFormat.mSampleRate = sampleRate; + + result = ExtAudioFileSetProperty(m_extAudioFileRef, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &m_clientDataFormat); + if (result != noErr) + return 0; + + // Change numberOfFrames64 to destination sample-rate + numberOfFrames64 = numberOfFrames64 * (m_clientDataFormat.mSampleRate / fileSampleRate); + size_t numberOfFrames = static_cast<size_t>(numberOfFrames64); + + size_t busChannelCount = mixToMono ? 1 : numberOfChannels; + + // Create AudioBus where we'll put the PCM audio data + OwnPtr<AudioBus> audioBus = adoptPtr(new AudioBus(busChannelCount, numberOfFrames)); + audioBus->setSampleRate(m_clientDataFormat.mSampleRate); // save for later + + // Only allocated in the mixToMono case + AudioFloatArray bufL; + AudioFloatArray bufR; + float* bufferL = 0; + float* bufferR = 0; + + // Setup AudioBufferList in preparation for reading + AudioBufferList* bufferList = createAudioBufferList(numberOfChannels); + + if (mixToMono && numberOfChannels == 2) { + bufL.resize(numberOfFrames); + bufR.resize(numberOfFrames); + bufferL = bufL.data(); + bufferR = bufR.data(); + + bufferList->mBuffers[0].mNumberChannels = 1; + bufferList->mBuffers[0].mDataByteSize = numberOfFrames * sizeof(float); + bufferList->mBuffers[0].mData = bufferL; + + bufferList->mBuffers[1].mNumberChannels = 1; + bufferList->mBuffers[1].mDataByteSize = numberOfFrames * sizeof(float); + bufferList->mBuffers[1].mData = bufferR; + } else { + ASSERT(!mixToMono || numberOfChannels == 1); + + // for True-stereo (numberOfChannels == 4) + for (size_t i = 0; i < numberOfChannels; ++i) { + bufferList->mBuffers[i].mNumberChannels = 1; + bufferList->mBuffers[i].mDataByteSize = numberOfFrames * sizeof(float); + bufferList->mBuffers[i].mData = audioBus->channel(i)->data(); + } + } + + // Read from the file (or in-memory version) + UInt32 framesToRead = numberOfFrames; + result = ExtAudioFileRead(m_extAudioFileRef, &framesToRead, bufferList); + if (result != noErr) + return 0; + + if (mixToMono && numberOfChannels == 2) { + // Mix stereo down to mono + float* destL = audioBus->channel(0)->data(); + for (size_t i = 0; i < numberOfFrames; i++) + destL[i] = 0.5f * (bufferL[i] + bufferR[i]); + } + + // Cleanup + destroyAudioBufferList(bufferList); + + return audioBus.release(); +} + +PassOwnPtr<AudioBus> createBusFromAudioFile(const char* filePath, bool mixToMono, double sampleRate) +{ + AudioFileReader reader(filePath); + return reader.createBus(sampleRate, mixToMono); +} + +PassOwnPtr<AudioBus> createBusFromInMemoryAudioFile(const void* data, size_t dataSize, bool mixToMono, double sampleRate) +{ + AudioFileReader reader(data, dataSize); + return reader.createBus(sampleRate, mixToMono); +} + +} // WebCore + +#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/platform/audio/mac/AudioFileReaderMac.h b/WebCore/platform/audio/mac/AudioFileReaderMac.h new file mode 100644 index 0000000..d531266 --- /dev/null +++ b/WebCore/platform/audio/mac/AudioFileReaderMac.h @@ -0,0 +1,71 @@ +/* + * 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: + * + * 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. + * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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 AudioFileReaderMac_h +#define AudioFileReaderMac_h + +#include <AudioToolbox/AudioFile.h> +#include <AudioToolbox/ExtendedAudioFile.h> +#include <wtf/PassOwnPtr.h> + +namespace WebCore { + +class AudioBus; + +// Wrapper class for AudioFile and ExtAudioFile CoreAudio APIs for reading files and in-memory versions of them... + +class AudioFileReader { +public: + AudioFileReader(const char* filePath); + AudioFileReader(const void* data, size_t dataSize); + ~AudioFileReader(); + + // Returns 0 if error + PassOwnPtr<AudioBus> createBus(double sampleRate, bool mixToMono); + + const void* data() const { return m_data; } + size_t dataSize() const { return m_dataSize; } + +private: + static OSStatus readProc(void* clientData, SInt64 position, UInt32 requestCount, void* buffer, UInt32* actualCount); + static SInt64 getSizeProc(void* clientData); + + const void* m_data; + size_t m_dataSize; + const char* m_filePath; + + AudioFileID m_audioFileID; + ExtAudioFileRef m_extAudioFileRef; + + AudioStreamBasicDescription m_fileDataFormat; + AudioStreamBasicDescription m_clientDataFormat; +}; + +} // namespace WebCore + +#endif // AudioFileReaderMac_h diff --git a/WebCore/platform/brew/PlatformKeyboardEventBrew.cpp b/WebCore/platform/brew/PlatformKeyboardEventBrew.cpp index 9d172a3..d7a1279 100644 --- a/WebCore/platform/brew/PlatformKeyboardEventBrew.cpp +++ b/WebCore/platform/brew/PlatformKeyboardEventBrew.cpp @@ -35,7 +35,7 @@ namespace WebCore { -static String keyIdentifierForBrewKeyCode(int16 keyCode) +static String keyIdentifierForBrewKeyCode(uint16 keyCode) { switch (keyCode) { case AVK_LALT: @@ -106,7 +106,7 @@ static String keyIdentifierForBrewKeyCode(int16 keyCode) static int windowsKeyCodeForKeyEvent(uint16 code) { switch (code) { - case AVK_A: + case AVK_CLR: return VK_BACK; // (08) BACKSPACE key case AVK_ENTER: return VK_RETURN; // (0D) Return key diff --git a/WebCore/platform/brew/PlatformMouseEventBrew.cpp b/WebCore/platform/brew/PlatformMouseEventBrew.cpp index 32593e6..a118d19 100644 --- a/WebCore/platform/brew/PlatformMouseEventBrew.cpp +++ b/WebCore/platform/brew/PlatformMouseEventBrew.cpp @@ -65,15 +65,10 @@ PlatformMouseEvent::PlatformMouseEvent(AEEEvent event, uint16 wParam, uint32 dwP m_altKey = keyModifiers & (KB_LALT | KB_RALT); m_metaKey = m_altKey; - uint16 mouseModifiers = AEE_POINTER_GET_MOUSE_MODIFIERS(dwParamStr); - if (mouseModifiers & AEE_POINTER_MOUSE_LBUTTON) - m_button = LeftButton; - else if (mouseModifiers & AEE_POINTER_MOUSE_RBUTTON) - m_button = RightButton; - else if (mouseModifiers & AEE_POINTER_MOUSE_MBUTTON) - m_button = MiddleButton; - else - m_button = NoButton; + // AEE_POINTER_GET_MOUSE_MODIFIERS(dwParamStr) always returns 0, + // so it is impossible to know which button is pressed or released. + // Just use LeftButton because Brew MP usually runs on touch device. + m_button = LeftButton; // AEE_POINTER_GET_TIME returns milliseconds m_timestamp = AEE_POINTER_GET_TIME(dwParamStr) * 0.001; diff --git a/WebCore/platform/brew/SSLKeyGeneratorBrew.cpp b/WebCore/platform/brew/SSLKeyGeneratorBrew.cpp index 4887e4f..dc1a148 100644 --- a/WebCore/platform/brew/SSLKeyGeneratorBrew.cpp +++ b/WebCore/platform/brew/SSLKeyGeneratorBrew.cpp @@ -24,12 +24,12 @@ namespace WebCore { -void WebCore::getSupportedKeySizes(Vector<String>& v) +void getSupportedKeySizes(Vector<String>& v) { notImplemented(); } -String WebCore::signedPublicKeyAndChallengeString(unsigned index, const String& challenge, const KURL& url) +String signedPublicKeyAndChallengeString(unsigned index, const String& challenge, const KURL& url) { notImplemented(); return String(); diff --git a/WebCore/platform/brew/SharedBufferBrew.cpp b/WebCore/platform/brew/SharedBufferBrew.cpp index 597825c..3d4c20a 100644 --- a/WebCore/platform/brew/SharedBufferBrew.cpp +++ b/WebCore/platform/brew/SharedBufferBrew.cpp @@ -64,6 +64,7 @@ PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& fi int32 bytesRead; while ((bytesRead = IFILE_Read(file.get(), result->m_buffer.data() + totalBytesRead, fileSize - totalBytesRead)) > 0) totalBytesRead += bytesRead; + result->m_size = totalBytesRead; if (totalBytesRead != fileSize) { LOG_ERROR("Failed to fully read contents of file %s - errno(%i)", filePath.ascii().data(), IFILEMGR_GetLastError(fileMgr.get())); diff --git a/WebCore/platform/chromium/ClipboardChromium.cpp b/WebCore/platform/chromium/ClipboardChromium.cpp index aff1466..3d82aea 100644 --- a/WebCore/platform/chromium/ClipboardChromium.cpp +++ b/WebCore/platform/chromium/ClipboardChromium.cpp @@ -364,10 +364,9 @@ PassRefPtr<FileList> ClipboardChromium::files() const if (!m_dataObject || m_dataObject->filenames.isEmpty()) return FileList::create(); - ScriptExecutionContext* scriptExecutionContext = m_frame->document()->scriptExecutionContext(); RefPtr<FileList> fileList = FileList::create(); for (size_t i = 0; i < m_dataObject->filenames.size(); ++i) - fileList->append(File::create(scriptExecutionContext, m_dataObject->filenames.at(i))); + fileList->append(File::create(m_dataObject->filenames.at(i))); return fileList.release(); } diff --git a/WebCore/platform/chromium/GeolocationServiceChromium.cpp b/WebCore/platform/chromium/GeolocationServiceChromium.cpp index 9333999..b64f5eb 100644 --- a/WebCore/platform/chromium/GeolocationServiceChromium.cpp +++ b/WebCore/platform/chromium/GeolocationServiceChromium.cpp @@ -35,6 +35,10 @@ namespace WebCore { +GeolocationServiceBridge::~GeolocationServiceBridge() +{ +} + GeolocationServiceChromium::GeolocationServiceChromium(GeolocationServiceClient* c) : GeolocationService(c), m_geolocation(static_cast<Geolocation*>(c)), diff --git a/WebCore/platform/chromium/GeolocationServiceChromium.h b/WebCore/platform/chromium/GeolocationServiceChromium.h index f139220..7e6f633 100644 --- a/WebCore/platform/chromium/GeolocationServiceChromium.h +++ b/WebCore/platform/chromium/GeolocationServiceChromium.h @@ -42,6 +42,7 @@ namespace WebCore { // Provides an interface for GeolocationServiceChromium to call into the embedder. class GeolocationServiceBridge { public: + virtual ~GeolocationServiceBridge(); // Called by GeolocationServiceChromium. virtual bool startUpdating(PositionOptions*) = 0; virtual void stopUpdating() = 0; diff --git a/WebCore/platform/graphics/Gradient.cpp b/WebCore/platform/graphics/Gradient.cpp index 3d8dfc9..f9427fb 100644 --- a/WebCore/platform/graphics/Gradient.cpp +++ b/WebCore/platform/graphics/Gradient.cpp @@ -117,9 +117,16 @@ void Gradient::sortStopsIfNecessary() if (m_stopsSorted) return; - if (m_stops.size()) - std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); m_stopsSorted = true; + + if (!m_stops.size()) + return; + + // Shortcut for the ideal case (ordered 2-stop gradient) + if (m_stops.size() == 2 && compareStops(*m_stops.begin(), *m_stops.end())) + return; + + std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); } void Gradient::getColor(float value, float* r, float* g, float* b, float* a) const diff --git a/WebCore/platform/graphics/Gradient.h b/WebCore/platform/graphics/Gradient.h index c4ac01b..0a69fa2 100644 --- a/WebCore/platform/graphics/Gradient.h +++ b/WebCore/platform/graphics/Gradient.h @@ -101,7 +101,7 @@ namespace WebCore { const FloatPoint& p1() const { return m_p1; } float r0() const { return m_r0; } float r1() const { return m_r1; } - const Vector<ColorStop>& getStops() const; + const Vector<ColorStop, 2>& getStops() const; #else #if PLATFORM(ANDROID) SkShader* getShader(SkShader::TileMode); @@ -150,7 +150,7 @@ namespace WebCore { FloatPoint m_p1; float m_r0; float m_r1; - mutable Vector<ColorStop> m_stops; + mutable Vector<ColorStop, 2> m_stops; mutable bool m_stopsSorted; mutable int m_lastStop; GradientSpreadMethod m_spreadMethod; diff --git a/WebCore/platform/graphics/GraphicsContext3D.cpp b/WebCore/platform/graphics/GraphicsContext3D.cpp index 170bb84..2da5862 100644 --- a/WebCore/platform/graphics/GraphicsContext3D.cpp +++ b/WebCore/platform/graphics/GraphicsContext3D.cpp @@ -830,6 +830,40 @@ bool GraphicsContext3D::supportsBGRA() // Returning false for now to be safe. return false; } + +bool GraphicsContext3D::supportsMapSubCHROMIUM() +{ + // We don't claim support for this extension at this time. + return false; +} + +void* GraphicsContext3D::mapBufferSubDataCHROMIUM(unsigned, int, int, unsigned) +{ + return 0; +} + +void GraphicsContext3D::unmapBufferSubDataCHROMIUM(const void*) +{ +} + +void* GraphicsContext3D::mapTexSubImage2DCHROMIUM(unsigned, int, int, int, int, int, unsigned, unsigned, unsigned) +{ + return 0; +} + +void GraphicsContext3D::unmapTexSubImage2DCHROMIUM(const void*) +{ +} + +bool GraphicsContext3D::supportsCopyTextureToParentTextureCHROMIUM() +{ + // We don't claim support for this extension at this time. + return false; +} + +void GraphicsContext3D::copyTextureToParentTextureCHROMIUM(unsigned, unsigned) +{ +} #endif } // namespace WebCore diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h index b583813..bcb7997 100644 --- a/WebCore/platform/graphics/GraphicsContext3D.h +++ b/WebCore/platform/graphics/GraphicsContext3D.h @@ -404,7 +404,12 @@ public: UNPACK_FLIP_Y_WEBGL = 0x9240, UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241, - BGRA_EXT = 0x80E1 + // GL_EXT_texture_format_BGRA8888 + BGRA_EXT = 0x80E1, + + // GL_CHROMIUM_map_sub (enums inherited from GL_ARB_vertex_buffer_object) + READ_ONLY = 0x88B8, + WRITE_ONLY = 0x88B9 }; // Context creation attributes. @@ -425,7 +430,12 @@ public: bool premultipliedAlpha; }; - static PassOwnPtr<GraphicsContext3D> create(Attributes attrs, HostWindow* hostWindow); + enum RenderStyle { + RenderOffscreen, + RenderDirectlyToHostWindow + }; + + static PassOwnPtr<GraphicsContext3D> create(Attributes attrs, HostWindow* hostWindow, RenderStyle renderStyle = RenderOffscreen); virtual ~GraphicsContext3D(); #if PLATFORM(MAC) @@ -751,10 +761,22 @@ public: // getError in the order they were added. void synthesizeGLError(unsigned long error); + // EXT_texture_format_BGRA8888 bool supportsBGRA(); + // GL_CHROMIUM_map_sub + bool supportsMapSubCHROMIUM(); + void* mapBufferSubDataCHROMIUM(unsigned target, int offset, int size, unsigned access); + void unmapBufferSubDataCHROMIUM(const void*); + void* mapTexSubImage2DCHROMIUM(unsigned target, int level, int xoffset, int yoffset, int width, int height, unsigned format, unsigned type, unsigned access); + void unmapTexSubImage2DCHROMIUM(const void*); + + // GL_CHROMIUM_copy_texture_to_parent_texture + bool supportsCopyTextureToParentTextureCHROMIUM(); + void copyTextureToParentTextureCHROMIUM(unsigned texture, unsigned parentTexture); + private: - GraphicsContext3D(Attributes attrs, HostWindow* hostWindow); + GraphicsContext3D(Attributes attrs, HostWindow* hostWindow, bool renderDirectlyToHostWindow); // Each platform must provide an implementation of this method. // diff --git a/WebCore/platform/graphics/GraphicsLayer.cpp b/WebCore/platform/graphics/GraphicsLayer.cpp index 5003907..b0f529b 100644 --- a/WebCore/platform/graphics/GraphicsLayer.cpp +++ b/WebCore/platform/graphics/GraphicsLayer.cpp @@ -73,7 +73,6 @@ GraphicsLayer::GraphicsLayer(GraphicsLayerClient* client) , m_masksToBounds(false) , m_drawsContent(false) , m_paintingPhase(GraphicsLayerPaintAll) - , m_geometryOrientation(CompositingCoordinatesTopDown) , m_contentsOrientation(CompositingCoordinatesTopDown) , m_parent(0) , m_maskLayer(0) @@ -411,29 +410,45 @@ void GraphicsLayer::dumpLayer(TextStream& ts, int indent, LayerTreeAsTextBehavio void GraphicsLayer::dumpProperties(TextStream& ts, int indent, LayerTreeAsTextBehavior behavior) const { - writeIndent(ts, indent + 1); - ts << "(position " << m_position.x() << " " << m_position.y() << ")\n"; + if (m_position != FloatPoint()) { + writeIndent(ts, indent + 1); + ts << "(position " << m_position.x() << " " << m_position.y() << ")\n"; + } - writeIndent(ts, indent + 1); - ts << "(anchor " << m_anchorPoint.x() << " " << m_anchorPoint.y() << ")\n"; + if (m_anchorPoint != FloatPoint3D(0.5f, 0.5f, 0)) { + writeIndent(ts, indent + 1); + ts << "(anchor " << m_anchorPoint.x() << " " << m_anchorPoint.y() << ")\n"; + } - writeIndent(ts, indent + 1); - ts << "(bounds " << m_size.width() << " " << m_size.height() << ")\n"; + if (m_size != IntSize()) { + writeIndent(ts, indent + 1); + ts << "(bounds " << m_size.width() << " " << m_size.height() << ")\n"; + } - writeIndent(ts, indent + 1); - ts << "(opacity " << m_opacity << ")\n"; + if (m_opacity != 1) { + writeIndent(ts, indent + 1); + ts << "(opacity " << m_opacity << ")\n"; + } - writeIndent(ts, indent + 1); - ts << "(usingTiledLayer " << m_usingTiledLayer << ")\n"; + if (m_usingTiledLayer) { + writeIndent(ts, indent + 1); + ts << "(usingTiledLayer " << m_usingTiledLayer << ")\n"; + } - writeIndent(ts, indent + 1); - ts << "(preserves3D " << m_preserves3D << ")\n"; + if (m_preserves3D) { + writeIndent(ts, indent + 1); + ts << "(preserves3D " << m_preserves3D << ")\n"; + } - writeIndent(ts, indent + 1); - ts << "(drawsContent " << m_drawsContent << ")\n"; + if (m_drawsContent) { + writeIndent(ts, indent + 1); + ts << "(drawsContent " << m_drawsContent << ")\n"; + } - writeIndent(ts, indent + 1); - ts << "(backfaceVisibility " << (m_backfaceVisibility ? "visible" : "hidden") << ")\n"; + if (!m_backfaceVisibility) { + writeIndent(ts, indent + 1); + ts << "(backfaceVisibility " << (m_backfaceVisibility ? "visible" : "hidden") << ")\n"; + } if (behavior & LayerTreeAsTextDebug) { writeIndent(ts, indent + 1); @@ -445,40 +460,29 @@ void GraphicsLayer::dumpProperties(TextStream& ts, int indent, LayerTreeAsTextBe ts << ")\n"; } - writeIndent(ts, indent + 1); - ts << "(backgroundColor "; - if (!m_backgroundColorSet) - ts << "none"; - else - ts << m_backgroundColor.name(); - ts << ")\n"; + if (m_backgroundColorSet) { + writeIndent(ts, indent + 1); + ts << "(backgroundColor " << m_backgroundColor.name() << ")\n"; + } - writeIndent(ts, indent + 1); - ts << "(transform "; - if (m_transform.isIdentity()) - ts << "identity"; - else { + if (!m_transform.isIdentity()) { + writeIndent(ts, indent + 1); + ts << "(transform "; ts << "[" << m_transform.m11() << " " << m_transform.m12() << " " << m_transform.m13() << " " << m_transform.m14() << "] "; ts << "[" << m_transform.m21() << " " << m_transform.m22() << " " << m_transform.m23() << " " << m_transform.m24() << "] "; ts << "[" << m_transform.m31() << " " << m_transform.m32() << " " << m_transform.m33() << " " << m_transform.m34() << "] "; - ts << "[" << m_transform.m41() << " " << m_transform.m42() << " " << m_transform.m43() << " " << m_transform.m44() << "]"; + ts << "[" << m_transform.m41() << " " << m_transform.m42() << " " << m_transform.m43() << " " << m_transform.m44() << "])\n"; } - ts << ")\n"; // Avoid dumping the sublayer transform on the root layer, because it's used for geometry flipping, whose behavior // differs between platforms. - if (parent()) { + if (parent() && !m_childrenTransform.isIdentity()) { writeIndent(ts, indent + 1); ts << "(childrenTransform "; - if (m_childrenTransform.isIdentity()) - ts << "identity"; - else { - ts << "[" << m_childrenTransform.m11() << " " << m_childrenTransform.m12() << " " << m_childrenTransform.m13() << " " << m_childrenTransform.m14() << "] "; - ts << "[" << m_childrenTransform.m21() << " " << m_childrenTransform.m22() << " " << m_childrenTransform.m23() << " " << m_childrenTransform.m24() << "] "; - ts << "[" << m_childrenTransform.m31() << " " << m_childrenTransform.m32() << " " << m_childrenTransform.m33() << " " << m_childrenTransform.m34() << "] "; - ts << "[" << m_childrenTransform.m41() << " " << m_childrenTransform.m42() << " " << m_childrenTransform.m43() << " " << m_childrenTransform.m44() << "]"; - } - ts << ")\n"; + ts << "[" << m_childrenTransform.m11() << " " << m_childrenTransform.m12() << " " << m_childrenTransform.m13() << " " << m_childrenTransform.m14() << "] "; + ts << "[" << m_childrenTransform.m21() << " " << m_childrenTransform.m22() << " " << m_childrenTransform.m23() << " " << m_childrenTransform.m24() << "] "; + ts << "[" << m_childrenTransform.m31() << " " << m_childrenTransform.m32() << " " << m_childrenTransform.m33() << " " << m_childrenTransform.m34() << "] "; + ts << "[" << m_childrenTransform.m41() << " " << m_childrenTransform.m42() << " " << m_childrenTransform.m43() << " " << m_childrenTransform.m44() << "])\n"; } if (m_replicaLayer) { diff --git a/WebCore/platform/graphics/GraphicsLayer.h b/WebCore/platform/graphics/GraphicsLayer.h index 68a580e..04899f2 100644 --- a/WebCore/platform/graphics/GraphicsLayer.h +++ b/WebCore/platform/graphics/GraphicsLayer.h @@ -313,14 +313,7 @@ public: int repaintCount() const { return m_repaintCount; } int incrementRepaintCount() { return ++m_repaintCount; } - // Report whether the underlying compositing system uses a top-down - // or a bottom-up coordinate system. enum CompositingCoordinatesOrientation { CompositingCoordinatesTopDown, CompositingCoordinatesBottomUp }; - static CompositingCoordinatesOrientation compositingCoordinatesOrientation(); - - // Set the geometry orientation (top-down, or bottom-up) for this layer, which also controls sublayer geometry. - virtual void setGeometryOrientation(CompositingCoordinatesOrientation orientation) { m_geometryOrientation = orientation; } - CompositingCoordinatesOrientation geometryOrientation() const { return m_geometryOrientation; } // Flippedness of the contents of this layer. Does not affect sublayer geometry. virtual void setContentsOrientation(CompositingCoordinatesOrientation orientation) { m_contentsOrientation = orientation; } @@ -395,8 +388,7 @@ protected: bool m_drawsContent : 1; GraphicsLayerPaintingPhase m_paintingPhase; - CompositingCoordinatesOrientation m_geometryOrientation; // affects geometry of layer positions - CompositingCoordinatesOrientation m_contentsOrientation; // affects orientation of layer contents + CompositingCoordinatesOrientation m_contentsOrientation; // affects orientation of layer contents Vector<GraphicsLayer*> m_children; GraphicsLayer* m_parent; diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp index 2588d8d..b4a669c 100644 --- a/WebCore/platform/graphics/MediaPlayer.cpp +++ b/WebCore/platform/graphics/MediaPlayer.cpp @@ -48,7 +48,7 @@ #if PLATFORM(MAC) #include "MediaPlayerPrivateQTKit.h" #elif OS(WINCE) && !PLATFORM(QT) -#include "MediaPlayerPrivateWince.h" +#include "MediaPlayerPrivateWinCE.h" #elif PLATFORM(WIN) #include "MediaPlayerPrivateQuickTimeVisualContext.h" #include "MediaPlayerPrivateQuicktimeWin.h" diff --git a/WebCore/platform/graphics/Path.h b/WebCore/platform/graphics/Path.h index 9896713..43ba889 100644 --- a/WebCore/platform/graphics/Path.h +++ b/WebCore/platform/graphics/Path.h @@ -133,11 +133,6 @@ namespace WebCore { void addBezierCurveTo(const FloatPoint& controlPoint1, const FloatPoint& controlPoint2, const FloatPoint& endPoint); void addArcTo(const FloatPoint&, const FloatPoint&, float radius); void closeSubpath(); -#if PLATFORM(QT) - void closeCanvasSubpath(); -#else - void closeCanvasSubpath() { closeSubpath(); } -#endif void addArc(const FloatPoint&, float radius, float startAngle, float endAngle, bool anticlockwise); void addRect(const FloatRect&); @@ -161,10 +156,6 @@ namespace WebCore { private: PlatformPathPtr m_path; - -#if PLATFORM(QT) - int m_lastMoveToIndex; -#endif }; } diff --git a/WebCore/platform/graphics/cairo/FontCacheCairo.cpp b/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp index 5d3263e..c09dd49 100644 --- a/WebCore/platform/graphics/cairo/FontCacheCairo.cpp +++ b/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp @@ -24,6 +24,7 @@ #include "CString.h" #include "Font.h" #include "OwnPtrCairo.h" +#include "PlatformRefPtrCairo.h" #include "SimpleFontData.h" #include <wtf/Assertions.h> @@ -37,7 +38,6 @@ void FontCache::platformInit() const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) { -#if defined(USE_FREETYPE) FcResult fresult; FontPlatformData* prim = const_cast<FontPlatformData*>(&font.primaryFont()->platformData()); @@ -47,13 +47,13 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, cons return 0; if (!prim->m_fallbacks) - prim->m_fallbacks = FcFontSort(NULL, prim->m_pattern, FcTrue, NULL, &fresult); + prim->m_fallbacks = FcFontSort(0, prim->m_pattern.get(), FcTrue, 0, &fresult); FcFontSet* fs = prim->m_fallbacks; for (int i = 0; i < fs->nfont; i++) { - FcPattern* fin = FcFontRenderPrepare(NULL, prim->m_pattern, fs->fonts[i]); - cairo_font_face_t* fontFace = cairo_ft_font_face_create_for_pattern(fin); + PlatformRefPtr<FcPattern> fin = adoptPlatformRef(FcFontRenderPrepare(0, prim->m_pattern.get(), fs->fonts[i])); + cairo_font_face_t* fontFace = cairo_ft_font_face_create_for_pattern(fin.get()); FontPlatformData alternateFont(fontFace, font.fontDescription().computedPixelSize(), false, false); cairo_font_face_destroy(fontFace); alternateFont.m_pattern = fin; @@ -61,7 +61,6 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, cons if (sfd->containsCharacters(characters, length)) return sfd; } -#endif return 0; } @@ -103,7 +102,6 @@ static bool isWellKnownFontName(const AtomicString family) FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family) { -#if defined(USE_FREETYPE) // Handle generic family types specially, because fontconfig does not know them, but we have // code to fallback correctly in our platform data implementation. if (!family.length() || family.startsWith("-webkit-") @@ -115,7 +113,7 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD CString familyNameString = family.string().utf8(); const char* fcfamily = familyNameString.data(); - OwnPtr<FcPattern> pattern(FcPatternCreate()); + PlatformRefPtr<FcPattern> pattern = adoptPlatformRef(FcPatternCreate()); if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily))) return 0; @@ -130,7 +128,6 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD if (!fontSet->fonts) return 0; -#endif return new FontPlatformData(fontDescription, family); } diff --git a/WebCore/platform/graphics/cairo/FontPlatformData.h b/WebCore/platform/graphics/cairo/FontPlatformData.h index fc6b9f1..e5ffef2 100644 --- a/WebCore/platform/graphics/cairo/FontPlatformData.h +++ b/WebCore/platform/graphics/cairo/FontPlatformData.h @@ -1,11 +1,5 @@ /* - * This file is part of the internal font implementation. It should not be included by anyone other than - * FontMac.cpp, FontWin.cpp and Font.cpp. - * - * Copyright (C) 2006, 2007, 2008 Apple Inc. - * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com - * Copyright (C) 2007 Holger Hans Peter Freyther - * Copyright (C) 2007 Pioneer Research Center USA, Inc. + * Copyright (C) 2010 Igalia S.L. * All rights reserved. * * This library is free software; you can redistribute it and/or @@ -28,160 +22,12 @@ #ifndef FontPlatformData_h #define FontPlatformData_h -#include <wtf/Forward.h> -#include <cairo.h> -#include "FontDescription.h" -#include "GlyphBuffer.h" - -#if defined(USE_FREETYPE) -#include <cairo-ft.h> -#include <fontconfig/fcfreetype.h> -#elif defined(USE_PANGO) -#include <pango/pangocairo.h> -#elif PLATFORM(WIN) -#include <cairo-win32.h> -#include "RefCountedGDIHandle.h" -#include "StringImpl.h" -#else -#error "Must defined a font backend" -#endif - -#if PLATFORM(WIN) -typedef struct HFONT__* HFONT; -#endif -namespace WebCore { - -class FontPlatformData { -public: - FontPlatformData(WTF::HashTableDeletedValueType) #if defined(USE_FREETYPE) - : m_pattern(hashTableDeletedFontValue()) - , m_fallbacks(0) +#include "FontPlatformDataFreeType.h" #elif defined(USE_PANGO) - : m_context(0) - , m_font(hashTableDeletedFontValue()) +#include "FontPlatformDataPango.h" #elif PLATFORM(WIN) - : m_fontFace(0) - , m_useGDI(false) - , m_font(WTF::HashTableDeletedValue) -#else -#error "Must defined a font backend" +#include "FontPlatformDataCairoWin.h" #endif - , m_size(0) - , m_syntheticBold(false) - , m_syntheticOblique(false) - , m_scaledFont(0) - { } - FontPlatformData() -#if defined(USE_FREETYPE) - : m_pattern(0) - , m_fallbacks(0) -#elif defined(USE_PANGO) - : m_context(0) - , m_font(0) -#elif PLATFORM(WIN) - : m_fontFace(0) - , m_useGDI(false) -#else -#error "Must defined a font backend" -#endif - , m_size(0) - , m_syntheticBold(false) - , m_syntheticOblique(false) - , m_scaledFont(0) - { } - -#if PLATFORM(WIN) - FontPlatformData(HFONT, float size, bool bold, bool oblique, bool useGDI); -#else - FontPlatformData(const FontDescription&, const AtomicString& family); -#endif - - FontPlatformData(cairo_font_face_t* fontFace, float size, bool bold, bool italic); - FontPlatformData(float size, bool bold, bool italic); - FontPlatformData(const FontPlatformData&); - - ~FontPlatformData(); - -#if !PLATFORM(WIN) - static bool init(); -#else - HFONT hfont() const { return m_font->handle(); } - bool useGDI() const { return m_useGDI; } - cairo_font_face_t* fontFace() const { return m_fontFace; } -#endif - - bool isFixedPitch(); - float size() const { return m_size; } - void setSize(float size) { m_size = size; } - bool syntheticBold() const { return m_syntheticBold; } - bool syntheticOblique() const { return m_syntheticOblique; } - - cairo_scaled_font_t* scaledFont() const { return m_scaledFont; } - - unsigned hash() const - { -#if PLATFORM(WIN) - return m_font->hash(); -#else -#if defined(USE_FREETYPE) - if (m_pattern) - return FcPatternHash(m_pattern); -#endif - uintptr_t hashCodes[1] = { reinterpret_cast<uintptr_t>(m_scaledFont) }; - return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar)); -#endif - } - - bool operator==(const FontPlatformData&) const; - FontPlatformData& operator=(const FontPlatformData&); - bool isHashTableDeletedValue() const - { -#if defined(USE_FREETYPE) - return m_pattern == hashTableDeletedFontValue(); -#elif defined(USE_PANGO) - return m_font == hashTableDeletedFontValue(); -#elif PLATFORM(WIN) - return m_font.isHashTableDeletedValue(); -#endif - } - -#ifndef NDEBUG - String description() const; -#endif - -#if defined(USE_FREETYPE) - FcPattern* m_pattern; - FcFontSet* m_fallbacks; -#elif defined(USE_PANGO) - static PangoFontMap* m_fontMap; - static GHashTable* m_hashTable; - - PangoContext* m_context; - PangoFont* m_font; -#elif PLATFORM(WIN) -private: - void platformDataInit(HFONT, float size, HDC, WCHAR* faceName); - - RefPtr<RefCountedGDIHandle<HFONT> > m_font; - cairo_font_face_t* m_fontFace; - bool m_useGDI; -#else -#error "Must defined a font backend" -#endif - float m_size; - bool m_syntheticBold; - bool m_syntheticOblique; - cairo_scaled_font_t* m_scaledFont; -private: -#if defined(USE_FREETYPE) - static FcPattern *hashTableDeletedFontValue() { return reinterpret_cast<FcPattern*>(-1); } -#elif defined(USE_PANGO) - static PangoFont *hashTableDeletedFontValue() { return reinterpret_cast<PangoFont*>(-1); } -#endif -}; - -} - -#endif +#endif // FontPlatformData_h diff --git a/WebCore/platform/graphics/cairo/FontPlatformDataCairo.cpp b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.cpp index 1f94f5a..7968966 100644 --- a/WebCore/platform/graphics/cairo/FontPlatformDataCairo.cpp +++ b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.cpp @@ -39,12 +39,10 @@ namespace WebCore { FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const AtomicString& familyName) - : m_pattern(0) - , m_fallbacks(0) + : m_fallbacks(0) , m_size(fontDescription.computedPixelSize()) , m_syntheticBold(false) , m_syntheticOblique(false) - , m_scaledFont(0) { FontPlatformData::init(); @@ -61,14 +59,14 @@ FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const int type = fontDescription.genericFamily(); - FcPattern* pattern = FcPatternCreate(); + PlatformRefPtr<FcPattern> pattern = adoptPlatformRef(FcPatternCreate()); cairo_font_face_t* fontFace; static const cairo_font_options_t* defaultOptions = cairo_font_options_create(); const cairo_font_options_t* options = NULL; cairo_matrix_t fontMatrix; - if (!FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily))) - goto freePattern; + if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily))) + return; switch (type) { case FontDescription::SerifFamily: @@ -89,31 +87,31 @@ FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const break; } - if (fcfamily && !FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily))) - goto freePattern; - if (!FcPatternAddInteger(pattern, FC_WEIGHT, fcweight)) - goto freePattern; - if (!FcPatternAddInteger(pattern, FC_SLANT, fcslant)) - goto freePattern; - if (!FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fcsize)) - goto freePattern; + if (fcfamily && !FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily))) + return; + if (!FcPatternAddInteger(pattern.get(), FC_WEIGHT, fcweight)) + return; + if (!FcPatternAddInteger(pattern.get(), FC_SLANT, fcslant)) + return; + if (!FcPatternAddDouble(pattern.get(), FC_PIXEL_SIZE, fcsize)) + return; - FcConfigSubstitute(NULL, pattern, FcMatchPattern); - FcDefaultSubstitute(pattern); + FcConfigSubstitute(0, pattern.get(), FcMatchPattern); + FcDefaultSubstitute(pattern.get()); FcResult fcresult; - m_pattern = FcFontMatch(NULL, pattern, &fcresult); + m_pattern = adoptPlatformRef(FcFontMatch(0, pattern.get(), &fcresult)); // FIXME: should we set some default font? if (!m_pattern) - goto freePattern; - fontFace = cairo_ft_font_face_create_for_pattern(m_pattern); + return; + fontFace = cairo_ft_font_face_create_for_pattern(m_pattern.get()); cairo_matrix_t ctm; cairo_matrix_init_scale(&fontMatrix, fontDescription.computedPixelSize(), fontDescription.computedPixelSize()); cairo_matrix_init_identity(&ctm); #if !PLATFORM(EFL) || ENABLE(GLIB_SUPPORT) if (GdkScreen* screen = gdk_screen_get_default()) - options = gdk_screen_get_font_options(screen); +gdk_screen_get_font_options(screen); #endif // gdk_screen_get_font_options() returns NULL if no default options are @@ -121,30 +119,23 @@ FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const if (!options) options = defaultOptions; - m_scaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options); + m_scaledFont = adoptPlatformRef(cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options)); cairo_font_face_destroy(fontFace); - -freePattern: - FcPatternDestroy(pattern); } FontPlatformData::FontPlatformData(float size, bool bold, bool italic) - : m_pattern(0) - , m_fallbacks(0) + : m_fallbacks(0) , m_size(size) , m_syntheticBold(bold) , m_syntheticOblique(italic) - , m_scaledFont(0) { } FontPlatformData::FontPlatformData(cairo_font_face_t* fontFace, float size, bool bold, bool italic) - : m_pattern(0) - , m_fallbacks(0) + : m_fallbacks(0) , m_size(size) , m_syntheticBold(bold) , m_syntheticOblique(italic) - , m_scaledFont(0) { cairo_matrix_t fontMatrix; cairo_matrix_init_scale(&fontMatrix, size, size); @@ -163,7 +154,7 @@ FontPlatformData::FontPlatformData(cairo_font_face_t* fontFace, float size, bool if (!options) options = defaultOptions; - m_scaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options); + m_scaledFont = adoptPlatformRef(cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options)); } FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other) @@ -175,17 +166,7 @@ FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other) m_size = other.m_size; m_syntheticBold = other.m_syntheticBold; m_syntheticOblique = other.m_syntheticOblique; - - if (other.m_scaledFont) - cairo_scaled_font_reference(other.m_scaledFont); - if (m_scaledFont) - cairo_scaled_font_destroy(m_scaledFont); m_scaledFont = other.m_scaledFont; - - if (other.m_pattern) - FcPatternReference(other.m_pattern); - if (m_pattern) - FcPatternDestroy(m_pattern); m_pattern = other.m_pattern; if (m_fallbacks) { @@ -198,9 +179,7 @@ FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other) } FontPlatformData::FontPlatformData(const FontPlatformData& other) - : m_pattern(0) - , m_fallbacks(0) - , m_scaledFont(0) + : m_fallbacks(0) { *this = other; } @@ -220,18 +199,10 @@ bool FontPlatformData::init() FontPlatformData::~FontPlatformData() { - if (m_pattern && ((FcPattern*)-1 != m_pattern)) { - FcPatternDestroy(m_pattern); - m_pattern = 0; - } - if (m_fallbacks) { FcFontSetDestroy(m_fallbacks); m_fallbacks = 0; } - - if (m_scaledFont) - cairo_scaled_font_destroy(m_scaledFont); } bool FontPlatformData::isFixedPitch() @@ -241,7 +212,7 @@ bool FontPlatformData::isFixedPitch() return false; int spacing; - if (FcPatternGetInteger(m_pattern, FC_SPACING, 0, &spacing) == FcResultMatch) + if (FcPatternGetInteger(m_pattern.get(), FC_SPACING, 0, &spacing) == FcResultMatch) return spacing == FC_MONO; return false; } @@ -250,10 +221,9 @@ bool FontPlatformData::operator==(const FontPlatformData& other) const { if (m_pattern == other.m_pattern) return true; - if (m_pattern == 0 || m_pattern == reinterpret_cast<FcPattern*>(-1) - || other.m_pattern == 0 || other.m_pattern == reinterpret_cast<FcPattern*>(-1)) + if (!m_pattern || m_pattern.isHashTableDeletedValue() || !other.m_pattern || other.m_pattern.isHashTableDeletedValue()) return false; - return FcPatternEqual(m_pattern, other.m_pattern); + return FcPatternEqual(m_pattern.get(), other.m_pattern.get()); } #ifndef NDEBUG diff --git a/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h new file mode 100644 index 0000000..987a684 --- /dev/null +++ b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2006, 2007, 2008 Apple Inc. + * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com + * Copyright (C) 2007 Holger Hans Peter Freyther + * Copyright (C) 2007 Pioneer Research Center USA, Inc. + * All rights reserved. + * + * 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 FontPlatformDataFreeType_h +#define FontPlatformDataFreeType_h + +#include "FontDescription.h" +#include "GlyphBuffer.h" +#include "HashFunctions.h" +#include "PlatformRefPtrCairo.h" +#include <cairo-ft.h> +#include <cairo.h> +#include <fontconfig/fcfreetype.h> +#include <wtf/Forward.h> + +namespace WebCore { + +class FontPlatformData { +public: + FontPlatformData(WTF::HashTableDeletedValueType) + : m_fallbacks(0) + , m_size(0) + , m_syntheticBold(false) + , m_syntheticOblique(false) + , m_scaledFont(WTF::HashTableDeletedValue) + { } + + FontPlatformData() + : m_fallbacks(0) + , m_size(0) + , m_syntheticBold(false) + , m_syntheticOblique(false) + { } + + FontPlatformData(const FontDescription&, const AtomicString& family); + FontPlatformData(cairo_font_face_t* fontFace, float size, bool bold, bool italic); + FontPlatformData(float size, bool bold, bool italic); + FontPlatformData(const FontPlatformData&); + + ~FontPlatformData(); + + static bool init(); + bool isFixedPitch(); + float size() const { return m_size; } + void setSize(float size) { m_size = size; } + bool syntheticBold() const { return m_syntheticBold; } + bool syntheticOblique() const { return m_syntheticOblique; } + + cairo_scaled_font_t* scaledFont() const { return m_scaledFont.get(); } + + unsigned hash() const + { + return PtrHash<cairo_scaled_font_t*>::hash(m_scaledFont.get()); + } + + bool operator==(const FontPlatformData&) const; + FontPlatformData& operator=(const FontPlatformData&); + bool isHashTableDeletedValue() const + { + return m_scaledFont.isHashTableDeletedValue(); + } + +#ifndef NDEBUG + String description() const; +#endif + + PlatformRefPtr<FcPattern> m_pattern; + FcFontSet* m_fallbacks; + float m_size; + bool m_syntheticBold; + bool m_syntheticOblique; + PlatformRefPtr<cairo_scaled_font_t> m_scaledFont; +}; + +} + +#endif // FontPlatformDataFreeType_h diff --git a/WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp b/WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp index 7c9ffe6..26da68d 100644 --- a/WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp +++ b/WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp @@ -42,7 +42,7 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b if (bufferLength > GlyphPage::size) return false; - FT_Face face = cairo_ft_scaled_font_lock_face(fontData->platformData().m_scaledFont); + FT_Face face = cairo_ft_scaled_font_lock_face(fontData->platformData().m_scaledFont.get()); if (!face) return false; @@ -57,7 +57,7 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b } } - cairo_ft_scaled_font_unlock_face(fontData->platformData().m_scaledFont); + cairo_ft_scaled_font_unlock_face(fontData->platformData().m_scaledFont.get()); return haveGlyphs; } diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp index 283e75a..5de7e1f 100644 --- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp +++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp @@ -38,6 +38,7 @@ #include "FEGaussianBlur.h" #include "FloatRect.h" #include "Font.h" +#include "OwnPtrCairo.h" #include "ImageBuffer.h" #include "ImageBufferFilter.h" #include "IntRect.h" @@ -201,7 +202,6 @@ static inline void drawPathShadow(GraphicsContext* context, GraphicsContextPriva // Calculate filter values to create appropriate shadow. cairo_t* cr = context->platformContext(); - cairo_path_t* path = cairo_copy_path(cr); double x0, x1, y0, y1; if (strokeShadow) cairo_stroke_extents(cr, &x0, &y0, &x1, &y1); @@ -214,15 +214,32 @@ static inline void drawPathShadow(GraphicsContext* context, GraphicsContextPriva float radius = 0; GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowOffset, shadowBlur); + cairo_clip_extents(cr, &x0, &y0, &x1, &y1); + FloatRect clipRect(x0, y0, x1 - x0, y1 - y0); + + FloatPoint rectLocation = shadowRect.location(); + + // Reduce the shadow rect using the clip area. + if (!clipRect.contains(shadowRect)) { + shadowRect.intersect(clipRect); + if (shadowRect.isEmpty()) + return; + shadowRect.inflate(radius); + shadowBufferSize = IntSize(shadowRect.width(), shadowRect.height()); + } + + shadowOffset = rectLocation - shadowRect.location(); + // Create suitably-sized ImageBuffer to hold the shadow. OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize); // Draw shadow into a new ImageBuffer. cairo_t* shadowContext = shadowBuffer->context()->platformContext(); copyContextProperties(cr, shadowContext); - cairo_translate(shadowContext, -rect.x() + radius, -rect.y() + radius); + cairo_translate(shadowContext, -rect.x() + radius + shadowOffset.width(), -rect.y() + radius + shadowOffset.height()); cairo_new_path(shadowContext); - cairo_append_path(shadowContext, path); + OwnPtr<cairo_path_t> path(cairo_copy_path(cr)); + cairo_append_path(shadowContext, path.get()); if (fillShadow) setPlatformFill(context, shadowContext, gcp); @@ -624,6 +641,12 @@ void GraphicsContext::fillRect(const FloatRect& rect) static void drawBorderlessRectShadow(GraphicsContext* context, const FloatRect& rect, const Color& rectColor) { #if ENABLE(FILTERS) + FloatSize shadowOffset; + float shadowBlur; + Color shadowColor; + if (!context->getShadow(shadowOffset, shadowBlur, shadowColor)) + return; + AffineTransform transform = context->getCTM(); // drawTiledShadow still does not work with rotations. if ((transform.isIdentityOrTranslationOrFlipped())) { @@ -638,13 +661,6 @@ static void drawBorderlessRectShadow(GraphicsContext* context, const FloatRect& return; } - FloatSize shadowOffset; - float shadowBlur; - Color shadowColor; - - if (!context->getShadow(shadowOffset, shadowBlur, shadowColor)) - return; - IntSize shadowBufferSize; FloatRect shadowRect; float radius = 0; @@ -957,18 +973,20 @@ PlatformRefPtr<cairo_surface_t> GraphicsContext::createShadowMask(PassOwnPtr<Ima return buffer->m_data.m_surface; FloatPoint blurRadius = FloatPoint(radius, radius); - float sd = FEGaussianBlur::calculateStdDeviation(radius); - if (!sd) + float stdDeviation = FEGaussianBlur::calculateStdDeviation(radius); + if (!stdDeviation) return buffer->m_data.m_surface; // create filter RefPtr<Filter> filter = ImageBufferFilter::create(); filter->setSourceImage(buffer); RefPtr<FilterEffect> source = SourceGraphic::create(); - source->setScaledSubRegion(FloatRect(FloatPoint(), shadowRect.size())); + source->setRepaintRectInLocalCoordinates(FloatRect(FloatPoint(), shadowRect.size())); source->setIsAlphaImage(true); - RefPtr<FilterEffect> blur = FEGaussianBlur::create(source.get(), sd, sd); - blur->setScaledSubRegion(FloatRect(FloatPoint(), shadowRect.size())); + RefPtr<FilterEffect> blur = FEGaussianBlur::create(stdDeviation, stdDeviation); + FilterEffectVector& inputEffects = blur->inputEffects(); + inputEffects.append(source.get()); + blur->setRepaintRectInLocalCoordinates(FloatRect(FloatPoint(), shadowRect.size())); blur->apply(filter.get()); return blur->resultImage()->m_data.m_surface; #endif diff --git a/WebCore/platform/graphics/cairo/OwnPtrCairo.cpp b/WebCore/platform/graphics/cairo/OwnPtrCairo.cpp index 9be8670..94f6809 100644 --- a/WebCore/platform/graphics/cairo/OwnPtrCairo.cpp +++ b/WebCore/platform/graphics/cairo/OwnPtrCairo.cpp @@ -25,15 +25,11 @@ #include <fontconfig/fcfreetype.h> #endif +#include <cairo.h> + namespace WTF { #if defined(USE_FREETYPE) -template <> void deleteOwnedPtr<FcPattern>(FcPattern* ptr) -{ - if (ptr) - FcPatternDestroy(ptr); -} - template <> void deleteOwnedPtr<FcObjectSet>(FcObjectSet* ptr) { if (ptr) @@ -47,4 +43,10 @@ template <> void deleteOwnedPtr<FcFontSet>(FcFontSet* ptr) } #endif +template <> void deleteOwnedPtr<cairo_path_t>(cairo_path_t* ptr) +{ + if (ptr) + cairo_path_destroy(ptr); +} + } // namespace WTF diff --git a/WebCore/platform/graphics/cairo/OwnPtrCairo.h b/WebCore/platform/graphics/cairo/OwnPtrCairo.h index 29f4562..035d80e 100644 --- a/WebCore/platform/graphics/cairo/OwnPtrCairo.h +++ b/WebCore/platform/graphics/cairo/OwnPtrCairo.h @@ -23,19 +23,21 @@ #include "OwnPtr.h" #if defined(USE_FREETYPE) -typedef struct _FcPattern FcPattern; typedef struct _FcObjectSet FcObjectSet; typedef struct _FcFontSet FcFontSet; #endif +typedef struct cairo_path cairo_path_t; + namespace WTF { #if defined(USE_FREETYPE) -template <> void deleteOwnedPtr<FcPattern>(FcPattern*); template <> void deleteOwnedPtr<FcObjectSet>(FcObjectSet*); template <> void deleteOwnedPtr<FcFontSet>(FcFontSet*); #endif +template <> void deleteOwnedPtr<cairo_path_t>(cairo_path_t*); + } // namespace WTF #endif diff --git a/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp b/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp index 6870560..aa466f9 100644 --- a/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp +++ b/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp @@ -21,6 +21,11 @@ #include <cairo.h> +#if defined(USE_FREETYPE) +#include <cairo-ft.h> +#include <fontconfig/fcfreetype.h> +#endif + namespace WTF { template <> cairo_t* refPlatformPtr(cairo_t* ptr) @@ -49,4 +54,32 @@ template <> void derefPlatformPtr(cairo_surface_t* ptr) cairo_surface_destroy(ptr); } +template <> cairo_scaled_font_t* refPlatformPtr(cairo_scaled_font_t* ptr) +{ + if (ptr) + cairo_scaled_font_reference(ptr); + return ptr; +} + +template <> void derefPlatformPtr(cairo_scaled_font_t* ptr) +{ + if (ptr) + cairo_scaled_font_destroy(ptr); +} + +#if defined(USE_FREETYPE) +template <> FcPattern* refPlatformPtr(FcPattern* ptr) +{ + if (ptr) + FcPatternReference(ptr); + return ptr; +} + +template <> void derefPlatformPtr(FcPattern* ptr) +{ + if (ptr) + FcPatternDestroy(ptr); +} +#endif + } diff --git a/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h b/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h index 51d8fa9..4b45c1b 100644 --- a/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h +++ b/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h @@ -24,6 +24,11 @@ typedef struct _cairo cairo_t; typedef struct _cairo_surface cairo_surface_t; +typedef struct _cairo_scaled_font cairo_scaled_font_t; + +#if defined(USE_FREETYPE) +typedef struct _FcPattern FcPattern; +#endif namespace WTF { @@ -33,6 +38,14 @@ template <> void derefPlatformPtr(cairo_t* ptr); template <> cairo_surface_t* refPlatformPtr(cairo_surface_t* ptr); template <> void derefPlatformPtr(cairo_surface_t* ptr); +template <> cairo_scaled_font_t* refPlatformPtr(cairo_scaled_font_t*); +template <> void derefPlatformPtr(cairo_scaled_font_t*); + +#if defined(USE_FREETYPE) +template <> FcPattern* refPlatformPtr(FcPattern*); +template <> void derefPlatformPtr(FcPattern*); +#endif + } #endif diff --git a/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp b/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp index 0055078..fd85d6f 100644 --- a/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp +++ b/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp @@ -47,7 +47,7 @@ void SimpleFontData::platformInit() { cairo_font_extents_t font_extents; cairo_text_extents_t text_extents; - cairo_scaled_font_extents(m_platformData.m_scaledFont, &font_extents); + cairo_scaled_font_extents(m_platformData.m_scaledFont.get(), &font_extents); m_ascent = static_cast<int>(lroundf(font_extents.ascent)); m_descent = static_cast<int>(lroundf(font_extents.descent)); m_lineSpacing = static_cast<int>(lroundf(font_extents.height)); @@ -58,9 +58,9 @@ void SimpleFontData::platformInit() // while we figure out what's going on. if (m_lineSpacing < m_ascent + m_descent) m_lineSpacing = m_ascent + m_descent; - cairo_scaled_font_text_extents(m_platformData.m_scaledFont, "x", &text_extents); + cairo_scaled_font_text_extents(m_platformData.m_scaledFont.get(), "x", &text_extents); m_xHeight = text_extents.height; - cairo_scaled_font_text_extents(m_platformData.m_scaledFont, " ", &text_extents); + cairo_scaled_font_text_extents(m_platformData.m_scaledFont.get(), " ", &text_extents); m_spaceWidth = static_cast<float>(text_extents.x_advance); m_lineGap = m_lineSpacing - m_ascent - m_descent; m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f; @@ -92,19 +92,19 @@ SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDes bool SimpleFontData::containsCharacters(const UChar* characters, int length) const { - FT_Face face = cairo_ft_scaled_font_lock_face(m_platformData.m_scaledFont); + FT_Face face = cairo_ft_scaled_font_lock_face(m_platformData.m_scaledFont.get()); if (!face) return false; for (int i = 0; i < length; i++) { if (FcFreeTypeCharIndex(face, characters[i]) == 0) { - cairo_ft_scaled_font_unlock_face(m_platformData.m_scaledFont); + cairo_ft_scaled_font_unlock_face(m_platformData.m_scaledFont.get()); return false; } } - cairo_ft_scaled_font_unlock_face(m_platformData.m_scaledFont); + cairo_ft_scaled_font_unlock_face(m_platformData.m_scaledFont.get()); return true; } @@ -125,10 +125,10 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const cairo_glyph_t cglyph = { glyph, 0, 0 }; cairo_text_extents_t extents; - cairo_scaled_font_glyph_extents(m_platformData.m_scaledFont, &cglyph, 1, &extents); + cairo_scaled_font_glyph_extents(m_platformData.m_scaledFont.get(), &cglyph, 1, &extents); float w = (float)m_spaceWidth; - if (cairo_scaled_font_status(m_platformData.m_scaledFont) == CAIRO_STATUS_SUCCESS && extents.x_advance != 0) + if (cairo_scaled_font_status(m_platformData.m_scaledFont.get()) == CAIRO_STATUS_SUCCESS && extents.x_advance) w = (float)extents.x_advance; return w; diff --git a/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp b/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp index 9826c3e..c2cde19 100644 --- a/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp +++ b/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp @@ -35,8 +35,7 @@ #include "Canvas2DLayerChromium.h" #include "DrawingBuffer.h" - -#include <GLES2/gl2.h> +#include "GraphicsContext3D.h" namespace WebCore { @@ -54,7 +53,7 @@ Canvas2DLayerChromium::Canvas2DLayerChromium(DrawingBuffer* drawingBuffer, Graph Canvas2DLayerChromium::~Canvas2DLayerChromium() { if (m_textureId) - glDeleteTextures(1, &m_textureId); + layerRendererContext()->deleteTexture(m_textureId); } void Canvas2DLayerChromium::updateContents() @@ -62,26 +61,27 @@ void Canvas2DLayerChromium::updateContents() if (!m_drawingBuffer) return; if (m_textureChanged) { // We have to generate a new backing texture. + GraphicsContext3D* context = layerRendererContext(); if (m_textureId) - glDeleteTextures(1, &m_textureId); - glGenTextures(1, &m_textureId); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_textureId); + context->deleteTexture(m_textureId); + m_textureId = context->createTexture(); + context->activeTexture(GraphicsContext3D::TEXTURE0); + context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId); IntSize size = m_drawingBuffer->size(); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - // Set the min-mag filters to linear and wrap modes to GL_CLAMP_TO_EDGE + context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, size.width(), size.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0); + // Set the min-mag filters to linear and wrap modes to GraphicsContext3D::CLAMP_TO_EDGE // to get around NPOT texture limitations of GLES. - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR); + context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR); + context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); + context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); m_textureChanged = false; - // FIXME: The glFinish() here is required because we have to make sure that the texture created in this + // FIXME: The finish() here is required because we have to make sure that the texture created in this // context (the compositor context) is actually created by the service side before the child context - // attempts to use it (in publishToPlatformLayer). glFinish() is currently the only call with strong + // attempts to use it (in publishToPlatformLayer). finish() is currently the only call with strong // enough semantics to promise this, but is actually much stronger. Ideally we'd do something like // inserting a fence here and waiting for it before trying to publish. - glFinish(); + context->finish(); } // Update the contents of the texture used by the compositor. if (m_contentsDirty) { diff --git a/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp b/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp index 56a7262..4aef25b 100644 --- a/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp +++ b/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp @@ -34,16 +34,16 @@ #include "CanvasLayerChromium.h" +#include "GraphicsContext3D.h" #include "LayerRendererChromium.h" -#include <GLES2/gl2.h> - namespace WebCore { unsigned CanvasLayerChromium::m_shaderProgramId = 0; -CanvasLayerChromium::SharedValues::SharedValues() - : m_canvasShaderProgram(0) +CanvasLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) + : m_context(context) + , m_canvasShaderProgram(0) , m_shaderSamplerLocation(-1) , m_shaderMatrixLocation(-1) , m_shaderAlphaLocation(-1) @@ -73,15 +73,15 @@ CanvasLayerChromium::SharedValues::SharedValues() " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n" "} \n"; - m_canvasShaderProgram = createShaderProgram(vertexShaderString, fragmentShaderString); + m_canvasShaderProgram = createShaderProgram(m_context, vertexShaderString, fragmentShaderString); if (!m_canvasShaderProgram) { LOG_ERROR("CanvasLayerChromium: Failed to create shader program"); return; } - m_shaderSamplerLocation = glGetUniformLocation(m_canvasShaderProgram, "s_texture"); - m_shaderMatrixLocation = glGetUniformLocation(m_canvasShaderProgram, "matrix"); - m_shaderAlphaLocation = glGetUniformLocation(m_canvasShaderProgram, "alpha"); + m_shaderSamplerLocation = m_context->getUniformLocation(m_canvasShaderProgram, "s_texture"); + m_shaderMatrixLocation = m_context->getUniformLocation(m_canvasShaderProgram, "matrix"); + m_shaderAlphaLocation = m_context->getUniformLocation(m_canvasShaderProgram, "alpha"); ASSERT(m_shaderSamplerLocation != -1); ASSERT(m_shaderMatrixLocation != -1); ASSERT(m_shaderAlphaLocation != -1); @@ -92,7 +92,7 @@ CanvasLayerChromium::SharedValues::SharedValues() CanvasLayerChromium::SharedValues::~SharedValues() { if (m_canvasShaderProgram) - GLC(glDeleteProgram(m_canvasShaderProgram)); + GLC(m_context, m_context->deleteProgram(m_canvasShaderProgram)); } CanvasLayerChromium::CanvasLayerChromium(GraphicsLayerChromium* owner) @@ -111,11 +111,12 @@ void CanvasLayerChromium::draw() ASSERT(layerRenderer()); const CanvasLayerChromium::SharedValues* sv = layerRenderer()->canvasLayerSharedValues(); ASSERT(sv && sv->initialized()); - GLC(glActiveTexture(GL_TEXTURE0)); - GLC(glBindTexture(GL_TEXTURE_2D, m_textureId)); + GraphicsContext3D* context = layerRendererContext(); + GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); + GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId)); layerRenderer()->useShader(sv->canvasShaderProgram()); - GLC(glUniform1i(sv->shaderSamplerLocation(), 0)); - drawTexturedQuad(layerRenderer()->projectionMatrix(), drawTransform(), + GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0)); + drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), bounds().width(), bounds().height(), drawOpacity(), sv->shaderMatrixLocation(), sv->shaderAlphaLocation()); diff --git a/WebCore/platform/graphics/chromium/CanvasLayerChromium.h b/WebCore/platform/graphics/chromium/CanvasLayerChromium.h index d591c73..6520b55 100644 --- a/WebCore/platform/graphics/chromium/CanvasLayerChromium.h +++ b/WebCore/platform/graphics/chromium/CanvasLayerChromium.h @@ -47,7 +47,7 @@ public: class SharedValues { public: - SharedValues(); + explicit SharedValues(GraphicsContext3D*); ~SharedValues(); unsigned canvasShaderProgram() const { return m_canvasShaderProgram; } @@ -57,6 +57,7 @@ public: bool initialized() const { return m_initialized; } private: + GraphicsContext3D* m_context; unsigned m_canvasShaderProgram; int m_shaderSamplerLocation; int m_shaderMatrixLocation; diff --git a/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp b/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp index 48119bb..86be8da 100644 --- a/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp +++ b/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp @@ -34,6 +34,7 @@ #include "ContentLayerChromium.h" +#include "GraphicsContext3D.h" #include "LayerRendererChromium.h" #include "RenderLayerBacking.h" @@ -47,12 +48,11 @@ #include <CoreGraphics/CGBitmapContext.h> #endif -#include <GLES2/gl2.h> - namespace WebCore { -ContentLayerChromium::SharedValues::SharedValues() - : m_contentShaderProgram(0) +ContentLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) + : m_context(context) + , m_contentShaderProgram(0) , m_shaderSamplerLocation(-1) , m_shaderMatrixLocation(-1) , m_shaderAlphaLocation(-1) @@ -71,8 +71,8 @@ ContentLayerChromium::SharedValues::SharedValues() "} \n"; // Note differences between Skia and Core Graphics versions: - // - Skia uses BGRA and origin is upper left - // - Core Graphics uses RGBA and origin is lower left + // - Skia uses BGRA + // - Core Graphics uses RGBA char fragmentShaderString[] = "precision mediump float; \n" "varying vec2 v_texCoord; \n" @@ -80,26 +80,25 @@ ContentLayerChromium::SharedValues::SharedValues() "uniform float alpha; \n" "void main() \n" "{ \n" -#if PLATFORM(SKIA) " vec4 texColor = texture2D(s_texture, v_texCoord); \n" +#if PLATFORM(SKIA) " gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha; \n" #elif PLATFORM(CG) - " vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); \n" " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n" #else #error "Need to implement for your platform." #endif "} \n"; - m_contentShaderProgram = createShaderProgram(vertexShaderString, fragmentShaderString); + m_contentShaderProgram = createShaderProgram(m_context, vertexShaderString, fragmentShaderString); if (!m_contentShaderProgram) { LOG_ERROR("ContentLayerChromium: Failed to create shader program"); return; } - m_shaderSamplerLocation = glGetUniformLocation(m_contentShaderProgram, "s_texture"); - m_shaderMatrixLocation = glGetUniformLocation(m_contentShaderProgram, "matrix"); - m_shaderAlphaLocation = glGetUniformLocation(m_contentShaderProgram, "alpha"); + m_shaderSamplerLocation = m_context->getUniformLocation(m_contentShaderProgram, "s_texture"); + m_shaderMatrixLocation = m_context->getUniformLocation(m_contentShaderProgram, "matrix"); + m_shaderAlphaLocation = m_context->getUniformLocation(m_contentShaderProgram, "alpha"); ASSERT(m_shaderSamplerLocation != -1); ASSERT(m_shaderMatrixLocation != -1); ASSERT(m_shaderAlphaLocation != -1); @@ -110,7 +109,7 @@ ContentLayerChromium::SharedValues::SharedValues() ContentLayerChromium::SharedValues::~SharedValues() { if (m_contentShaderProgram) - GLC(glDeleteProgram(m_contentShaderProgram)); + GLC(m_context, m_context->deleteProgram(m_contentShaderProgram)); } @@ -128,7 +127,7 @@ ContentLayerChromium::ContentLayerChromium(GraphicsLayerChromium* owner) ContentLayerChromium::~ContentLayerChromium() { if (m_contentsTexture) - GLC(glDeleteTextures(1, &m_contentsTexture)); + GLC(layerRendererContext(), layerRendererContext()->deleteTexture(m_contentsTexture)); } @@ -207,11 +206,13 @@ void ContentLayerChromium::updateContents() dirtyRect.width(), dirtyRect.height(), 8, rowBytes, colorSpace.get(), kCGImageAlphaPremultipliedLast)); + CGContextTranslateCTM(contextCG.get(), 0, dirtyRect.height()); + CGContextScaleCTM(contextCG.get(), 1, -1); GraphicsContext graphicsContext(contextCG.get()); LocalCurrentGraphicsContext scopedNSGraphicsContext(&graphicsContext); - // Translate the graphics contxt into the coordinate system of the dirty rect. + // Translate the graphics context into the coordinate system of the dirty rect. graphicsContext.translate(-dirtyRect.x(), -dirtyRect.y()); m_owner->paintGraphicsLayerContents(graphicsContext, dirtyRect); @@ -235,30 +236,21 @@ void ContentLayerChromium::updateTextureRect(void* pixels, const IntSize& bitmap if (!pixels) return; - glBindTexture(GL_TEXTURE_2D, textureId); + GraphicsContext3D* context = layerRendererContext(); + context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId); // If the texture id or size changed since last time then we need to tell GL // to re-allocate a texture. if (m_contentsTexture != textureId || requiredTextureSize != m_allocatedTextureSize) { ASSERT(bitmapSize == requiredTextureSize); - GLC(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, requiredTextureSize.width(), requiredTextureSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels)); + GLC(context, context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, requiredTextureSize.width(), requiredTextureSize.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels)); m_contentsTexture = textureId; m_allocatedTextureSize = requiredTextureSize; } else { ASSERT(updateRect.width() <= m_allocatedTextureSize.width() && updateRect.height() <= m_allocatedTextureSize.height()); ASSERT(updateRect.width() == bitmapSize.width() && updateRect.height() == bitmapSize.height()); -#if PLATFORM(CG) - // The origin is at the lower left in Core Graphics' coordinate system. We need to correct for this here. - GLC(glTexSubImage2D(GL_TEXTURE_2D, 0, - updateRect.x(), m_allocatedTextureSize.height() - updateRect.height() - updateRect.y(), - updateRect.width(), updateRect.height(), - GL_RGBA, GL_UNSIGNED_BYTE, pixels)); -#elif PLATFORM(SKIA) - GLC(glTexSubImage2D(GL_TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GL_RGBA, GL_UNSIGNED_BYTE, pixels)); -#else -#error "Need to implement for your platform." -#endif + GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels)); } m_dirtyRect.setSize(FloatSize()); @@ -273,11 +265,12 @@ void ContentLayerChromium::draw() ASSERT(layerRenderer()); const ContentLayerChromium::SharedValues* sv = layerRenderer()->contentLayerSharedValues(); ASSERT(sv && sv->initialized()); - GLC(glActiveTexture(GL_TEXTURE0)); - GLC(glBindTexture(GL_TEXTURE_2D, m_contentsTexture)); + GraphicsContext3D* context = layerRendererContext(); + GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); + GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_contentsTexture)); layerRenderer()->useShader(sv->contentShaderProgram()); - GLC(glUniform1i(sv->shaderSamplerLocation(), 0)); - drawTexturedQuad(layerRenderer()->projectionMatrix(), drawTransform(), + GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0)); + drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), bounds().width(), bounds().height(), drawOpacity(), sv->shaderMatrixLocation(), sv->shaderAlphaLocation()); } diff --git a/WebCore/platform/graphics/chromium/ContentLayerChromium.h b/WebCore/platform/graphics/chromium/ContentLayerChromium.h index 3e15372..42a77c7 100644 --- a/WebCore/platform/graphics/chromium/ContentLayerChromium.h +++ b/WebCore/platform/graphics/chromium/ContentLayerChromium.h @@ -44,7 +44,7 @@ class ContentLayerChromium : public LayerChromium { public: static PassRefPtr<ContentLayerChromium> create(GraphicsLayerChromium* owner = 0); - ~ContentLayerChromium(); + virtual ~ContentLayerChromium(); virtual void updateContents(); virtual void draw(); @@ -55,7 +55,7 @@ public: // context). class SharedValues { public: - SharedValues(); + explicit SharedValues(GraphicsContext3D*); ~SharedValues(); unsigned contentShaderProgram() const { return m_contentShaderProgram; } @@ -65,6 +65,7 @@ public: int initialized() const { return m_initialized; } private: + GraphicsContext3D* m_context; unsigned m_contentShaderProgram; int m_shaderSamplerLocation; int m_shaderMatrixLocation; diff --git a/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp b/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp index 64981ee..9ce0efe 100644 --- a/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp +++ b/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp @@ -39,12 +39,6 @@ #include "Canvas2DLayerChromium.h" #endif -#include <GLES2/gl2.h> -#ifndef GL_GLEXT_PROTOTYPES -#define GL_GLEXT_PROTOTYPES 1 -#endif -#include <GLES2/gl2ext.h> - namespace WebCore { struct DrawingBufferInternal { @@ -105,8 +99,8 @@ void DrawingBuffer::publishToPlatformLayer() // happens before the compositor draws. This means we might draw stale frames sometimes. Ideally this // would insert a fence into the child command stream that the compositor could wait for. m_context->makeContextCurrent(); - glCopyTextureToParentTexture(m_internal->offscreenColorTexture, parentTexture); - glFlush(); + m_context->copyTextureToParentTextureCHROMIUM(m_internal->offscreenColorTexture, parentTexture); + m_context->flush(); } #endif diff --git a/WebCore/platform/graphics/chromium/FontCacheLinux.cpp b/WebCore/platform/graphics/chromium/FontCacheLinux.cpp index 2fda22d..4399d35 100644 --- a/WebCore/platform/graphics/chromium/FontCacheLinux.cpp +++ b/WebCore/platform/graphics/chromium/FontCacheLinux.cpp @@ -43,7 +43,6 @@ #include "SkTypeface.h" #include "SkUtils.h" -#include <unicode/utf16.h> #include <wtf/Assertions.h> #include <wtf/text/AtomicString.h> #include <wtf/text/CString.h> diff --git a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp index bbae72a..21dcd8e 100644 --- a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp +++ b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp @@ -84,11 +84,6 @@ static void clearLayerBackgroundColor(LayerChromium& layer) layer.setBackgroundColor(static_cast<RGBA32>(0)); } -GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayer::compositingCoordinatesOrientation() -{ - return CompositingCoordinatesBottomUp; -} - PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client) { return new GraphicsLayerChromium(client); @@ -324,7 +319,6 @@ void GraphicsLayerChromium::setContentsToImage(Image* image) { bool childrenChanged = false; if (image) { - NativeImagePtr nativeImage = image->nativeImageForCurrentFrame(); if (!m_contentsLayer.get() || m_contentsLayerPurpose != ContentsLayerForImage) { RefPtr<ImageLayerChromium> imageLayer = ImageLayerChromium::create(this); setupContentsLayer(imageLayer.get()); @@ -333,7 +327,7 @@ void GraphicsLayerChromium::setContentsToImage(Image* image) childrenChanged = true; } ImageLayerChromium* imageLayer = static_cast<ImageLayerChromium*>(m_contentsLayer.get()); - imageLayer->setContents(nativeImage); + imageLayer->setContents(image); updateContentsRect(); } else { if (m_contentsLayer) { @@ -400,15 +394,6 @@ void GraphicsLayerChromium::setContentsToMedia(PlatformLayer* layer) updateSublayerList(); } -void GraphicsLayerChromium::setGeometryOrientation(CompositingCoordinatesOrientation orientation) -{ - if (orientation == m_geometryOrientation) - return; - - GraphicsLayer::setGeometryOrientation(orientation); - updateGeometryOrientation(); -} - PlatformLayer* GraphicsLayerChromium::hostLayerForSublayers() const { return m_transformLayer ? m_transformLayer.get() : m_layer.get(); @@ -625,21 +610,6 @@ void GraphicsLayerChromium::updateContentsRect() m_contentsLayer->setBounds(IntSize(m_contentsRect.width(), m_contentsRect.height())); } -void GraphicsLayerChromium::updateGeometryOrientation() -{ - switch (geometryOrientation()) { - case CompositingCoordinatesTopDown: - m_layer->setGeometryFlipped(false); - break; - - case CompositingCoordinatesBottomUp: - m_layer->setGeometryFlipped(true); - break; - } - // Geometry orientation is mapped onto children transform in older QuartzCores, - // so is handled via setGeometryOrientation(). -} - void GraphicsLayerChromium::setupContentsLayer(LayerChromium* contentsLayer) { if (contentsLayer == m_contentsLayer) diff --git a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h index dde443d..214058d 100644 --- a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h +++ b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h @@ -94,8 +94,6 @@ public: virtual void setDebugBackgroundColor(const Color&); virtual void setDebugBorder(const Color&, float borderWidth); - virtual void setGeometryOrientation(CompositingCoordinatesOrientation); - void notifySyncRequired() { if (m_client) @@ -125,7 +123,6 @@ private: void updateContentsImage(); void updateContentsVideo(); void updateContentsRect(); - void updateGeometryOrientation(); void setupContentsLayer(LayerChromium*); LayerChromium* contentsLayer() const { return m_contentsLayer.get(); } diff --git a/WebCore/platform/graphics/chromium/ImageChromium.cpp b/WebCore/platform/graphics/chromium/ImageChromium.cpp new file mode 100644 index 0000000..e90d566 --- /dev/null +++ b/WebCore/platform/graphics/chromium/ImageChromium.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2008-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 "Image.h" + +#include "ChromiumBridge.h" + +namespace WebCore { + +// Other Image methods are implemented in ImageSkia.cpp + +PassRefPtr<Image> Image::loadPlatformResource(const char *name) +{ + return ChromiumBridge::loadPlatformImageResource(name); +} + +} // namespace WebCore diff --git a/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp b/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp index 060bb46..c97be82 100644 --- a/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp +++ b/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp @@ -34,6 +34,7 @@ #include "ImageLayerChromium.h" +#include "Image.h" #include "LayerRendererChromium.h" #if PLATFORM(SKIA) @@ -61,7 +62,7 @@ ImageLayerChromium::ImageLayerChromium(GraphicsLayerChromium* owner) { } -void ImageLayerChromium::setContents(NativeImagePtr contents) +void ImageLayerChromium::setContents(Image* contents) { // Check if the image has changed. if (m_contents == contents) @@ -75,13 +76,14 @@ void ImageLayerChromium::updateContents() ASSERT(layerRenderer()); void* pixels = 0; - IntRect dirtyRect(m_dirtyRect); IntSize requiredTextureSize; IntSize bitmapSize; + NativeImagePtr nativeImage = m_contents->nativeImageForCurrentFrame(); + #if PLATFORM(SKIA) // The layer contains an Image. - NativeImageSkia* skiaImage = static_cast<NativeImageSkia*>(m_contents); + NativeImageSkia* skiaImage = static_cast<NativeImageSkia*>(nativeImage); const SkBitmap* skiaBitmap = skiaImage; requiredTextureSize = IntSize(skiaBitmap->width(), skiaBitmap->height()); ASSERT(skiaBitmap); @@ -95,9 +97,8 @@ void ImageLayerChromium::updateContents() } #elif PLATFORM(CG) // NativeImagePtr is a CGImageRef on Mac OS X. - CGImageRef cgImage = m_contents; - int width = CGImageGetWidth(cgImage); - int height = CGImageGetHeight(cgImage); + int width = CGImageGetWidth(nativeImage); + int height = CGImageGetHeight(nativeImage); requiredTextureSize = IntSize(width, height); bitmapSize = requiredTextureSize; // FIXME: we should get rid of this temporary copy where possible. @@ -109,7 +110,7 @@ void ImageLayerChromium::updateContents() // Try to reuse the color space from the image to preserve its colors. // Some images use a color space (such as indexed) unsupported by the bitmap context. RetainPtr<CGColorSpaceRef> colorSpaceReleaser; - CGColorSpaceRef colorSpace = CGImageGetColorSpace(cgImage); + CGColorSpaceRef colorSpace = CGImageGetColorSpace(nativeImage); CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace); switch (colorSpaceModel) { case kCGColorSpaceModelMonochrome: @@ -130,7 +131,7 @@ void ImageLayerChromium::updateContents() CGContextSetBlendMode(tempContext.get(), kCGBlendModeCopy); CGContextDrawImage(tempContext.get(), CGRectMake(0, 0, static_cast<CGFloat>(width), static_cast<CGFloat>(height)), - cgImage); + nativeImage); pixels = tempVector.data(); #else #error "Need to implement for your platform." @@ -146,6 +147,10 @@ void ImageLayerChromium::updateContents() if (!textureId) textureId = layerRenderer()->createLayerTexture(); + // Clip the dirty rect to the bitmap dimensions. + IntRect dirtyRect(m_dirtyRect); + dirtyRect.intersect(IntRect(IntPoint(0, 0), bitmapSize)); + if (pixels) updateTextureRect(pixels, bitmapSize, requiredTextureSize, dirtyRect, textureId); } diff --git a/WebCore/platform/graphics/chromium/ImageLayerChromium.h b/WebCore/platform/graphics/chromium/ImageLayerChromium.h index e95284c..b91f04a 100644 --- a/WebCore/platform/graphics/chromium/ImageLayerChromium.h +++ b/WebCore/platform/graphics/chromium/ImageLayerChromium.h @@ -36,8 +36,14 @@ #include "ContentLayerChromium.h" +#if PLATFORM(CG) +#include <wtf/RetainPtr.h> +#endif + namespace WebCore { +class Image; + // A Layer that contains only an Image element. class ImageLayerChromium : public ContentLayerChromium { public: @@ -46,11 +52,12 @@ public: virtual void updateContents(); virtual bool drawsContent() { return m_contents; } - void setContents(NativeImagePtr); + void setContents(Image* image); private: ImageLayerChromium(GraphicsLayerChromium* owner); - NativeImagePtr m_contents; + + RefPtr<Image> m_contents; }; } diff --git a/WebCore/platform/graphics/chromium/LayerChromium.cpp b/WebCore/platform/graphics/chromium/LayerChromium.cpp index 6519f1f..e36c69d 100644 --- a/WebCore/platform/graphics/chromium/LayerChromium.cpp +++ b/WebCore/platform/graphics/chromium/LayerChromium.cpp @@ -34,6 +34,7 @@ #include "LayerChromium.h" +#include "GraphicsContext3D.h" #include "LayerRendererChromium.h" #if PLATFORM(SKIA) #include "NativeImageSkia.h" @@ -41,8 +42,7 @@ #endif #include "RenderLayerBacking.h" #include "skia/ext/platform_canvas.h" - -#include <GLES2/gl2.h> +#include <wtf/text/WTFString.h> namespace WebCore { @@ -51,24 +51,26 @@ using namespace std; const unsigned LayerChromium::s_positionAttribLocation = 0; const unsigned LayerChromium::s_texCoordAttribLocation = 1; -static GLuint loadShader(GLenum type, const char* shaderSource) +static unsigned loadShader(GraphicsContext3D* context, unsigned type, const char* shaderSource) { - GLuint shader = glCreateShader(type); + unsigned shader = context->createShader(type); if (!shader) return 0; - GLC(glShaderSource(shader, 1, &shaderSource, 0)); - GLC(glCompileShader(shader)); - GLint compiled; - GLC(glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled)); + String sourceString(shaderSource); + GLC(context, context->shaderSource(shader, sourceString)); + GLC(context, context->compileShader(shader)); + int compiled; + GLC(context, context->getShaderiv(shader, GraphicsContext3D::COMPILE_STATUS, &compiled)); if (!compiled) { - GLC(glDeleteShader(shader)); + GLC(context, context->deleteShader(shader)); return 0; } return shader; } -LayerChromium::SharedValues::SharedValues() - : m_quadVerticesVbo(0) +LayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) + : m_context(context) + , m_quadVerticesVbo(0) , m_quadElementsVbo(0) , m_maxTextureSize(0) , m_borderShaderProgram(0) @@ -77,24 +79,22 @@ LayerChromium::SharedValues::SharedValues() , m_initialized(false) { // Vertex positions and texture coordinates for the 4 corners of a 1x1 quad. - GLfloat vertices[] = { -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.0f, 1.0f, 1.0f }; - GLushort indices[] = { 0, 1, 2, 0, 2, 3, // The two triangles that make up the layer quad. + float vertices[] = { -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.0f, 1.0f, 1.0f }; + uint16_t indices[] = { 0, 1, 2, 0, 2, 3, // The two triangles that make up the layer quad. 0, 1, 2, 3}; // A line path for drawing the layer border. - GLuint vboIds[2]; - GLC(glGenBuffers(2, vboIds)); - m_quadVerticesVbo = vboIds[0]; - m_quadElementsVbo = vboIds[1]; - GLC(glBindBuffer(GL_ARRAY_BUFFER, m_quadVerticesVbo)); - GLC(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW)); - GLC(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_quadElementsVbo)); - GLC(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW)); + GLC(m_context, m_quadVerticesVbo = m_context->createBuffer()); + GLC(m_context, m_quadElementsVbo = m_context->createBuffer()); + GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_quadVerticesVbo)); + GLC(m_context, m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, sizeof(vertices), vertices, GraphicsContext3D::STATIC_DRAW)); + GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, m_quadElementsVbo)); + GLC(m_context, m_context->bufferData(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GraphicsContext3D::STATIC_DRAW)); // Get the max texture size supported by the system. - GLC(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize)); + GLC(m_context, m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize)); // Shaders for drawing the debug borders around the layers. char borderVertexShaderString[] = @@ -112,14 +112,14 @@ LayerChromium::SharedValues::SharedValues() " gl_FragColor = vec4(color.xyz * color.w, color.w);\n" "} \n"; - m_borderShaderProgram = createShaderProgram(borderVertexShaderString, borderFragmentShaderString); + m_borderShaderProgram = createShaderProgram(m_context, borderVertexShaderString, borderFragmentShaderString); if (!m_borderShaderProgram) { LOG_ERROR("ContentLayerChromium: Failed to create shader program"); return; } - m_borderShaderMatrixLocation = glGetUniformLocation(m_borderShaderProgram, "matrix"); - m_borderShaderColorLocation = glGetUniformLocation(m_borderShaderProgram, "color"); + m_borderShaderMatrixLocation = m_context->getUniformLocation(m_borderShaderProgram, "matrix"); + m_borderShaderColorLocation = m_context->getUniformLocation(m_borderShaderProgram, "color"); ASSERT(m_borderShaderMatrixLocation != -1); ASSERT(m_borderShaderColorLocation != -1); @@ -128,11 +128,10 @@ LayerChromium::SharedValues::SharedValues() LayerChromium::SharedValues::~SharedValues() { - GLuint vboIds[2] = { m_quadVerticesVbo, m_quadElementsVbo }; - GLC(glDeleteBuffers(2, vboIds)); - + GLC(m_context, m_context->deleteBuffer(m_quadVerticesVbo)); + GLC(m_context, m_context->deleteBuffer(m_quadElementsVbo)); if (m_borderShaderProgram) - GLC(glDeleteProgram(m_borderShaderProgram)); + GLC(m_context, m_context->deleteProgram(m_borderShaderProgram)); } @@ -181,45 +180,45 @@ void LayerChromium::setLayerRenderer(LayerRendererChromium* renderer) m_layerRenderer = renderer; } -unsigned LayerChromium::createShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource) +unsigned LayerChromium::createShaderProgram(GraphicsContext3D* context, const char* vertexShaderSource, const char* fragmentShaderSource) { - GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vertexShaderSource); + unsigned vertexShader = loadShader(context, GraphicsContext3D::VERTEX_SHADER, vertexShaderSource); if (!vertexShader) { LOG_ERROR("Failed to create vertex shader"); return 0; } - GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentShaderSource); + unsigned fragmentShader = loadShader(context, GraphicsContext3D::FRAGMENT_SHADER, fragmentShaderSource); if (!fragmentShader) { - GLC(glDeleteShader(vertexShader)); + GLC(context, context->deleteShader(vertexShader)); LOG_ERROR("Failed to create fragment shader"); return 0; } - GLuint programObject = glCreateProgram(); + unsigned programObject = context->createProgram(); if (!programObject) { LOG_ERROR("Failed to create shader program"); return 0; } - GLC(glAttachShader(programObject, vertexShader)); - GLC(glAttachShader(programObject, fragmentShader)); + GLC(context, context->attachShader(programObject, vertexShader)); + GLC(context, context->attachShader(programObject, fragmentShader)); // Bind the common attrib locations. - GLC(glBindAttribLocation(programObject, s_positionAttribLocation, "a_position")); - GLC(glBindAttribLocation(programObject, s_texCoordAttribLocation, "a_texCoord")); + GLC(context, context->bindAttribLocation(programObject, s_positionAttribLocation, "a_position")); + GLC(context, context->bindAttribLocation(programObject, s_texCoordAttribLocation, "a_texCoord")); - GLC(glLinkProgram(programObject)); - GLint linked; - GLC(glGetProgramiv(programObject, GL_LINK_STATUS, &linked)); + GLC(context, context->linkProgram(programObject)); + int linked; + GLC(context, context->getProgramiv(programObject, GraphicsContext3D::LINK_STATUS, &linked)); if (!linked) { LOG_ERROR("Failed to link shader program"); - GLC(glDeleteProgram(programObject)); + GLC(context, context->deleteProgram(programObject)); return 0; } - GLC(glDeleteShader(vertexShader)); - GLC(glDeleteShader(fragmentShader)); + GLC(context, context->deleteShader(vertexShader)); + GLC(context, context->deleteShader(fragmentShader)); return programObject; } @@ -299,10 +298,15 @@ void LayerChromium::setBounds(const IntSize& size) if (m_bounds == size) return; + bool firstResize = !m_bounds.width() && !m_bounds.height() && size.width() && size.height(); + m_bounds = size; m_backingStoreSize = size; - setNeedsCommit(); + if (firstResize) + setNeedsDisplay(FloatRect(0, 0, m_bounds.width(), m_bounds.height())); + else + setNeedsCommit(); } void LayerChromium::setFrame(const FloatRect& rect) @@ -311,7 +315,7 @@ void LayerChromium::setFrame(const FloatRect& rect) return; m_frame = rect; - setNeedsCommit(); + setNeedsDisplay(FloatRect(0, 0, m_bounds.width(), m_bounds.height())); } const LayerChromium* LayerChromium::rootLayer() const @@ -353,7 +357,6 @@ void LayerChromium::setNeedsDisplay(const FloatRect& dirtyRect) m_contentsDirty = true; m_dirtyRect.unite(dirtyRect); - setNeedsCommit(); } @@ -363,6 +366,12 @@ void LayerChromium::setNeedsDisplay() m_contentsDirty = true; } +void LayerChromium::resetNeedsDisplay() +{ + m_dirtyRect = FloatRect(); + m_contentsDirty = false; +} + void LayerChromium::toGLMatrix(float* flattened, const TransformationMatrix& m) { flattened[0] = m.m11(); @@ -383,11 +392,17 @@ void LayerChromium::toGLMatrix(float* flattened, const TransformationMatrix& m) flattened[15] = m.m44(); } -void LayerChromium::drawTexturedQuad(const TransformationMatrix& projectionMatrix, const TransformationMatrix& drawMatrix, +GraphicsContext3D* LayerChromium::layerRendererContext() const +{ + ASSERT(layerRenderer()); + return layerRenderer()->context(); +} + +void LayerChromium::drawTexturedQuad(GraphicsContext3D* context, const TransformationMatrix& projectionMatrix, const TransformationMatrix& drawMatrix, float width, float height, float opacity, int matrixLocation, int alphaLocation) { - static GLfloat glMatrix[16]; + static float glMatrix[16]; TransformationMatrix renderMatrix = drawMatrix; @@ -399,17 +414,17 @@ void LayerChromium::drawTexturedQuad(const TransformationMatrix& projectionMatri toGLMatrix(&glMatrix[0], renderMatrix); - GLC(glUniformMatrix4fv(matrixLocation, 1, false, &glMatrix[0])); + GLC(context, context->uniformMatrix4fv(matrixLocation, false, &glMatrix[0], 1)); if (alphaLocation != -1) - GLC(glUniform1f(alphaLocation, opacity)); + GLC(context, context->uniform1f(alphaLocation, opacity)); - GLC(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0)); + GLC(context, context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0)); } void LayerChromium::drawDebugBorder() { - static GLfloat glMatrix[16]; + static float glMatrix[16]; if (!borderColor().alpha()) return; @@ -421,14 +436,15 @@ void LayerChromium::drawDebugBorder() renderMatrix.scale3d(bounds().width(), bounds().height(), 1); renderMatrix.multiply(layerRenderer()->projectionMatrix()); toGLMatrix(&glMatrix[0], renderMatrix); - GLC(glUniformMatrix4fv(sv->borderShaderMatrixLocation(), 1, false, &glMatrix[0])); + GraphicsContext3D* context = layerRendererContext(); + GLC(context, context->uniformMatrix4fv(sv->borderShaderMatrixLocation(), false, &glMatrix[0], 1)); - GLC(glUniform4f(sv->borderShaderColorLocation(), borderColor().red() / 255.0, borderColor().green() / 255.0, borderColor().blue() / 255.0, 1)); + GLC(context, context->uniform4f(sv->borderShaderColorLocation(), borderColor().red() / 255.0, borderColor().green() / 255.0, borderColor().blue() / 255.0, 1)); - GLC(glLineWidth(borderWidth())); + GLC(context, context->lineWidth(borderWidth())); // The indices for the line are stored in the same array as the triangle indices. - GLC(glDrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, (void*)(6 * sizeof(unsigned short)))); + GLC(context, context->drawElements(GraphicsContext3D::LINE_LOOP, 4, GraphicsContext3D::UNSIGNED_SHORT, 6 * sizeof(unsigned short))); } const FloatRect LayerChromium::getDrawRect() const @@ -455,24 +471,26 @@ void LayerChromium::drawAsMask() // We reuse the border shader here as all we need a single colored shader pass. // The color specified here is only for debug puproses as typically when we call this // method, writes to the color channels are disabled. - GLC(glUniform4f(sv->borderShaderColorLocation(), 0, 1 , 0, 0.7)); + GraphicsContext3D* context = layerRendererContext(); + GLC(context, context->uniform4f(sv->borderShaderColorLocation(), 0, 1 , 0, 0.7)); - drawTexturedQuad(layerRenderer()->projectionMatrix(), drawTransform(), - bounds().width(), bounds().height(), drawOpacity(), - sv->borderShaderMatrixLocation(), -1); + drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), + bounds().width(), bounds().height(), drawOpacity(), + sv->borderShaderMatrixLocation(), -1); } // static void LayerChromium::prepareForDraw(const SharedValues* sv) { - GLC(glBindBuffer(GL_ARRAY_BUFFER, sv->quadVerticesVbo())); - GLC(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sv->quadElementsVbo())); - GLuint offset = 0; - GLC(glVertexAttribPointer(s_positionAttribLocation, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)offset)); - offset += 3 * sizeof(GLfloat); - GLC(glVertexAttribPointer(s_texCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)offset)); - GLC(glEnableVertexAttribArray(s_positionAttribLocation)); - GLC(glEnableVertexAttribArray(s_texCoordAttribLocation)); + GraphicsContext3D* context = sv->context(); + GLC(context, context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, sv->quadVerticesVbo())); + GLC(context, context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, sv->quadElementsVbo())); + unsigned offset = 0; + GLC(context, context->vertexAttribPointer(s_positionAttribLocation, 3, GraphicsContext3D::FLOAT, false, 5 * sizeof(float), offset)); + offset += 3 * sizeof(float); + GLC(context, context->vertexAttribPointer(s_texCoordAttribLocation, 2, GraphicsContext3D::FLOAT, false, 5 * sizeof(float), offset)); + GLC(context, context->enableVertexAttribArray(s_positionAttribLocation)); + GLC(context, context->enableVertexAttribArray(s_texCoordAttribLocation)); } } diff --git a/WebCore/platform/graphics/chromium/LayerChromium.h b/WebCore/platform/graphics/chromium/LayerChromium.h index ba15088..30d35d1 100644 --- a/WebCore/platform/graphics/chromium/LayerChromium.h +++ b/WebCore/platform/graphics/chromium/LayerChromium.h @@ -62,7 +62,7 @@ class LayerChromium : public RefCounted<LayerChromium> { public: static PassRefPtr<LayerChromium> create(GraphicsLayerChromium* owner = 0); - ~LayerChromium(); + virtual ~LayerChromium(); const LayerChromium* rootLayer() const; LayerChromium* superlayer() const; @@ -112,6 +112,8 @@ public: void setNeedsDisplay(const FloatRect& dirtyRect); void setNeedsDisplay(); + const FloatRect& dirtyRect() const { return m_dirtyRect; } + void resetNeedsDisplay(); void setNeedsDisplayOnBoundsChange(bool needsDisplay) { m_needsDisplayOnBoundsChange = needsDisplay; } @@ -169,9 +171,10 @@ public: // context). class SharedValues { public: - SharedValues(); + explicit SharedValues(GraphicsContext3D*); ~SharedValues(); + GraphicsContext3D* context() const { return m_context; } unsigned quadVerticesVbo() const { return m_quadVerticesVbo; } unsigned quadElementsVbo() const { return m_quadElementsVbo; } int maxTextureSize() const { return m_maxTextureSize; } @@ -181,6 +184,7 @@ public: bool initialized() const { return m_initialized; } private: + GraphicsContext3D* m_context; unsigned m_quadVerticesVbo; unsigned m_quadElementsVbo; int m_maxTextureSize; @@ -197,14 +201,15 @@ protected: LayerChromium(GraphicsLayerChromium* owner); LayerRendererChromium* layerRenderer() const { return m_layerRenderer; } + GraphicsContext3D* layerRendererContext() const; - static void drawTexturedQuad(const TransformationMatrix& projectionMatrix, const TransformationMatrix& layerMatrix, + static void drawTexturedQuad(GraphicsContext3D*, const TransformationMatrix& projectionMatrix, const TransformationMatrix& layerMatrix, float width, float height, float opacity, int matrixLocation, int alphaLocation); static void toGLMatrix(float*, const TransformationMatrix&); - static unsigned createShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource); + static unsigned createShaderProgram(GraphicsContext3D*, const char* vertexShaderSource, const char* fragmentShaderSource); IntSize m_bounds; FloatRect m_dirtyRect; diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp index 4708310..116a15d 100644 --- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp +++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp @@ -35,7 +35,7 @@ #include "LayerRendererChromium.h" #include "Canvas2DLayerChromium.h" -#include "GLES2Context.h" +#include "GraphicsContext3D.h" #include "LayerChromium.h" #include "NotImplemented.h" #include "WebGLLayerChromium.h" @@ -46,8 +46,6 @@ #include <CoreGraphics/CGBitmapContext.h> #endif -#include <GLES2/gl2.h> - namespace WebCore { static TransformationMatrix orthoMatrix(float left, float right, float bottom, float top, float nearZ, float farZ) @@ -75,19 +73,19 @@ static inline bool compareLayerZ(const LayerChromium* a, const LayerChromium* b) return transformA.m43() < transformB.m43(); } -PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(PassOwnPtr<GLES2Context> gles2Context) +PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(PassOwnPtr<GraphicsContext3D> context) { - if (!gles2Context) + if (!context) return 0; - OwnPtr<LayerRendererChromium> layerRenderer(new LayerRendererChromium(gles2Context)); + OwnPtr<LayerRendererChromium> layerRenderer(new LayerRendererChromium(context)); if (!layerRenderer->hardwareCompositing()) return 0; return layerRenderer.release(); } -LayerRendererChromium::LayerRendererChromium(PassOwnPtr<GLES2Context> gles2Context) +LayerRendererChromium::LayerRendererChromium(PassOwnPtr<GraphicsContext3D> context) : m_rootLayerTextureId(0) , m_rootLayerTextureWidth(0) , m_rootLayerTextureHeight(0) @@ -96,7 +94,7 @@ LayerRendererChromium::LayerRendererChromium(PassOwnPtr<GLES2Context> gles2Conte , m_needsDisplay(false) , m_scrollPosition(IntPoint(-1, -1)) , m_currentShader(0) - , m_gles2Context(gles2Context) + , m_context(context) { m_hardwareCompositing = initializeSharedObjects(); } @@ -106,11 +104,16 @@ LayerRendererChromium::~LayerRendererChromium() cleanupSharedObjects(); } -void LayerRendererChromium::debugGLCall(const char* command, const char* file, int line) +GraphicsContext3D* LayerRendererChromium::context() +{ + return m_context.get(); +} + +void LayerRendererChromium::debugGLCall(GraphicsContext3D* context, const char* command, const char* file, int line) { - GLenum error = glGetError(); - if (error != GL_NO_ERROR) - LOG_ERROR("GL command failed: File: %s\n\tLine %d\n\tcommand: %s, error %x\n", file, line, command, error); + unsigned long error = context->getError(); + if (error != GraphicsContext3D::NO_ERROR) + LOG_ERROR("GL command failed: File: %s\n\tLine %d\n\tcommand: %s, error %x\n", file, line, command, static_cast<int>(error)); } // Creates a canvas and an associated graphics context that the root layer will @@ -138,6 +141,8 @@ void LayerRendererChromium::setRootLayerCanvasSize(const IntSize& size) size.width(), size.height(), 8, rowBytes, colorSpace.get(), kCGImageAlphaPremultipliedLast)); + CGContextTranslateCTM(m_rootLayerCGContext.get(), 0, size.height()); + CGContextScaleCTM(m_rootLayerCGContext.get(), 1, -1); m_rootLayerGraphicsContext = new GraphicsContext(m_rootLayerCGContext.get()); #else #error "Need to implement for your platform." @@ -149,15 +154,15 @@ void LayerRendererChromium::setRootLayerCanvasSize(const IntSize& size) void LayerRendererChromium::useShader(unsigned programId) { if (programId != m_currentShader) { - GLC(glUseProgram(programId)); + GLC(m_context, m_context->useProgram(programId)); m_currentShader = programId; } } // Updates the contents of the root layer texture that fall inside the updateRect // and re-composits all sublayers. -void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect& visibleRect, - const IntRect& contentRect, const IntPoint& scrollPosition) +void LayerRendererChromium::prepareToDrawLayers(const IntRect& visibleRect, const IntRect& contentRect, + const IntPoint& scrollPosition) { ASSERT(m_hardwareCompositing); @@ -166,7 +171,7 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect& makeContextCurrent(); - GLC(glBindTexture(GL_TEXTURE_2D, m_rootLayerTextureId)); + GLC(m_context, m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_rootLayerTextureId)); // If the size of the visible area has changed then allocate a new texture // to store the contents of the root layer and adjust the projection matrix @@ -178,56 +183,44 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect& m_rootLayerTextureHeight = visibleRect.height(); m_projectionMatrix = orthoMatrix(0, visibleRectWidth, visibleRectHeight, 0, -1000, 1000); - GLC(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_rootLayerTextureWidth, m_rootLayerTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); + GLC(m_context, m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, m_rootLayerTextureWidth, m_rootLayerTextureHeight, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0)); } // The GL viewport covers the entire visible area, including the scrollbars. - GLC(glViewport(0, 0, visibleRectWidth, visibleRectHeight)); + GLC(m_context, m_context->viewport(0, 0, visibleRectWidth, visibleRectHeight)); // Bind the common vertex attributes used for drawing all the layers. LayerChromium::prepareForDraw(layerSharedValues()); // FIXME: These calls can be made once, when the compositor context is initialized. - GLC(glDisable(GL_DEPTH_TEST)); - GLC(glDisable(GL_CULL_FACE)); - GLC(glDepthFunc(GL_LEQUAL)); - GLC(glClearStencil(0)); + GLC(m_context, m_context->disable(GraphicsContext3D::DEPTH_TEST)); + GLC(m_context, m_context->disable(GraphicsContext3D::CULL_FACE)); + GLC(m_context, m_context->depthFunc(GraphicsContext3D::LEQUAL)); + GLC(m_context, m_context->clearStencil(0)); if (m_scrollPosition == IntPoint(-1, -1)) m_scrollPosition = scrollPosition; IntPoint scrollDelta = toPoint(scrollPosition - m_scrollPosition); - // Scroll only when the updateRect contains pixels for the newly uncovered region to avoid flashing. - if ((scrollDelta.x() && updateRect.width() >= abs(scrollDelta.x()) && updateRect.height() >= contentRect.height()) - || (scrollDelta.y() && updateRect.height() >= abs(scrollDelta.y()) && updateRect.width() >= contentRect.width())) { + // Scroll the backbuffer + if (scrollDelta.x() || scrollDelta.y()) { // Scrolling works as follows: We render a quad with the current root layer contents // translated by the amount the page has scrolled since the last update and then read the // pixels of the content area (visible area excluding the scroll bars) back into the - // root layer texture. The newly exposed area is subesquently filled as usual with - // the contents of the updateRect. + // root layer texture. The newly exposed area will be filled by a subsequent drawLayersIntoRect call TransformationMatrix scrolledLayerMatrix; -#if PLATFORM(SKIA) - float scaleFactor = 1.0f; -#elif PLATFORM(CG) - // Because the contents of the OpenGL texture are inverted - // vertically compared to the Skia backend, we need to move - // the backing store in the opposite direction. - float scaleFactor = -1.0f; -#else -#error "Need to implement for your platform." -#endif scrolledLayerMatrix.translate3d(0.5 * visibleRect.width() - scrollDelta.x(), - 0.5 * visibleRect.height() + scaleFactor * scrollDelta.y(), 0); + 0.5 * visibleRect.height() + scrollDelta.y(), 0); scrolledLayerMatrix.scale3d(1, -1, 1); useShader(m_scrollShaderProgram); - GLC(glUniform1i(m_scrollShaderSamplerLocation, 0)); - LayerChromium::drawTexturedQuad(m_projectionMatrix, scrolledLayerMatrix, + GLC(m_context, m_context->uniform1i(m_scrollShaderSamplerLocation, 0)); + LayerChromium::drawTexturedQuad(m_context.get(), m_projectionMatrix, scrolledLayerMatrix, visibleRect.width(), visibleRect.height(), 1, m_scrollShaderMatrixLocation, -1); - GLC(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, contentRect.width(), contentRect.height())); + GLC(m_context, m_context->copyTexSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, 0, 0, contentRect.width(), contentRect.height())); m_scrollPosition = scrollPosition; } else if (abs(scrollDelta.y()) > contentRect.height() || abs(scrollDelta.x()) > contentRect.width()) { // Scrolling larger than the contentRect size does not preserve any of the pixels, so there is @@ -235,64 +228,83 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect& m_scrollPosition = scrollPosition; } - // FIXME: The following check should go away when the compositor renders independently from its own thread. - // Ignore a 1x1 update rect at (0, 0) as that's used a way to kick off a redraw for the compositor. - if (!(!updateRect.x() && !updateRect.y() && updateRect.width() == 1 && updateRect.height() == 1)) { - // Update the root layer texture. - ASSERT((updateRect.x() + updateRect.width() <= m_rootLayerTextureWidth) - && (updateRect.y() + updateRect.height() <= m_rootLayerTextureHeight)); + // Translate all the composited layers by the scroll position. + TransformationMatrix matrix; + matrix.translate3d(-m_scrollPosition.x(), -m_scrollPosition.y(), 0); + + // Traverse the layer tree and update the layer transforms. + float opacity = 1; + const Vector<RefPtr<LayerChromium> >& sublayers = m_rootLayer->getSublayers(); + size_t i; + for (i = 0; i < sublayers.size(); i++) + updateLayersRecursive(sublayers[i].get(), matrix, opacity); +} + +void LayerRendererChromium::updateRootLayerTextureRect(const IntRect& updateRect) +{ + ASSERT(m_hardwareCompositing); + + if (!m_rootLayer) + return; + + GLC(m_context, m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_rootLayerTextureId)); + + // Update the root layer texture. + ASSERT((updateRect.right() <= m_rootLayerTextureWidth) + && (updateRect.bottom() <= m_rootLayerTextureHeight)); #if PLATFORM(SKIA) - // Get the contents of the updated rect. - const SkBitmap bitmap = m_rootLayerCanvas->getDevice()->accessBitmap(false); - int rootLayerWidth = bitmap.width(); - int rootLayerHeight = bitmap.height(); - ASSERT(rootLayerWidth == updateRect.width() && rootLayerHeight == updateRect.height()); - void* pixels = bitmap.getPixels(); - - // Copy the contents of the updated rect to the root layer texture. - GLC(glTexSubImage2D(GL_TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GL_RGBA, GL_UNSIGNED_BYTE, pixels)); + // Get the contents of the updated rect. + const SkBitmap bitmap = m_rootLayerCanvas->getDevice()->accessBitmap(false); + int bitmapWidth = bitmap.width(); + int bitmapHeight = bitmap.height(); + ASSERT(bitmapWidth == updateRect.width() && bitmapHeight == updateRect.height()); + void* pixels = bitmap.getPixels(); #elif PLATFORM(CG) - // Get the contents of the updated rect. - ASSERT(static_cast<int>(CGBitmapContextGetWidth(m_rootLayerCGContext.get())) == updateRect.width() && static_cast<int>(CGBitmapContextGetHeight(m_rootLayerCGContext.get())) == updateRect.height()); - void* pixels = m_rootLayerBackingStore.data(); - - // Copy the contents of the updated rect to the root layer texture. - // The origin is at the lower left in Core Graphics' coordinate system. We need to correct for this here. - GLC(glTexSubImage2D(GL_TEXTURE_2D, 0, - updateRect.x(), m_rootLayerTextureHeight - updateRect.y() - updateRect.height(), - updateRect.width(), updateRect.height(), - GL_RGBA, GL_UNSIGNED_BYTE, pixels)); + // Get the contents of the updated rect. + ASSERT(static_cast<int>(CGBitmapContextGetWidth(m_rootLayerCGContext.get())) == updateRect.width() && static_cast<int>(CGBitmapContextGetHeight(m_rootLayerCGContext.get())) == updateRect.height()); + void* pixels = m_rootLayerBackingStore.data(); #else #error "Need to implement for your platform." #endif - } + // Copy the contents of the updated rect to the root layer texture. + GLC(m_context, m_context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels)); +} + +void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect& contentRect) +{ + ASSERT(m_hardwareCompositing); - glClearColor(0, 0, 1, 1); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + m_context->clearColor(0, 0, 1, 1); + m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT); + + GLC(m_context, m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_rootLayerTextureId)); // Render the root layer using a quad that takes up the entire visible area of the window. // We reuse the shader program used by ContentLayerChromium. const ContentLayerChromium::SharedValues* contentLayerValues = contentLayerSharedValues(); useShader(contentLayerValues->contentShaderProgram()); - GLC(glUniform1i(contentLayerValues->shaderSamplerLocation(), 0)); + GLC(m_context, m_context->uniform1i(contentLayerValues->shaderSamplerLocation(), 0)); TransformationMatrix layerMatrix; layerMatrix.translate3d(visibleRect.width() * 0.5f, visibleRect.height() * 0.5f, 0); - LayerChromium::drawTexturedQuad(m_projectionMatrix, layerMatrix, + LayerChromium::drawTexturedQuad(m_context.get(), m_projectionMatrix, layerMatrix, visibleRect.width(), visibleRect.height(), 1, contentLayerValues->shaderMatrixLocation(), contentLayerValues->shaderAlphaLocation()); // If culling is enabled then we will cull the backface. - GLC(glCullFace(GL_BACK)); + GLC(m_context, m_context->cullFace(GraphicsContext3D::BACK)); // The orthographic projection is setup such that Y starts at zero and // increases going down the page so we need to adjust the winding order of // front facing triangles. - GLC(glFrontFace(GL_CW)); + GLC(m_context, m_context->frontFace(GraphicsContext3D::CW)); // The shader used to render layers returns pre-multiplied alpha colors // so we need to send the blending mode appropriately. - GLC(glEnable(GL_BLEND)); - GLC(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); + GLC(m_context, m_context->enable(GraphicsContext3D::BLEND)); + GLC(m_context, m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA)); + + // Set the rootVisibleRect --- used by subsequent drawLayers calls + m_rootVisibleRect = visibleRect; // Translate all the composited layers by the scroll position. TransformationMatrix matrix; @@ -305,43 +317,67 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect& for (i = 0; i < sublayers.size(); i++) updateLayersRecursive(sublayers[i].get(), matrix, opacity); - m_rootVisibleRect = visibleRect; - // Enable scissoring to avoid rendering composited layers over the scrollbars. - GLC(glEnable(GL_SCISSOR_TEST)); + GLC(m_context, m_context->enable(GraphicsContext3D::SCISSOR_TEST)); FloatRect scissorRect(contentRect); + // The scissorRect should not include the scroll offset. scissorRect.move(-m_scrollPosition.x(), -m_scrollPosition.y()); scissorToRect(scissorRect); // Clear the stencil buffer to 0. - GLC(glClear(GL_STENCIL_BUFFER_BIT)); + GLC(m_context, m_context->clear(GraphicsContext3D::STENCIL_BUFFER_BIT)); // Disable writes to the stencil buffer. - GLC(glStencilMask(0)); + GLC(m_context, m_context->stencilMask(0)); // Traverse the layer tree one more time to draw the layers. - for (i = 0; i < sublayers.size(); i++) + for (size_t i = 0; i < sublayers.size(); i++) drawLayersRecursive(sublayers[i].get(), scissorRect); - GLC(glDisable(GL_SCISSOR_TEST)); + GLC(m_context, m_context->disable(GraphicsContext3D::SCISSOR_TEST)); +} - m_gles2Context->swapBuffers(); +void LayerRendererChromium::finish() +{ + m_context->finish(); +} +void LayerRendererChromium::present() +{ + // We're done! Time to swapbuffers! + + // Note that currently this has the same effect as swapBuffers; we should + // consider exposing a different entry point on GraphicsContext3D. + m_context->prepareTexture(); m_needsDisplay = false; } +void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& rect) +{ + ASSERT(rect.right() <= rootLayerTextureSize().width() + && rect.bottom() <= rootLayerTextureSize().height()); + + if (!pixels) + return; + + makeContextCurrent(); + + GLC(m_context, m_context->readPixels(rect.x(), rect.y(), rect.width(), rect.height(), + GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels)); +} + // FIXME: This method should eventually be replaced by a proper texture manager. unsigned LayerRendererChromium::createLayerTexture() { - GLuint textureId = 0; - GLC(glGenTextures(1, &textureId)); - GLC(glBindTexture(GL_TEXTURE_2D, textureId)); + unsigned textureId = 0; + GLC(m_context, textureId = m_context->createTexture()); + GLC(m_context, m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId)); // Do basic linear filtering on resize. - GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); - // NPOT textures in GL ES only work when the wrap mode is set to GL_CLAMP_TO_EDGE. - GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); - GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + GLC(m_context, m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR)); + GLC(m_context, m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR)); + // NPOT textures in GL ES only work when the wrap mode is set to GraphicsContext3D::CLAMP_TO_EDGE. + GLC(m_context, m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE)); + GLC(m_context, m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE)); return textureId; } @@ -440,18 +476,18 @@ void LayerRendererChromium::drawLayerIntoStencilBuffer(LayerChromium* layer, boo { // Enable writes to the stencil buffer and increment the stencil values // by one for every pixel under the current layer. - GLC(glStencilMask(0xff)); - GLC(glStencilFunc(GL_ALWAYS, 1, 0xff)); - GLenum stencilOp = (decrement ? GL_DECR : GL_INCR); - GLC(glStencilOp(stencilOp, stencilOp, stencilOp)); + GLC(m_context, m_context->stencilMask(0xff)); + GLC(m_context, m_context->stencilFunc(GraphicsContext3D::ALWAYS, 1, 0xff)); + unsigned stencilOp = (decrement ? GraphicsContext3D::DECR : GraphicsContext3D::INCR); + GLC(m_context, m_context->stencilOp(stencilOp, stencilOp, stencilOp)); - GLC(glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE)); + GLC(m_context, m_context->colorMask(false, false, false, false)); layer->drawAsMask(); // Disable writes to the stencil buffer. - GLC(glStencilMask(0)); - GLC(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)); + GLC(m_context, m_context->stencilMask(0)); + GLC(m_context, m_context->colorMask(true, true, true, true)); } // Recursively walk the layer tree and draw the layers. @@ -468,7 +504,7 @@ void LayerRendererChromium::drawLayersRecursive(LayerChromium* layer, const Floa bool mustClearDepth = false; if (layer->preserves3D()) { if (!depthTestEnabledForSubtree) { - GLC(glEnable(GL_DEPTH_TEST)); + GLC(m_context, m_context->enable(GraphicsContext3D::DEPTH_TEST)); depthTestEnabledForSubtree = true; // Need to clear the depth buffer when we're done rendering this subtree. @@ -505,7 +541,7 @@ void LayerRendererChromium::drawLayersRecursive(LayerChromium* layer, const Floa // is rendered, the stencil values should be all back to zero. An 8 bit stencil buffer // will allow us up to 255 nested clipping layers which is hopefully enough. if (!currentStencilValue) - GLC(glEnable(GL_STENCIL_TEST)); + GLC(m_context, m_context->enable(GraphicsContext3D::STENCIL_TEST)); drawLayerIntoStencilBuffer(layer, false); @@ -517,7 +553,7 @@ void LayerRendererChromium::drawLayersRecursive(LayerChromium* layer, const Floa // currentStencilValue. if (didStencilDraw) { // The sublayers will render only if the stencil test passes. - GLC(glStencilFunc(GL_EQUAL, currentStencilValue, 0xff)); + GLC(m_context, m_context->stencilFunc(GraphicsContext3D::EQUAL, currentStencilValue, 0xff)); } // If we're using depth testing then we need to sort the children in Z to @@ -548,8 +584,8 @@ void LayerRendererChromium::drawLayersRecursive(LayerChromium* layer, const Floa currentStencilValue--; if (!currentStencilValue) { // Disable stencil testing. - GLC(glDisable(GL_STENCIL_TEST)); - GLC(glStencilFunc(GL_ALWAYS, 0, 0xff)); + GLC(m_context, m_context->disable(GraphicsContext3D::STENCIL_TEST)); + GLC(m_context, m_context->stencilFunc(GraphicsContext3D::ALWAYS, 0, 0xff)); } } @@ -558,8 +594,8 @@ void LayerRendererChromium::drawLayersRecursive(LayerChromium* layer, const Floa } if (mustClearDepth) { - GLC(glDisable(GL_DEPTH_TEST)); - GLC(glClear(GL_DEPTH_BUFFER_BIT)); + GLC(m_context, m_context->disable(GraphicsContext3D::DEPTH_TEST)); + GLC(m_context, m_context->clear(GraphicsContext3D::DEPTH_BUFFER_BIT)); depthTestEnabledForSubtree = false; } } @@ -573,13 +609,13 @@ void LayerRendererChromium::drawLayer(LayerChromium* layer) if (layer->contentsDirty()) { // Update the backing texture contents for any dirty portion of the layer. layer->updateContents(); - m_gles2Context->makeCurrent(); + m_context->makeContextCurrent(); } if (layer->doubleSided()) - glDisable(GL_CULL_FACE); + m_context->disable(GraphicsContext3D::CULL_FACE); else - glEnable(GL_CULL_FACE); + m_context->enable(GraphicsContext3D::CULL_FACE); layer->draw(); } @@ -594,12 +630,13 @@ void LayerRendererChromium::scissorToRect(const FloatRect& scissorRect) { // Compute the lower left corner of the scissor rect. float bottom = std::max((float)m_rootVisibleRect.height() - scissorRect.bottom(), 0.f); - GLC(glScissor(scissorRect.x(), bottom, scissorRect.width(), scissorRect.height())); + GLC(m_context, m_context->scissor(scissorRect.x(), bottom, scissorRect.width(), scissorRect.height())); } bool LayerRendererChromium::makeContextCurrent() { - return m_gles2Context->makeCurrent(); + m_context->makeContextCurrent(); + return true; } // Checks whether a given size is within the maximum allowed texture size range. @@ -610,6 +647,12 @@ bool LayerRendererChromium::checkTextureSize(const IntSize& textureSize) return true; } +void LayerRendererChromium::resizeOnscreenContent(const IntSize& size) +{ + if (m_context) + m_context->reshape(size.width(), size.height()); +} + bool LayerRendererChromium::initializeSharedObjects() { makeContextCurrent(); @@ -637,15 +680,15 @@ bool LayerRendererChromium::initializeSharedObjects() " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w); \n" "} \n"; - m_scrollShaderProgram = LayerChromium::createShaderProgram(scrollVertexShaderString, scrollFragmentShaderString); + m_scrollShaderProgram = LayerChromium::createShaderProgram(m_context.get(), scrollVertexShaderString, scrollFragmentShaderString); if (!m_scrollShaderProgram) { LOG_ERROR("LayerRendererChromium: Failed to create scroll shader program"); cleanupSharedObjects(); return false; } - GLC(m_scrollShaderSamplerLocation = glGetUniformLocation(m_scrollShaderProgram, "s_texture")); - GLC(m_scrollShaderMatrixLocation = glGetUniformLocation(m_scrollShaderProgram, "matrix")); + GLC(m_context, m_scrollShaderSamplerLocation = m_context->getUniformLocation(m_scrollShaderProgram, "s_texture")); + GLC(m_context, m_scrollShaderMatrixLocation = m_context->getUniformLocation(m_scrollShaderProgram, "matrix")); if (m_scrollShaderSamplerLocation == -1 || m_scrollShaderMatrixLocation == -1) { LOG_ERROR("Failed to initialize scroll shader."); cleanupSharedObjects(); @@ -661,19 +704,19 @@ bool LayerRendererChromium::initializeSharedObjects() } // Turn off filtering for the root layer to avoid blurring from the repeated // writes and reads to the framebuffer that happen while scrolling. - GLC(glBindTexture(GL_TEXTURE_2D, m_rootLayerTextureId)); - GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - GLC(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + GLC(m_context, m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_rootLayerTextureId)); + GLC(m_context, m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST)); + GLC(m_context, m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST)); // Get the max texture size supported by the system. - GLC(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize)); + GLC(m_context, m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize)); // Get the number of bits available in the stencil buffer. - GLC(glGetIntegerv(GL_STENCIL_BITS, &m_numStencilBits)); + GLC(m_context, m_context->getIntegerv(GraphicsContext3D::STENCIL_BITS, &m_numStencilBits)); - m_layerSharedValues = adoptPtr(new LayerChromium::SharedValues()); - m_contentLayerSharedValues = adoptPtr(new ContentLayerChromium::SharedValues()); - m_canvasLayerSharedValues = adoptPtr(new CanvasLayerChromium::SharedValues()); + m_layerSharedValues = adoptPtr(new LayerChromium::SharedValues(m_context.get())); + m_contentLayerSharedValues = adoptPtr(new ContentLayerChromium::SharedValues(m_context.get())); + m_canvasLayerSharedValues = adoptPtr(new CanvasLayerChromium::SharedValues(m_context.get())); if (!m_layerSharedValues->initialized() || !m_contentLayerSharedValues->initialized() || !m_canvasLayerSharedValues->initialized()) { cleanupSharedObjects(); return false; @@ -691,12 +734,12 @@ void LayerRendererChromium::cleanupSharedObjects() m_canvasLayerSharedValues.clear(); if (m_scrollShaderProgram) { - GLC(glDeleteProgram(m_scrollShaderProgram)); + GLC(m_context, m_context->deleteProgram(m_scrollShaderProgram)); m_scrollShaderProgram = 0; } if (m_rootLayerTextureId) { - GLC(glDeleteTextures(1, &m_rootLayerTextureId)); + GLC(m_context, m_context->deleteTexture(m_rootLayerTextureId)); m_rootLayerTextureId = 0; } } diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/WebCore/platform/graphics/chromium/LayerRendererChromium.h index 8f44afe..c733228 100644 --- a/WebCore/platform/graphics/chromium/LayerRendererChromium.h +++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.h @@ -51,19 +51,32 @@ namespace WebCore { -class GLES2Context; +class GraphicsContext3D; // Class that handles drawing of composited render layers using GL. class LayerRendererChromium : public Noncopyable { public: - static PassOwnPtr<LayerRendererChromium> create(PassOwnPtr<GLES2Context> gles2Context); + static PassOwnPtr<LayerRendererChromium> create(PassOwnPtr<GraphicsContext3D> graphicsContext3D); - LayerRendererChromium(PassOwnPtr<GLES2Context> gles2Context); + LayerRendererChromium(PassOwnPtr<GraphicsContext3D> graphicsContext3D); ~LayerRendererChromium(); - // Updates the contents of the root layer that fall inside the updateRect and recomposites - // all the layers. - void drawLayers(const IntRect& updateRect, const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition); + GraphicsContext3D* context(); + + // updates size of root texture, if needed, and scrolls the backbuffer. + void prepareToDrawLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition); + + // updates a rectangle within the root layer texture + void updateRootLayerTextureRect(const IntRect& updateRect); + + // draws the current layers onto the backbuffer + void drawLayers(const IntRect& visibleRect, const IntRect& contentRect); + + // waits for rendering to finish + void finish(); + + // puts backbuffer onscreen + void present(); void setRootLayer(PassRefPtr<LayerChromium> layer) { m_rootLayer = layer; } LayerChromium* rootLayer() { return m_rootLayer.get(); } @@ -78,7 +91,7 @@ public: unsigned createLayerTexture(); - static void debugGLCall(const char* command, const char* file, int line); + static void debugGLCall(GraphicsContext3D*, const char* command, const char* file, int line); const TransformationMatrix& projectionMatrix() const { return m_projectionMatrix; } @@ -90,6 +103,11 @@ public: const ContentLayerChromium::SharedValues* contentLayerSharedValues() const { return m_contentLayerSharedValues.get(); } const CanvasLayerChromium::SharedValues* canvasLayerSharedValues() const { return m_canvasLayerSharedValues.get(); } + void resizeOnscreenContent(const IntSize&); + + IntSize rootLayerTextureSize() const { return IntSize(m_rootLayerTextureWidth, m_rootLayerTextureHeight); } + void getFramebufferPixels(void *pixels, const IntRect& rect); + private: void updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, float opacity); @@ -153,7 +171,7 @@ private: OwnPtr<ContentLayerChromium::SharedValues> m_contentLayerSharedValues; OwnPtr<CanvasLayerChromium::SharedValues> m_canvasLayerSharedValues; - OwnPtr<GLES2Context> m_gles2Context; + OwnPtr<GraphicsContext3D> m_context; }; // Setting DEBUG_GL_CALLS to 1 will call glGetError() after almost every GL @@ -162,9 +180,9 @@ private: #define DEBUG_GL_CALLS 0 #if DEBUG_GL_CALLS && !defined ( NDEBUG ) -#define GLC(x) { (x), LayerRendererChromium::debugGLCall(#x, __FILE__, __LINE__); } +#define GLC(context, x) { (x), LayerRendererChromium::debugGLCall(context, #x, __FILE__, __LINE__); } #else -#define GLC(x) (x) +#define GLC(context, x) (x) #endif diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp index c0da285..0fb1bb4 100644 --- a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp +++ b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp @@ -33,14 +33,11 @@ #if USE(ACCELERATED_COMPOSITING) #include "VideoLayerChromium.h" +#include "GraphicsContext3D.h" #include "LayerRendererChromium.h" #include "RenderLayerBacking.h" #include "skia/ext/platform_canvas.h" -#include <GLES2/gl2.h> -#define GL_GLEXT_PROTOTYPES -#include <GLES2/gl2ext.h> - #if PLATFORM(SKIA) #include "NativeImageSkia.h" #include "PlatformContextSkia.h" @@ -153,9 +150,10 @@ void VideoLayerChromium::createTextureRect(const IntSize& requiredTextureSize, c if (!pixels) return; - glBindTexture(GL_TEXTURE_2D, textureId); + GraphicsContext3D* context = layerRendererContext(); + context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId); ASSERT(bitmapSize == requiredTextureSize); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, requiredTextureSize.width(), requiredTextureSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, requiredTextureSize.width(), requiredTextureSize.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels); m_contentsTexture = textureId; m_allocatedTextureSize = requiredTextureSize; @@ -174,11 +172,13 @@ void VideoLayerChromium::updateTextureRect(const IntRect& updateRect, unsigned t SkBitmap::Config skiaConfig = skiaBitmap->config(); if (skiaConfig == SkBitmap::kARGB_8888_Config) { - glBindTexture(GL_TEXTURE_2D, textureId); - void* mem = glMapTexSubImage2D(GL_TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GL_RGBA, GL_UNSIGNED_BYTE, GL_WRITE_ONLY); + GraphicsContext3D* context = layerRendererContext(); + context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId); + ASSERT(context->supportsMapSubCHROMIUM()); + void* mem = context->mapTexSubImage2DCHROMIUM(GraphicsContext3D::TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, GraphicsContext3D::WRITE_ONLY); skiaBitmap->setPixels(mem); m_owner->paintGraphicsLayerContents(*m_graphicsContext, updateRect); - glUnmapTexSubImage2D(mem); + context->unmapTexSubImage2DCHROMIUM(mem); } updateCompleted(); diff --git a/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp b/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp index 411f416..2055ae6 100644 --- a/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp +++ b/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp @@ -36,7 +36,6 @@ #include "GraphicsContext3D.h" #include "LayerRendererChromium.h" -#include <GLES2/gl2.h> namespace WebCore { @@ -53,15 +52,16 @@ WebGLLayerChromium::WebGLLayerChromium(GraphicsLayerChromium* owner) void WebGLLayerChromium::updateContents() { + GraphicsContext3D* rendererContext = layerRendererContext(); ASSERT(m_context); if (m_textureChanged) { - glBindTexture(GL_TEXTURE_2D, m_textureId); + rendererContext->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId); // Set the min-mag filters to linear and wrap modes to GL_CLAMP_TO_EDGE // to get around NPOT texture limitations of GLES. - 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); + rendererContext->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR); + rendererContext->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR); + rendererContext->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); + rendererContext->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); m_textureChanged = false; } // Update the contents of the texture used by the compositor. diff --git a/WebCore/platform/graphics/filters/FEBlend.cpp b/WebCore/platform/graphics/filters/FEBlend.cpp index 99c0ae7..acd6545 100644 --- a/WebCore/platform/graphics/filters/FEBlend.cpp +++ b/WebCore/platform/graphics/filters/FEBlend.cpp @@ -35,27 +35,15 @@ typedef unsigned char (*BlendType)(unsigned char colorA, unsigned char colorB, u namespace WebCore { -FEBlend::FEBlend(FilterEffect* in, FilterEffect* in2, BlendModeType mode) +FEBlend::FEBlend(BlendModeType mode) : FilterEffect() - , m_in(in) - , m_in2(in2) , m_mode(mode) { } -PassRefPtr<FEBlend> FEBlend::create(FilterEffect* in, FilterEffect* in2, BlendModeType mode) +PassRefPtr<FEBlend> FEBlend::create(BlendModeType mode) { - return adoptRef(new FEBlend(in, in2, mode)); -} - -FilterEffect* FEBlend::in2() const -{ - return m_in2.get(); -} - -void FEBlend::setIn2(FilterEffect* in2) -{ - m_in2 = in2; + return adoptRef(new FEBlend(mode)); } BlendModeType FEBlend::blendMode() const @@ -100,9 +88,11 @@ static unsigned char lighten(unsigned char colorA, unsigned char colorB, unsigne void FEBlend::apply(Filter* filter) { - m_in->apply(filter); - m_in2->apply(filter); - if (!m_in->resultImage() || !m_in2->resultImage()) + FilterEffect* in = inputEffect(0); + FilterEffect* in2 = inputEffect(1); + in->apply(filter); + in2->apply(filter); + if (!in->resultImage() || !in2->resultImage()) return; if (m_mode == FEBLEND_MODE_UNKNOWN) @@ -111,11 +101,11 @@ void FEBlend::apply(Filter* filter) if (!getEffectContext()) return; - IntRect effectADrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion()); - RefPtr<CanvasPixelArray> srcPixelArrayA(m_in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data()); + IntRect effectADrawingRect = calculateDrawingIntRect(in->repaintRectInLocalCoordinates()); + RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data()); - IntRect effectBDrawingRect = calculateDrawingIntRect(m_in2->scaledSubRegion()); - RefPtr<CanvasPixelArray> srcPixelArrayB(m_in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)->data()); + IntRect effectBDrawingRect = calculateDrawingIntRect(in2->repaintRectInLocalCoordinates()); + RefPtr<CanvasPixelArray> srcPixelArrayB(in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)->data()); IntRect imageRect(IntPoint(), resultImage()->size()); RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height()); @@ -176,8 +166,8 @@ TextStream& FEBlend::externalRepresentation(TextStream& ts, int indent) const ts << "[feBlend"; FilterEffect::externalRepresentation(ts); ts << " mode=\"" << m_mode << "\"]\n"; - m_in->externalRepresentation(ts, indent + 1); - m_in2->externalRepresentation(ts, indent + 1); + inputEffect(0)->externalRepresentation(ts, indent + 1); + inputEffect(1)->externalRepresentation(ts, indent + 1); return ts; } diff --git a/WebCore/platform/graphics/filters/FEBlend.h b/WebCore/platform/graphics/filters/FEBlend.h index 52de647..2e67588 100644 --- a/WebCore/platform/graphics/filters/FEBlend.h +++ b/WebCore/platform/graphics/filters/FEBlend.h @@ -40,24 +40,18 @@ namespace WebCore { class FEBlend : public FilterEffect { public: - static PassRefPtr<FEBlend> create(FilterEffect*, FilterEffect*, BlendModeType); - - FilterEffect* in2() const; - void setIn2(FilterEffect*); + static PassRefPtr<FEBlend> create(BlendModeType); BlendModeType blendMode() const; void setBlendMode(BlendModeType); - virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get(), m_in2.get()); } void apply(Filter*); void dump(); TextStream& externalRepresentation(TextStream&, int indent) const; private: - FEBlend(FilterEffect*, FilterEffect*, BlendModeType); + FEBlend(BlendModeType); - RefPtr<FilterEffect> m_in; - RefPtr<FilterEffect> m_in2; BlendModeType m_mode; }; diff --git a/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/WebCore/platform/graphics/filters/FEColorMatrix.cpp index 7718066..1d9c66b 100644 --- a/WebCore/platform/graphics/filters/FEColorMatrix.cpp +++ b/WebCore/platform/graphics/filters/FEColorMatrix.cpp @@ -34,17 +34,16 @@ namespace WebCore { -FEColorMatrix::FEColorMatrix(FilterEffect* in, ColorMatrixType type, const Vector<float>& values) +FEColorMatrix::FEColorMatrix(ColorMatrixType type, const Vector<float>& values) : FilterEffect() - , m_in(in) , m_type(type) , m_values(values) { } -PassRefPtr<FEColorMatrix> FEColorMatrix::create(FilterEffect* in, ColorMatrixType type, const Vector<float>& values) +PassRefPtr<FEColorMatrix> FEColorMatrix::create(ColorMatrixType type, const Vector<float>& values) { - return adoptRef(new FEColorMatrix(in, type, values)); + return adoptRef(new FEColorMatrix(type, values)); } ColorMatrixType FEColorMatrix::type() const @@ -156,15 +155,16 @@ void effectType(const PassRefPtr<CanvasPixelArray>& srcPixelArray, PassRefPtr<Im void FEColorMatrix::apply(Filter* filter) { - m_in->apply(filter); - if (!m_in->resultImage()) + FilterEffect* in = inputEffect(0); + in->apply(filter); + if (!in->resultImage()) return; GraphicsContext* filterContext = getEffectContext(); if (!filterContext) return; - filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); + filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, calculateDrawingRect(in->repaintRectInLocalCoordinates())); IntRect imageRect(IntPoint(), resultImage()->size()); PassRefPtr<ImageData> imageData(resultImage()->getUnmultipliedImageData(imageRect)); @@ -236,7 +236,7 @@ TextStream& FEColorMatrix::externalRepresentation(TextStream& ts, int indent) co ts << "\""; } ts << "]\n"; - m_in->externalRepresentation(ts, indent + 1); + inputEffect(0)->externalRepresentation(ts, indent + 1); return ts; } diff --git a/WebCore/platform/graphics/filters/FEColorMatrix.h b/WebCore/platform/graphics/filters/FEColorMatrix.h index 906d0f1..9b9084c 100644 --- a/WebCore/platform/graphics/filters/FEColorMatrix.h +++ b/WebCore/platform/graphics/filters/FEColorMatrix.h @@ -40,7 +40,7 @@ namespace WebCore { class FEColorMatrix : public FilterEffect { public: - static PassRefPtr<FEColorMatrix> create(FilterEffect*, ColorMatrixType, const Vector<float>&); + static PassRefPtr<FEColorMatrix> create(ColorMatrixType, const Vector<float>&); ColorMatrixType type() const; void setType(ColorMatrixType); @@ -48,15 +48,13 @@ namespace WebCore { const Vector<float>& values() const; void setValues(const Vector<float>&); - virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get()); } void apply(Filter*); void dump(); TextStream& externalRepresentation(TextStream&, int indent) const; private: - FEColorMatrix(FilterEffect*, ColorMatrixType, const Vector<float>&); + FEColorMatrix(ColorMatrixType, const Vector<float>&); - RefPtr<FilterEffect> m_in; ColorMatrixType m_type; Vector<float> m_values; }; diff --git a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp index 19df970..471fec8 100644 --- a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp +++ b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp @@ -36,10 +36,9 @@ namespace WebCore { typedef void (*TransferType)(unsigned char*, const ComponentTransferFunction&); -FEComponentTransfer::FEComponentTransfer(FilterEffect* in, const ComponentTransferFunction& redFunc, +FEComponentTransfer::FEComponentTransfer(const ComponentTransferFunction& redFunc, const ComponentTransferFunction& greenFunc, const ComponentTransferFunction& blueFunc, const ComponentTransferFunction& alphaFunc) : FilterEffect() - , m_in(in) , m_redFunc(redFunc) , m_greenFunc(greenFunc) , m_blueFunc(blueFunc) @@ -47,10 +46,10 @@ FEComponentTransfer::FEComponentTransfer(FilterEffect* in, const ComponentTransf { } -PassRefPtr<FEComponentTransfer> FEComponentTransfer::create(FilterEffect* in, const ComponentTransferFunction& redFunc, +PassRefPtr<FEComponentTransfer> FEComponentTransfer::create(const ComponentTransferFunction& redFunc, const ComponentTransferFunction& greenFunc, const ComponentTransferFunction& blueFunc, const ComponentTransferFunction& alphaFunc) { - return adoptRef(new FEComponentTransfer(in, redFunc, greenFunc, blueFunc, alphaFunc)); + return adoptRef(new FEComponentTransfer(redFunc, greenFunc, blueFunc, alphaFunc)); } ComponentTransferFunction FEComponentTransfer::redFunction() const @@ -150,8 +149,9 @@ static void gamma(unsigned char* values, const ComponentTransferFunction& transf void FEComponentTransfer::apply(Filter* filter) { - m_in->apply(filter); - if (!m_in->resultImage()) + FilterEffect* in = inputEffect(0); + in->apply(filter); + if (!in->resultImage()) return; if (!getEffectContext()) @@ -167,8 +167,8 @@ void FEComponentTransfer::apply(Filter* filter) for (unsigned channel = 0; channel < 4; channel++) (*callEffect[transferFunction[channel].type])(tables[channel], transferFunction[channel]); - IntRect drawingRect = calculateDrawingIntRect(m_in->scaledSubRegion()); - RefPtr<ImageData> imageData(m_in->resultImage()->getUnmultipliedImageData(drawingRect)); + IntRect drawingRect = calculateDrawingIntRect(in->repaintRectInLocalCoordinates()); + RefPtr<ImageData> imageData(in->resultImage()->getUnmultipliedImageData(drawingRect)); CanvasPixelArray* srcPixelArray(imageData->data()); for (unsigned pixelOffset = 0; pixelOffset < srcPixelArray->length(); pixelOffset += 4) { @@ -235,7 +235,7 @@ TextStream& FEComponentTransfer::externalRepresentation(TextStream& ts, int inde ts << "{blue: " << m_blueFunc << "}\n"; writeIndent(ts, indent + 2); ts << "{alpha: " << m_alphaFunc << "}]\n"; - m_in->externalRepresentation(ts, indent + 1); + inputEffect(0)->externalRepresentation(ts, indent + 1); return ts; } diff --git a/WebCore/platform/graphics/filters/FEComponentTransfer.h b/WebCore/platform/graphics/filters/FEComponentTransfer.h index 834d9ee..55724db 100644 --- a/WebCore/platform/graphics/filters/FEComponentTransfer.h +++ b/WebCore/platform/graphics/filters/FEComponentTransfer.h @@ -63,7 +63,7 @@ namespace WebCore { class FEComponentTransfer : public FilterEffect { public: - static PassRefPtr<FEComponentTransfer> create(FilterEffect*, const ComponentTransferFunction&, + static PassRefPtr<FEComponentTransfer> create(const ComponentTransferFunction&, const ComponentTransferFunction&, const ComponentTransferFunction&, const ComponentTransferFunction&); ComponentTransferFunction redFunction() const; @@ -78,16 +78,14 @@ namespace WebCore { ComponentTransferFunction alphaFunction() const; void setAlphaFunction(const ComponentTransferFunction&); - virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get()); } void apply(Filter*); void dump(); TextStream& externalRepresentation(TextStream&, int indent) const; private: - FEComponentTransfer(FilterEffect*,const ComponentTransferFunction&, const ComponentTransferFunction&, - const ComponentTransferFunction&, const ComponentTransferFunction&); + FEComponentTransfer(const ComponentTransferFunction&, const ComponentTransferFunction&, + const ComponentTransferFunction&, const ComponentTransferFunction&); - RefPtr<FilterEffect> m_in; ComponentTransferFunction m_redFunc; ComponentTransferFunction m_greenFunc; ComponentTransferFunction m_blueFunc; diff --git a/WebCore/platform/graphics/filters/FEComposite.cpp b/WebCore/platform/graphics/filters/FEComposite.cpp index d9f00ce..c10a0f2 100644 --- a/WebCore/platform/graphics/filters/FEComposite.cpp +++ b/WebCore/platform/graphics/filters/FEComposite.cpp @@ -32,11 +32,8 @@ namespace WebCore { -FEComposite::FEComposite(FilterEffect* in, FilterEffect* in2, const CompositeOperationType& type, - const float& k1, const float& k2, const float& k3, const float& k4) +FEComposite::FEComposite(const CompositeOperationType& type, float k1, float k2, float k3, float k4) : FilterEffect() - , m_in(in) - , m_in2(in2) , m_type(type) , m_k1(k1) , m_k2(k2) @@ -45,10 +42,9 @@ FEComposite::FEComposite(FilterEffect* in, FilterEffect* in2, const CompositeOpe { } -PassRefPtr<FEComposite> FEComposite::create(FilterEffect* in, FilterEffect* in2, const CompositeOperationType& type, - const float& k1, const float& k2, const float& k3, const float& k4) +PassRefPtr<FEComposite> FEComposite::create(const CompositeOperationType& type, float k1, float k2, float k3, float k4) { - return adoptRef(new FEComposite(in, in2, type, k1, k2, k3, k4)); + return adoptRef(new FEComposite(type, k1, k2, k3, k4)); } CompositeOperationType FEComposite::operation() const @@ -119,9 +115,11 @@ inline void arithmetic(const RefPtr<CanvasPixelArray>& srcPixelArrayA, CanvasPix void FEComposite::apply(Filter* filter) { - m_in->apply(filter); - m_in2->apply(filter); - if (!m_in->resultImage() || !m_in2->resultImage()) + FilterEffect* in = inputEffect(0); + FilterEffect* in2 = inputEffect(1); + in->apply(filter); + in2->apply(filter); + if (!in->resultImage() || !in2->resultImage()) return; GraphicsContext* filterContext = getEffectContext(); @@ -131,33 +129,33 @@ void FEComposite::apply(Filter* filter) FloatRect srcRect = FloatRect(0.f, 0.f, -1.f, -1.f); switch (m_type) { case FECOMPOSITE_OPERATOR_OVER: - filterContext->drawImageBuffer(m_in2->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion())); - filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); + filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, calculateDrawingRect(in2->repaintRectInLocalCoordinates())); + filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, calculateDrawingRect(in->repaintRectInLocalCoordinates())); break; case FECOMPOSITE_OPERATOR_IN: filterContext->save(); - filterContext->clipToImageBuffer(m_in2->resultImage(), calculateDrawingRect(m_in2->scaledSubRegion())); - filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); + filterContext->clipToImageBuffer(in2->resultImage(), calculateDrawingRect(in2->repaintRectInLocalCoordinates())); + filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, calculateDrawingRect(in->repaintRectInLocalCoordinates())); filterContext->restore(); break; case FECOMPOSITE_OPERATOR_OUT: - filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); - filterContext->drawImageBuffer(m_in2->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion()), srcRect, CompositeDestinationOut); + filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, calculateDrawingRect(in->repaintRectInLocalCoordinates())); + filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, calculateDrawingRect(in2->repaintRectInLocalCoordinates()), srcRect, CompositeDestinationOut); break; case FECOMPOSITE_OPERATOR_ATOP: - filterContext->drawImageBuffer(m_in2->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion())); - filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()), srcRect, CompositeSourceAtop); + filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, calculateDrawingRect(in2->repaintRectInLocalCoordinates())); + filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, calculateDrawingRect(in->repaintRectInLocalCoordinates()), srcRect, CompositeSourceAtop); break; case FECOMPOSITE_OPERATOR_XOR: - filterContext->drawImageBuffer(m_in2->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion())); - filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()), srcRect, CompositeXOR); + filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, calculateDrawingRect(in2->repaintRectInLocalCoordinates())); + filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, calculateDrawingRect(in->repaintRectInLocalCoordinates()), srcRect, CompositeXOR); break; case FECOMPOSITE_OPERATOR_ARITHMETIC: { - IntRect effectADrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion()); - RefPtr<CanvasPixelArray> srcPixelArrayA(m_in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data()); + IntRect effectADrawingRect = calculateDrawingIntRect(in->repaintRectInLocalCoordinates()); + RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data()); - IntRect effectBDrawingRect = calculateDrawingIntRect(m_in2->scaledSubRegion()); - RefPtr<ImageData> imageData(m_in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)); + IntRect effectBDrawingRect = calculateDrawingIntRect(in2->repaintRectInLocalCoordinates()); + RefPtr<ImageData> imageData(in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)); CanvasPixelArray* srcPixelArrayB(imageData->data()); arithmetic(srcPixelArrayA, srcPixelArrayB, m_k1, m_k2, m_k3, m_k4); @@ -210,8 +208,8 @@ TextStream& FEComposite::externalRepresentation(TextStream& ts, int indent) cons if (m_type == FECOMPOSITE_OPERATOR_ARITHMETIC) ts << " k1=\"" << m_k1 << "\" k2=\"" << m_k2 << "\" k3=\"" << m_k3 << "\" k4=\"" << m_k4 << "\""; ts << "]\n"; - m_in->externalRepresentation(ts, indent + 1); - m_in2->externalRepresentation(ts, indent + 1); + inputEffect(0)->externalRepresentation(ts, indent + 1); + inputEffect(1)->externalRepresentation(ts, indent + 1); return ts; } diff --git a/WebCore/platform/graphics/filters/FEComposite.h b/WebCore/platform/graphics/filters/FEComposite.h index 11268c7..448d036 100644 --- a/WebCore/platform/graphics/filters/FEComposite.h +++ b/WebCore/platform/graphics/filters/FEComposite.h @@ -42,8 +42,7 @@ enum CompositeOperationType { class FEComposite : public FilterEffect { public: - static PassRefPtr<FEComposite> create(FilterEffect*, FilterEffect*, const CompositeOperationType&, - const float&, const float&, const float&, const float&); + static PassRefPtr<FEComposite> create(const CompositeOperationType&, float, float, float, float); CompositeOperationType operation() const; void setOperation(CompositeOperationType); @@ -60,17 +59,13 @@ public: float k4() const; void setK4(float); - virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get(), m_in2.get()); } void apply(Filter*); void dump(); TextStream& externalRepresentation(TextStream&, int indent) const; private: - FEComposite(FilterEffect*, FilterEffect*, const CompositeOperationType&, - const float&, const float&, const float&, const float&); + FEComposite(const CompositeOperationType&, float, float, float, float); - RefPtr<FilterEffect> m_in; - RefPtr<FilterEffect> m_in2; CompositeOperationType m_type; float m_k1; float m_k2; diff --git a/WebCore/platform/graphics/filters/FEGaussianBlur.cpp b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp index 44bb65a..72a5a04 100644 --- a/WebCore/platform/graphics/filters/FEGaussianBlur.cpp +++ b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp @@ -38,17 +38,16 @@ static const float gGaussianKernelFactor = (3 * sqrtf(2 * piFloat) / 4.f); namespace WebCore { -FEGaussianBlur::FEGaussianBlur(FilterEffect* in, const float& x, const float& y) +FEGaussianBlur::FEGaussianBlur(float x, float y) : FilterEffect() - , m_in(in) , m_stdX(x) , m_stdY(y) { } -PassRefPtr<FEGaussianBlur> FEGaussianBlur::create(FilterEffect* in, const float& x, const float& y) +PassRefPtr<FEGaussianBlur> FEGaussianBlur::create(float x, float y) { - return adoptRef(new FEGaussianBlur(in, x, y)); + return adoptRef(new FEGaussianBlur(x, y)); } float FEGaussianBlur::stdDeviationX() const @@ -128,17 +127,18 @@ void FEGaussianBlur::kernelPosition(int boxBlur, unsigned& std, int& dLeft, int& void FEGaussianBlur::apply(Filter* filter) { - m_in->apply(filter); - if (!m_in->resultImage()) + FilterEffect* in = inputEffect(0); + in->apply(filter); + if (!in->resultImage()) return; if (!getEffectContext()) return; - setIsAlphaImage(m_in->isAlphaImage()); + setIsAlphaImage(in->isAlphaImage()); - IntRect effectDrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion()); - RefPtr<ImageData> srcImageData(m_in->resultImage()->getPremultipliedImageData(effectDrawingRect)); + IntRect effectDrawingRect = calculateDrawingIntRect(in->repaintRectInLocalCoordinates()); + RefPtr<ImageData> srcImageData(in->resultImage()->getPremultipliedImageData(effectDrawingRect)); IntRect imageRect(IntPoint(), resultImage()->size()); if (!m_stdX && !m_stdY) { @@ -196,7 +196,7 @@ TextStream& FEGaussianBlur::externalRepresentation(TextStream& ts, int indent) c ts << "[feGaussianBlur"; FilterEffect::externalRepresentation(ts); ts << " stdDeviation=\"" << m_stdX << ", " << m_stdY << "\"]\n"; - m_in->externalRepresentation(ts, indent + 1); + inputEffect(0)->externalRepresentation(ts, indent + 1); return ts; } diff --git a/WebCore/platform/graphics/filters/FEGaussianBlur.h b/WebCore/platform/graphics/filters/FEGaussianBlur.h index ad5c5a3..63d763e 100644 --- a/WebCore/platform/graphics/filters/FEGaussianBlur.h +++ b/WebCore/platform/graphics/filters/FEGaussianBlur.h @@ -30,7 +30,7 @@ namespace WebCore { class FEGaussianBlur : public FilterEffect { public: - static PassRefPtr<FEGaussianBlur> create(FilterEffect*, const float&, const float&); + static PassRefPtr<FEGaussianBlur> create(float, float); float stdDeviationX() const; void setStdDeviationX(float); @@ -38,7 +38,6 @@ public: float stdDeviationY() const; void setStdDeviationY(float); - virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get()); } void apply(Filter*); void dump(); TextStream& externalRepresentation(TextStream&, int indent) const; @@ -46,10 +45,9 @@ public: static float calculateStdDeviation(float); private: - FEGaussianBlur(FilterEffect*, const float&, const float&); + FEGaussianBlur(float, float); static void kernelPosition(int boxBlur, unsigned& std, int& dLeft, int& dRight); - RefPtr<FilterEffect> m_in; float m_stdX; float m_stdY; }; diff --git a/WebCore/platform/graphics/filters/Filter.h b/WebCore/platform/graphics/filters/Filter.h index 16d499f..7ad25aa 100644 --- a/WebCore/platform/graphics/filters/Filter.h +++ b/WebCore/platform/graphics/filters/Filter.h @@ -48,7 +48,7 @@ namespace WebCore { virtual FloatRect filterRegion() const = 0; // SVG specific - virtual void calculateEffectSubRegion(FilterEffect*) { } + virtual void determineFilterPrimitiveSubregion(FilterEffect*, const FloatRect&) { } virtual FloatSize maxImageSize() const = 0; virtual bool effectBoundingBoxMode() const = 0; diff --git a/WebCore/platform/graphics/filters/FilterEffect.cpp b/WebCore/platform/graphics/filters/FilterEffect.cpp index 4d7265c..b6278b2 100644 --- a/WebCore/platform/graphics/filters/FilterEffect.cpp +++ b/WebCore/platform/graphics/filters/FilterEffect.cpp @@ -1,21 +1,23 @@ /* - Copyright (C) Alex Mathews <possessedpenguinbob@gmail.com> - - 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 - aint 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. -*/ + * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com> + * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> + * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * + * 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" @@ -25,11 +27,11 @@ namespace WebCore { FilterEffect::FilterEffect() - : m_hasX(false) + : m_alphaImage(false) + , m_hasX(false) , m_hasY(false) , m_hasWidth(false) , m_hasHeight(false) - , m_alphaImage(false) { } @@ -37,43 +39,49 @@ FilterEffect::~FilterEffect() { } -FloatRect FilterEffect::calculateUnionOfChildEffectSubregions(Filter* filter, FilterEffect* in) -{ - return in->calculateEffectRect(filter); -} - -FloatRect FilterEffect::calculateUnionOfChildEffectSubregions(Filter* filter, FilterEffect* in, FilterEffect* in2) +FloatRect FilterEffect::determineFilterPrimitiveSubregion(Filter* filter) { - FloatRect uniteEffectRect = in->calculateEffectRect(filter); - uniteEffectRect.unite(in2->calculateEffectRect(filter)); - return uniteEffectRect; + FloatRect uniteRect; + unsigned size = m_inputEffects.size(); + + // FETurbulence, FEImage and FEFlood don't have input effects, take the filter region as unite rect. + if (!size) + uniteRect = filter->filterRegion(); + else { + for (unsigned i = 0; i < size; ++i) + uniteRect.unite(m_inputEffects.at(i)->determineFilterPrimitiveSubregion(filter)); + } + + filter->determineFilterPrimitiveSubregion(this, uniteRect); + return m_filterPrimitiveSubregion; } -FloatRect FilterEffect::calculateEffectRect(Filter* filter) +IntRect FilterEffect::calculateDrawingIntRect(const FloatRect& effectRect) const { - setUnionOfChildEffectSubregions(uniteChildEffectSubregions(filter)); - filter->calculateEffectSubRegion(this); - return subRegion(); + ASSERT(m_effectBuffer); + FloatPoint location = m_repaintRectInLocalCoordinates.location(); + location.move(-effectRect.x(), -effectRect.y()); + return IntRect(roundedIntPoint(location), m_effectBuffer->size()); } -IntRect FilterEffect::calculateDrawingIntRect(const FloatRect& effectRect) +FloatRect FilterEffect::calculateDrawingRect(const FloatRect& srcRect) const { - IntPoint location = roundedIntPoint(FloatPoint(scaledSubRegion().x() - effectRect.x(), - scaledSubRegion().y() - effectRect.y())); - return IntRect(location, resultImage()->size()); + return FloatRect(FloatPoint(srcRect.x() - m_repaintRectInLocalCoordinates.x(), + srcRect.y() - m_repaintRectInLocalCoordinates.y()), srcRect.size()); } -FloatRect FilterEffect::calculateDrawingRect(const FloatRect& srcRect) +FilterEffect* FilterEffect::inputEffect(unsigned number) const { - FloatPoint startPoint = FloatPoint(srcRect.x() - scaledSubRegion().x(), srcRect.y() - scaledSubRegion().y()); - FloatRect drawingRect = FloatRect(startPoint, srcRect.size()); - return drawingRect; + ASSERT(number < m_inputEffects.size()); + return m_inputEffects.at(number).get(); } GraphicsContext* FilterEffect::getEffectContext() { - IntRect bufferRect = enclosingIntRect(scaledSubRegion()); + IntRect bufferRect = enclosingIntRect(m_repaintRectInLocalCoordinates); m_effectBuffer = ImageBuffer::create(bufferRect.size(), LinearRGB); + if (!m_effectBuffer) + return 0; return m_effectBuffer->context(); } diff --git a/WebCore/platform/graphics/filters/FilterEffect.h b/WebCore/platform/graphics/filters/FilterEffect.h index 3b8b5a3..91c52f3 100644 --- a/WebCore/platform/graphics/filters/FilterEffect.h +++ b/WebCore/platform/graphics/filters/FilterEffect.h @@ -1,22 +1,23 @@ /* - Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com> - 2009 Dirk Schulze <krit@webkit.org> - - 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 - aint 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. -*/ + * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com> + * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> + * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * + * 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 FilterEffect_h #define FilterEffect_h @@ -32,84 +33,97 @@ #include <wtf/PassOwnPtr.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> +#include <wtf/Vector.h> namespace WebCore { - class FilterEffect : public RefCounted<FilterEffect> { - public: - virtual ~FilterEffect(); +typedef Vector<RefPtr<FilterEffect> > FilterEffectVector; + +class FilterEffect : public RefCounted<FilterEffect> { +public: + virtual ~FilterEffect(); + + // The result is bounded to the size of the filter primitive to save resources. + ImageBuffer* resultImage() const { return m_effectBuffer.get(); } + void setEffectBuffer(PassOwnPtr<ImageBuffer> effectBuffer) { m_effectBuffer = effectBuffer; } + + // Creates the ImageBuffer for the current filter primitive result in the size of the + // repaintRect. Gives back the GraphicsContext of the own ImageBuffer. + GraphicsContext* getEffectContext(); - void setUnionOfChildEffectSubregions(const FloatRect& uniteRect) { m_unionOfChildEffectSubregions = uniteRect; } - FloatRect unionOfChildEffectSubregions() const { return m_unionOfChildEffectSubregions; } + FilterEffectVector& inputEffects() { return m_inputEffects; } + FilterEffect* inputEffect(unsigned) const; + unsigned numberOfEffectInputs() const { return m_inputEffects.size(); } - FloatRect subRegion() const { return m_subRegion; } - void setSubRegion(const FloatRect& subRegion) { m_subRegion = subRegion; } + FloatRect calculateDrawingRect(const FloatRect&) const; + IntRect calculateDrawingIntRect(const FloatRect&) const; - FloatRect scaledSubRegion() const { return m_scaledSubRegion; } - void setScaledSubRegion(const FloatRect& scaledSubRegion) { m_scaledSubRegion = scaledSubRegion; } + // Solid black image with different alpha values. + bool isAlphaImage() const { return m_alphaImage; } + void setIsAlphaImage(bool alphaImage) { m_alphaImage = alphaImage; } - FloatRect effectBoundaries() const { return m_effectBoundaries; } - void setEffectBoundaries(const FloatRect& effectBoundaries) { m_effectBoundaries = effectBoundaries; } + FloatRect repaintRectInLocalCoordinates() const { return m_repaintRectInLocalCoordinates; } + void setRepaintRectInLocalCoordinates(const FloatRect& repaintRectInLocalCoordinates) { m_repaintRectInLocalCoordinates = repaintRectInLocalCoordinates; } - bool hasX() { return m_hasX; } - void setHasX(bool value) { m_hasX = value; } + virtual void apply(Filter*) = 0; + virtual void dump() = 0; - bool hasY() { return m_hasY; } - void setHasY(bool value) { m_hasY = value; } + virtual bool isSourceInput() const { return false; } - bool hasWidth() { return m_hasWidth; } - void setHasWidth(bool value) { m_hasWidth = value; } + virtual TextStream& externalRepresentation(TextStream&, int indention = 0) const; - bool hasHeight() { return m_hasHeight; } - void setHasHeight(bool value) { m_hasHeight = value; } +public: + // The following functions are SVG specific and will move to RenderSVGResourceFilterPrimitive. + // See bug https://bugs.webkit.org/show_bug.cgi?id=45614. + bool hasX() const { return m_hasX; } + void setHasX(bool value) { m_hasX = value; } - // The result is bounded by the size of the filter primitive to save resources - ImageBuffer* resultImage() { return m_effectBuffer.get(); } - void setEffectBuffer(PassOwnPtr<ImageBuffer> effectBuffer) { m_effectBuffer = effectBuffer; } + bool hasY() const { return m_hasY; } + void setHasY(bool value) { m_hasY = value; } - FloatRect calculateUnionOfChildEffectSubregions(Filter*, FilterEffect*, FilterEffect*); - FloatRect calculateUnionOfChildEffectSubregions(Filter*, FilterEffect*); + bool hasWidth() const { return m_hasWidth; } + void setHasWidth(bool value) { m_hasWidth = value; } - GraphicsContext* getEffectContext(); - FloatRect calculateDrawingRect(const FloatRect&); - IntRect calculateDrawingIntRect(const FloatRect&); + bool hasHeight() const { return m_hasHeight; } + void setHasHeight(bool value) { m_hasHeight = value; } - // black image with different alpha values - bool isAlphaImage() { return m_alphaImage; } - void setIsAlphaImage(bool alphaImage) { m_alphaImage = alphaImage; } + // FIXME: Pseudo primitives like SourceGraphic and SourceAlpha as well as FETile still need special handling. + virtual FloatRect determineFilterPrimitiveSubregion(Filter*); - virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return filter->filterRegion(); } - virtual FloatRect calculateEffectRect(Filter*); - virtual void apply(Filter*) = 0; - virtual void dump() = 0; + FloatRect filterPrimitiveSubregion() const { return m_filterPrimitiveSubregion; } + void setFilterPrimitiveSubregion(const FloatRect& filterPrimitiveSubregion) { m_filterPrimitiveSubregion = filterPrimitiveSubregion; } - virtual bool isSourceInput() { return false; } + FloatRect effectBoundaries() const { return m_effectBoundaries; } + void setEffectBoundaries(const FloatRect& effectBoundaries) { m_effectBoundaries = effectBoundaries; } - virtual TextStream& externalRepresentation(TextStream&, int indention = 0) const; - protected: - FilterEffect(); +protected: + FilterEffect(); - private: +private: + OwnPtr<ImageBuffer> m_effectBuffer; + FilterEffectVector m_inputEffects; - bool m_xBBoxMode : 1; - bool m_yBBoxMode : 1; - bool m_widthBBoxMode : 1; - bool m_heightBBoxMode : 1; + bool m_alphaImage; - bool m_hasX : 1; - bool m_hasY : 1; - bool m_hasWidth : 1; - bool m_hasHeight : 1; + // FIXME: Should be the paint region of the filter primitive, instead of the scaled subregion on use of filterRes. + FloatRect m_repaintRectInLocalCoordinates; - bool m_alphaImage; +private: + // The following member variables are SVG specific and will move to RenderSVGResourceFilterPrimitive. + // See bug https://bugs.webkit.org/show_bug.cgi?id=45614. - FloatRect m_effectBoundaries; - FloatRect m_subRegion; - FloatRect m_scaledSubRegion; - FloatRect m_unionOfChildEffectSubregions; + // The subregion of a filter primitive according to the SVG Filter specification in local coordinates. + // This is SVG specific and needs to move to RenderSVGResourceFilterPrimitive. + FloatRect m_filterPrimitiveSubregion; - mutable OwnPtr<ImageBuffer> m_effectBuffer; - }; + // x, y, width and height of the actual SVGFE*Element. Is needed to determine the subregion of the + // filter primitive on a later step. + FloatRect m_effectBoundaries; + bool m_hasX; + bool m_hasY; + bool m_hasWidth; + bool m_hasHeight; +}; } // namespace WebCore diff --git a/WebCore/platform/graphics/filters/SourceAlpha.cpp b/WebCore/platform/graphics/filters/SourceAlpha.cpp index 37b0023..9c6a953 100644 --- a/WebCore/platform/graphics/filters/SourceAlpha.cpp +++ b/WebCore/platform/graphics/filters/SourceAlpha.cpp @@ -42,16 +42,16 @@ const AtomicString& SourceAlpha::effectName() return s_effectName; } -FloatRect SourceAlpha::calculateEffectRect(Filter* filter) +FloatRect SourceAlpha::determineFilterPrimitiveSubregion(Filter* filter) { FloatRect clippedSourceRect = filter->sourceImageRect(); if (filter->sourceImageRect().x() < filter->filterRegion().x()) clippedSourceRect.setX(filter->filterRegion().x()); if (filter->sourceImageRect().y() < filter->filterRegion().y()) clippedSourceRect.setY(filter->filterRegion().y()); - setSubRegion(clippedSourceRect); + setFilterPrimitiveSubregion(clippedSourceRect); clippedSourceRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); - setScaledSubRegion(clippedSourceRect); + setRepaintRectInLocalCoordinates(clippedSourceRect); return filter->filterRegion(); } diff --git a/WebCore/platform/graphics/filters/SourceAlpha.h b/WebCore/platform/graphics/filters/SourceAlpha.h index e5c6815..25a17b2 100644 --- a/WebCore/platform/graphics/filters/SourceAlpha.h +++ b/WebCore/platform/graphics/filters/SourceAlpha.h @@ -34,11 +34,12 @@ namespace WebCore { static const AtomicString& effectName(); - virtual bool isSourceInput() { return true; } - virtual FloatRect calculateEffectRect(Filter*); void apply(Filter*); void dump(); TextStream& externalRepresentation(TextStream&, int indent) const; + + virtual bool isSourceInput() const { return true; } + virtual FloatRect determineFilterPrimitiveSubregion(Filter*); private: SourceAlpha() { } diff --git a/WebCore/platform/graphics/filters/SourceGraphic.cpp b/WebCore/platform/graphics/filters/SourceGraphic.cpp index 5730d34..6a32e36 100644 --- a/WebCore/platform/graphics/filters/SourceGraphic.cpp +++ b/WebCore/platform/graphics/filters/SourceGraphic.cpp @@ -41,16 +41,16 @@ const AtomicString& SourceGraphic::effectName() return s_effectName; } -FloatRect SourceGraphic::calculateEffectRect(Filter* filter) +FloatRect SourceGraphic::determineFilterPrimitiveSubregion(Filter* filter) { FloatRect clippedSourceRect = filter->sourceImageRect(); if (filter->sourceImageRect().x() < filter->filterRegion().x()) clippedSourceRect.setX(filter->filterRegion().x()); if (filter->sourceImageRect().y() < filter->filterRegion().y()) clippedSourceRect.setY(filter->filterRegion().y()); - setSubRegion(clippedSourceRect); + setFilterPrimitiveSubregion(clippedSourceRect); clippedSourceRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); - setScaledSubRegion(clippedSourceRect); + setRepaintRectInLocalCoordinates(clippedSourceRect); return filter->filterRegion(); } diff --git a/WebCore/platform/graphics/filters/SourceGraphic.h b/WebCore/platform/graphics/filters/SourceGraphic.h index 05238a2..911648c 100644 --- a/WebCore/platform/graphics/filters/SourceGraphic.h +++ b/WebCore/platform/graphics/filters/SourceGraphic.h @@ -35,12 +35,13 @@ namespace WebCore { static const AtomicString& effectName(); - virtual bool isSourceInput() { return true; } - virtual FloatRect calculateEffectRect(Filter*); void apply(Filter*); void dump(); TextStream& externalRepresentation(TextStream&, int indent) const; - + + virtual bool isSourceInput() const { return true; } + virtual FloatRect determineFilterPrimitiveSubregion(Filter*); + private: SourceGraphic() { } }; diff --git a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp index 6424293..7629735 100644 --- a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp +++ b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp @@ -58,11 +58,13 @@ SharedGraphicsContext3D::SharedGraphicsContext3D(PassOwnPtr<GraphicsContext3D> c , m_solidFillShader(SolidFillShader::create(m_context.get())) , m_texShader(TexShader::create(m_context.get())) { + allContexts()->add(this); } SharedGraphicsContext3D::~SharedGraphicsContext3D() { m_context->deleteBuffer(m_quadVertices); + allContexts()->remove(this); } void SharedGraphicsContext3D::makeContextCurrent() @@ -112,6 +114,11 @@ void SharedGraphicsContext3D::getIntegerv(unsigned long pname, int* value) m_context->getIntegerv(pname, value); } +void SharedGraphicsContext3D::flush() +{ + m_context->flush(); +} + unsigned SharedGraphicsContext3D::createFramebuffer() { return m_context->createFramebuffer(); @@ -162,6 +169,17 @@ bool SharedGraphicsContext3D::supportsBGRA() return m_context->supportsBGRA(); } +bool SharedGraphicsContext3D::supportsCopyTextureToParentTextureCHROMIUM() + +{ + return m_context->supportsCopyTextureToParentTextureCHROMIUM(); +} + +void SharedGraphicsContext3D::copyTextureToParentTextureCHROMIUM(unsigned texture, unsigned parentTexture) +{ + return m_context->copyTextureToParentTextureCHROMIUM(texture, parentTexture); +} + Texture* SharedGraphicsContext3D::createTexture(NativeImagePtr ptr, Texture::Format format, int width, int height) { RefPtr<Texture> texture = m_textures.get(ptr); @@ -180,6 +198,28 @@ Texture* SharedGraphicsContext3D::getTexture(NativeImagePtr ptr) return texture ? texture.get() : 0; } +void SharedGraphicsContext3D::removeTextureFor(NativeImagePtr ptr) +{ + TextureHashMap::iterator it = m_textures.find(ptr); + if (it != m_textures.end()) + m_textures.remove(it); +} + +// static +void SharedGraphicsContext3D::removeTexturesFor(NativeImagePtr ptr) +{ + for (HashSet<SharedGraphicsContext3D*>::iterator it = allContexts()->begin(); it != allContexts()->end(); ++it) + (*it)->removeTextureFor(ptr); +} + +// static +HashSet<SharedGraphicsContext3D*>* SharedGraphicsContext3D::allContexts() +{ + static OwnPtr<HashSet<SharedGraphicsContext3D*> > set(new HashSet<SharedGraphicsContext3D*>); + return set.get(); +} + + PassRefPtr<Texture> SharedGraphicsContext3D::createTexture(Texture::Format format, int width, int height) { return Texture::create(m_context.get(), format, width, height); diff --git a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h index 1baa0f6..3ba3c52 100644 --- a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h +++ b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h @@ -36,6 +36,7 @@ #include "Texture.h" #include <wtf/HashMap.h> +#include <wtf/HashSet.h> #include <wtf/OwnPtr.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> @@ -69,6 +70,7 @@ public: void drawArrays(unsigned long mode, long first, long count); unsigned long getError(); void getIntegerv(unsigned long pname, int* value); + void flush(); unsigned createFramebuffer(); unsigned createTexture(); @@ -97,17 +99,30 @@ public: bool supportsBGRA(); + // GL_CHROMIUM_copy_texture_to_parent_texture + bool supportsCopyTextureToParentTextureCHROMIUM(); + void copyTextureToParentTextureCHROMIUM(unsigned texture, unsigned parentTexture); + // Creates a texture associated with the given image. Is owned by this context's // TextureHashMap. Texture* createTexture(NativeImagePtr, Texture::Format, int width, int height); Texture* getTexture(NativeImagePtr); + // Multiple SharedGraphicsContext3D can exist in a single process (one per compositing context) and the same + // NativeImagePtr may be uploaded as a texture into all of them. This function removes uploaded textures + // for a given NativeImagePtr in all contexts. + static void removeTexturesFor(NativeImagePtr); + // Creates a texture that is not associated with any image. The caller takes ownership of // the texture. PassRefPtr<Texture> createTexture(Texture::Format, int width, int height); private: - SharedGraphicsContext3D(PassOwnPtr<GraphicsContext3D> context); + explicit SharedGraphicsContext3D(PassOwnPtr<GraphicsContext3D> context); + + // Used to implement removeTexturesFor(), see the comment above. + static HashSet<SharedGraphicsContext3D*>* allContexts(); + void removeTextureFor(NativeImagePtr); OwnPtr<GraphicsContext3D> m_context; diff --git a/WebCore/platform/graphics/gpu/SolidFillShader.cpp b/WebCore/platform/graphics/gpu/SolidFillShader.cpp index bbc4792..ff1b1fa 100644 --- a/WebCore/platform/graphics/gpu/SolidFillShader.cpp +++ b/WebCore/platform/graphics/gpu/SolidFillShader.cpp @@ -54,7 +54,9 @@ PassOwnPtr<SolidFillShader> SolidFillShader::create(GraphicsContext3D* context) " gl_Position = vec4(matrix * position, 1.0);\n" "}\n"; static const char* fragmentShaderSource = + "#ifdef GL_ES\n" "precision mediump float;\n" + "#endif\n" "uniform mat3 matrix;\n" "uniform vec4 color;\n" "void main() {\n" diff --git a/WebCore/platform/graphics/gpu/TexShader.cpp b/WebCore/platform/graphics/gpu/TexShader.cpp index ba3ecdd..01f4306 100644 --- a/WebCore/platform/graphics/gpu/TexShader.cpp +++ b/WebCore/platform/graphics/gpu/TexShader.cpp @@ -57,7 +57,9 @@ PassOwnPtr<TexShader> TexShader::create(GraphicsContext3D* context) " gl_Position = vec4(matrix * position, 1.0);\n" "}\n"; static const char* fragmentShaderSource = + "#ifdef GL_ES\n" "precision mediump float;\n" + "#endif\n" "uniform sampler2D sampler;\n" "uniform float alpha;\n" "varying vec3 texCoord;\n" diff --git a/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp b/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp index 2ff4f38..efccff0 100644 --- a/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp +++ b/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp @@ -195,7 +195,11 @@ void GStreamerGWorld::setWindowOverlay(GstMessage* message) g_object_set(sink, "force-aspect-ratio", TRUE, NULL); if (m_videoWindow) +#if GST_CHECK_VERSION(0, 10, 31) || GST_VERSION_NANO + gst_x_overlay_set_window_handle(GST_X_OVERLAY(sink), m_videoWindow->videoWindowId()); +#else gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(sink), m_videoWindow->videoWindowId()); +#endif } } diff --git a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp index 4791b4c..0071d67 100644 --- a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp +++ b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp @@ -23,6 +23,7 @@ #include "config.h" #include "MediaPlayerPrivateGStreamer.h" + #if ENABLE(VIDEO) #include "ColorSpace.h" @@ -40,19 +41,15 @@ #include "MIMETypeRegistry.h" #include "MediaPlayer.h" #include "NotImplemented.h" -#include "ScrollView.h" #include "SecurityOrigin.h" #include "TimeRanges.h" #include "VideoSinkGStreamer.h" #include "WebKitWebSourceGStreamer.h" -#include "Widget.h" #include <GOwnPtr.h> #include <gst/gst.h> -#include <gst/interfaces/mixer.h> #include <gst/video/video.h> #include <limits> #include <math.h> -#include <wtf/text/CString.h> // GstPlayFlags flags from playbin2. It is the policy of GStreamer to // not publicly expose element-specific enums. That's why this diff --git a/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp b/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp index bcd59c6..4e57193 100644 --- a/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp +++ b/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp @@ -23,6 +23,7 @@ #include "Document.h" #include "GOwnPtr.h" #include "GRefPtr.h" +#include "NetworkingContext.h" #include "Noncopyable.h" #include "NotImplemented.h" #include "ResourceHandleClient.h" @@ -43,7 +44,7 @@ class StreamingClient : public Noncopyable, public ResourceHandleClient { virtual void willSendRequest(ResourceHandle*, ResourceRequest&, const ResourceResponse&); virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); virtual void didReceiveData(ResourceHandle*, const char*, int, int); - virtual void didFinishLoading(ResourceHandle*); + virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/); virtual void didFail(ResourceHandle*, const ResourceError&); virtual void wasBlocked(ResourceHandle*); virtual void cannotShowURL(ResourceHandle*); @@ -391,14 +392,17 @@ static bool webKitWebSrcStart(WebKitWebSrc* src) request.setTargetType(ResourceRequestBase::TargetIsMedia); request.setAllowCookies(true); + NetworkingContext* context = 0; if (priv->frame) { Document* document = priv->frame->document(); if (document) request.setHTTPReferrer(document->documentURI()); FrameLoader* loader = priv->frame->loader(); - if (loader) + if (loader) { loader->addExtraFieldsToSubresourceRequest(request); + context = loader->networkingContext(); + } } // Let Apple web servers know we want to access their nice movie trailers. @@ -419,7 +423,7 @@ static bool webKitWebSrcStart(WebKitWebSrc* src) // Needed to use DLNA streaming servers request.setHTTPHeaderField("transferMode.dlna", "Streaming"); - priv->resourceHandle = ResourceHandle::create(request, priv->client, 0, false, false); + priv->resourceHandle = ResourceHandle::create(context, request, priv->client, false, false); if (!priv->resourceHandle) { GST_ERROR_OBJECT(src, "Failed to create ResourceHandle"); return false; @@ -762,7 +766,7 @@ void StreamingClient::didReceiveData(ResourceHandle* handle, const char* data, i GST_ELEMENT_ERROR(m_src, CORE, FAILED, (0), (0)); } -void StreamingClient::didFinishLoading(ResourceHandle*) +void StreamingClient::didFinishLoading(ResourceHandle*, double) { WebKitWebSrcPrivate* priv = m_src->priv; diff --git a/WebCore/platform/graphics/gtk/FontCachePango.cpp b/WebCore/platform/graphics/gtk/FontCachePango.cpp new file mode 100644 index 0000000..fad29e0 --- /dev/null +++ b/WebCore/platform/graphics/gtk/FontCachePango.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2008 Alp Toker <alp@atoker.com> + * + * 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 "FontCache.h" + +#include "CString.h" +#include "Font.h" +#include "OwnPtrCairo.h" +#include "SimpleFontData.h" +#include <wtf/Assertions.h> + +namespace WebCore { + +void FontCache::platformInit() +{ + if (!FontPlatformData::init()) + ASSERT_NOT_REACHED(); +} + +const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) +{ + return 0; +} + +SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font) +{ + return 0; +} + +SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& fontDescription) +{ + // FIXME: Would be even better to somehow get the user's default font here. + // For now we'll pick the default that the user would get without changing any prefs. + static AtomicString timesStr("Times New Roman"); + return getCachedFontData(fontDescription, timesStr); +} + +void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks) +{ +} + +FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family) +{ + return new FontPlatformData(fontDescription, family); +} + +} diff --git a/WebCore/platform/graphics/gtk/FontGtk.cpp b/WebCore/platform/graphics/gtk/FontGtk.cpp index 489bad7..27f48fc 100644 --- a/WebCore/platform/graphics/gtk/FontGtk.cpp +++ b/WebCore/platform/graphics/gtk/FontGtk.cpp @@ -139,7 +139,7 @@ static void setPangoAttributes(const Font* font, const TextRun& run, PangoLayout { #if defined(USE_FREETYPE) if (font->primaryFont()->platformData().m_pattern) { - PangoFontDescription* desc = pango_fc_font_description_from_pattern(font->primaryFont()->platformData().m_pattern, FALSE); + PangoFontDescription* desc = pango_fc_font_description_from_pattern(font->primaryFont()->platformData().m_pattern.get(), FALSE); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); } diff --git a/WebCore/platform/graphics/gtk/FontPlatformDataPango.h b/WebCore/platform/graphics/gtk/FontPlatformDataPango.h new file mode 100644 index 0000000..7b1e51f --- /dev/null +++ b/WebCore/platform/graphics/gtk/FontPlatformDataPango.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2006, 2007, 2008 Apple Inc. + * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com + * Copyright (C) 2007 Holger Hans Peter Freyther + * Copyright (C) 2007 Pioneer Research Center USA, Inc. + * All rights reserved. + * + * 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 FontPlatformDataPango_h +#define FontPlatformDataPango_h + +#include "FontDescription.h" +#include "GlyphBuffer.h" +#include <cairo.h> +#include <pango/pangocairo.h> +#include <wtf/Forward.h> + +namespace WebCore { + +class FontPlatformData { +public: + FontPlatformData(WTF::HashTableDeletedValueType) + : m_context(0) + , m_font(hashTableDeletedFontValue()) + , m_size(0) + , m_syntheticBold(false) + , m_syntheticOblique(false) + , m_scaledFont(0) + { } + + FontPlatformData() + : m_context(0) + , m_font(0) + , m_size(0) + , m_syntheticBold(false) + , m_syntheticOblique(false) + , m_scaledFont(0) + { } + + FontPlatformData(const FontDescription&, const AtomicString& family); + FontPlatformData(cairo_font_face_t* fontFace, float size, bool bold, bool italic); + FontPlatformData(float size, bool bold, bool italic); + FontPlatformData(const FontPlatformData&); + ~FontPlatformData(); + + static bool init(); + bool isFixedPitch(); + float size() const { return m_size; } + void setSize(float size) { m_size = size; } + bool syntheticBold() const { return m_syntheticBold; } + bool syntheticOblique() const { return m_syntheticOblique; } + + cairo_scaled_font_t* scaledFont() const { return m_scaledFont; } + + unsigned hash() const + { + uintptr_t hashCodes[1] = { reinterpret_cast<uintptr_t>(m_scaledFont) }; + return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar)); + } + + bool operator==(const FontPlatformData&) const; + FontPlatformData& operator=(const FontPlatformData&); + bool isHashTableDeletedValue() const + { + return m_font == hashTableDeletedFontValue(); + } + +#ifndef NDEBUG + String description() const; +#endif + + static PangoFontMap* m_fontMap; + static GHashTable* m_hashTable; + PangoContext* m_context; + PangoFont* m_font; + float m_size; + bool m_syntheticBold; + bool m_syntheticOblique; + cairo_scaled_font_t* m_scaledFont; +private: + static PangoFont *hashTableDeletedFontValue() { return reinterpret_cast<PangoFont*>(-1); } +}; + +} + +#endif // FontPlatformDataPango_h diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm index 54b261c..a4919d8 100644 --- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm +++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm @@ -31,21 +31,22 @@ #import "BlockExceptions.h" +#include "ANGLE/ShaderLang.h" #include "ArrayBuffer.h" #include "ArrayBufferView.h" -#include "WebGLObject.h" #include "CanvasRenderingContext.h" +#include <CoreGraphics/CGBitmapContext.h> #include "Float32Array.h" #include "GraphicsContext.h" #include "HTMLCanvasElement.h" #include "ImageBuffer.h" #include "Int32Array.h" #include "NotImplemented.h" -#include "Uint8Array.h" -#include "WebGLLayer.h" -#include <CoreGraphics/CGBitmapContext.h> #include <OpenGL/CGLRenderers.h> #include <OpenGL/gl.h> +#include "Uint8Array.h" +#include "WebGLLayer.h" +#include "WebGLObject.h" #include <wtf/UnusedParam.h> #include <wtf/text/CString.h> @@ -76,13 +77,16 @@ static void setPixelFormat(Vector<CGLPixelFormatAttribute>& attribs, int colorBi attribs.append(static_cast<CGLPixelFormatAttribute>(0)); } -PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow) +PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle) { - OwnPtr<GraphicsContext3D> context(new GraphicsContext3D(attrs, hostWindow)); + // This implementation doesn't currently support rendering directly to the HostWindow. + if (renderStyle == RenderDirectlyToHostWindow) + return 0; + OwnPtr<GraphicsContext3D> context(new GraphicsContext3D(attrs, hostWindow, false)); return context->m_contextObj ? context.release() : 0; } -GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow) +GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, bool) : m_currentWidth(0) , m_currentHeight(0) , m_attrs(attrs) @@ -229,81 +233,14 @@ GraphicsContext3D::~GraphicsContext3D() } } -void GraphicsContext3D::validateAttributes() -{ - const char* extensions = reinterpret_cast<const char*>(::glGetString(GL_EXTENSIONS)); - if (m_attrs.stencil) { - if (std::strstr(extensions, "GL_EXT_packed_depth_stencil")) { - if (!m_attrs.depth) - m_attrs.depth = true; - } else - m_attrs.stencil = false; - } - if (m_attrs.antialias) { - bool isValidVendor = true; - // Currently in Mac we only turn on antialias if vendor is NVIDIA. - const char* vendor = reinterpret_cast<const char*>(::glGetString(GL_VENDOR)); - if (!std::strstr(vendor, "NVIDIA")) - isValidVendor = false; - if (!isValidVendor || !std::strstr(extensions, "GL_EXT_framebuffer_multisample")) - m_attrs.antialias = false; - } - // FIXME: instead of enforcing premultipliedAlpha = true, implement the - // correct behavior when premultipliedAlpha = false is requested. - m_attrs.premultipliedAlpha = true; -} - void GraphicsContext3D::makeContextCurrent() { - CGLSetCurrentContext(m_contextObj); -} - -void GraphicsContext3D::paintRenderingResultsToCanvas(CanvasRenderingContext* context) -{ - HTMLCanvasElement* canvas = context->canvas(); - ImageBuffer* imageBuffer = canvas->buffer(); - - int rowBytes = m_currentWidth * 4; - int totalBytes = rowBytes * m_currentHeight; - - OwnArrayPtr<unsigned char> pixels(new unsigned char[totalBytes]); - if (!pixels) + if (!m_contextObj) return; - CGLSetCurrentContext(m_contextObj); - - bool mustRestoreFBO = false; - if (m_attrs.antialias) { - ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); - ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); - ::glBlitFramebufferEXT(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); - ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); - mustRestoreFBO = true; - } else { - if (m_boundFBO != m_fbo) { - mustRestoreFBO = true; - ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); - } - } - - GLint packAlignment = 4; - bool mustRestorePackAlignment = false; - ::glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment); - if (packAlignment > 4) { - ::glPixelStorei(GL_PACK_ALIGNMENT, 4); - mustRestorePackAlignment = true; - } - - ::glReadPixels(0, 0, m_currentWidth, m_currentHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels.get()); - - if (mustRestorePackAlignment) - ::glPixelStorei(GL_PACK_ALIGNMENT, packAlignment); - - if (mustRestoreFBO) - ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); - - paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight, - canvas->width(), canvas->height(), imageBuffer->context()->platformContext()); + CGLContextObj currentContext = CGLGetCurrentContext(); + if (currentContext != m_contextObj) + CGLSetCurrentContext(m_contextObj); } bool GraphicsContext3D::isGLES2Compliant() const @@ -320,1343 +257,7 @@ bool GraphicsContext3D::isErrorGeneratedOnOutOfBoundsAccesses() const { return false; } - -void GraphicsContext3D::reshape(int width, int height) -{ - if (width == m_currentWidth && height == m_currentHeight || !m_contextObj) - return; - - m_currentWidth = width; - m_currentHeight = height; - - CGLSetCurrentContext(m_contextObj); - - GLuint internalColorFormat, colorFormat, internalDepthStencilFormat = 0; - if (m_attrs.alpha) { - internalColorFormat = GL_RGBA8; - colorFormat = GL_RGBA; - } else { - internalColorFormat = GL_RGB8; - 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_COMPONENT; - } - - bool mustRestoreFBO = false; - - // resize multisample FBO - if (m_attrs.antialias) { - GLint maxSampleCount; - ::glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount); - GLint sampleCount = std::min(8, maxSampleCount); - if (sampleCount > maxSampleCount) - sampleCount = maxSampleCount; - if (m_boundFBO != m_multisampleFBO) { - ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); - mustRestoreFBO = true; - } - ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); - ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height); - ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); - if (m_attrs.stencil || m_attrs.depth) { - ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); - ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height); - if (m_attrs.stencil) - ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); - if (m_attrs.depth) - ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); - } - ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); - if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) { - // FIXME: cleanup. - notImplemented(); - } - } - - // resize regular FBO - if (m_boundFBO != m_fbo) { - mustRestoreFBO = true; - ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); - } - ::glBindTexture(GL_TEXTURE_2D, m_texture); - ::glTexImage2D(GL_TEXTURE_2D, 0, internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0); - ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0); - ::glBindTexture(GL_TEXTURE_2D, 0); - if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth)) { - ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer); - ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height); - 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); - } - if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) { - // FIXME: cleanup - notImplemented(); - } - - if (m_attrs.antialias) { - ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); - if (m_boundFBO == m_multisampleFBO) - mustRestoreFBO = false; - } - - // Initialize renderbuffers to 0. - GLboolean colorMask[] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}, depthMask = GL_TRUE, stencilMask = GL_TRUE; - GLboolean isScissorEnabled = GL_FALSE; - GLboolean isDitherEnabled = GL_FALSE; - GLbitfield clearMask = GL_COLOR_BUFFER_BIT; - ::glGetBooleanv(GL_COLOR_WRITEMASK, colorMask); - ::glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - if (m_attrs.depth) { - ::glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask); - ::glDepthMask(GL_TRUE); - clearMask |= GL_DEPTH_BUFFER_BIT; - } - if (m_attrs.stencil) { - ::glGetBooleanv(GL_STENCIL_WRITEMASK, &stencilMask); - ::glStencilMask(GL_TRUE); - clearMask |= GL_STENCIL_BUFFER_BIT; - } - isScissorEnabled = ::glIsEnabled(GL_SCISSOR_TEST); - ::glDisable(GL_SCISSOR_TEST); - isDitherEnabled = ::glIsEnabled(GL_DITHER); - ::glDisable(GL_DITHER); - - ::glClear(clearMask); - - ::glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]); - if (m_attrs.depth) - ::glDepthMask(depthMask); - if (m_attrs.stencil) - ::glStencilMask(stencilMask); - if (isScissorEnabled) - ::glEnable(GL_SCISSOR_TEST); - else - ::glDisable(GL_SCISSOR_TEST); - if (isDitherEnabled) - ::glEnable(GL_DITHER); - else - ::glDisable(GL_DITHER); - - if (mustRestoreFBO) - ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); - - ::glFlush(); -} - -static inline void ensureContext(CGLContextObj context) -{ - if (!context) - return; - - CGLContextObj currentContext = CGLGetCurrentContext(); - if (currentContext != context) - CGLSetCurrentContext(context); -} - -void GraphicsContext3D::prepareTexture() -{ - ensureContext(m_contextObj); - if (m_attrs.antialias) { - ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); - ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); - ::glBlitFramebufferEXT(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); - ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); - } - ::glFinish(); -} - -void GraphicsContext3D::activeTexture(unsigned long texture) -{ - ensureContext(m_contextObj); - ::glActiveTexture(texture); -} - -void GraphicsContext3D::attachShader(Platform3DObject program, Platform3DObject shader) -{ - ASSERT(program); - ASSERT(shader); - ensureContext(m_contextObj); - ::glAttachShader((GLuint) program, (GLuint) shader); -} - -void GraphicsContext3D::bindAttribLocation(Platform3DObject program, unsigned long index, const String& name) -{ - ASSERT(program); - ensureContext(m_contextObj); - ::glBindAttribLocation((GLuint) program, index, name.utf8().data()); -} - -void GraphicsContext3D::bindBuffer(unsigned long target, Platform3DObject buffer) -{ - ensureContext(m_contextObj); - ::glBindBuffer(target, (GLuint) buffer); -} - - -void GraphicsContext3D::bindFramebuffer(unsigned long target, Platform3DObject buffer) -{ - ensureContext(m_contextObj); - GLuint fbo; - if (buffer) - fbo = (GLuint)buffer; - else - fbo = (m_attrs.antialias ? m_multisampleFBO : m_fbo); - if (fbo != m_boundFBO) { - ::glBindFramebufferEXT(target, fbo); - m_boundFBO = fbo; - } -} - -void GraphicsContext3D::bindRenderbuffer(unsigned long target, Platform3DObject renderbuffer) -{ - ensureContext(m_contextObj); - ::glBindRenderbufferEXT(target, (GLuint) renderbuffer); -} - - -void GraphicsContext3D::bindTexture(unsigned long target, Platform3DObject texture) -{ - ensureContext(m_contextObj); - ::glBindTexture(target, (GLuint) texture); -} - -void GraphicsContext3D::blendColor(double red, double green, double blue, double alpha) -{ - ensureContext(m_contextObj); - ::glBlendColor(static_cast<float>(red), static_cast<float>(green), static_cast<float>(blue), static_cast<float>(alpha)); -} - -void GraphicsContext3D::blendEquation( unsigned long mode ) -{ - ensureContext(m_contextObj); - ::glBlendEquation(mode); -} - -void GraphicsContext3D::blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha) -{ - ensureContext(m_contextObj); - ::glBlendEquationSeparate(modeRGB, modeAlpha); -} - - -void GraphicsContext3D::blendFunc(unsigned long sfactor, unsigned long dfactor) -{ - ensureContext(m_contextObj); - ::glBlendFunc(sfactor, dfactor); -} - -void GraphicsContext3D::blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha) -{ - ensureContext(m_contextObj); - ::glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); -} - -void GraphicsContext3D::bufferData(unsigned long target, int size, unsigned long usage) -{ - ensureContext(m_contextObj); - ::glBufferData(target, size, 0, usage); -} - -void GraphicsContext3D::bufferData(unsigned long target, int size, const void* data, unsigned long usage) -{ - ensureContext(m_contextObj); - ::glBufferData(target, size, data, usage); -} - -void GraphicsContext3D::bufferSubData(unsigned long target, long offset, int size, const void* data) -{ - ensureContext(m_contextObj); - ::glBufferSubData(target, offset, size, data); -} - -unsigned long GraphicsContext3D::checkFramebufferStatus(unsigned long target) -{ - ensureContext(m_contextObj); - return ::glCheckFramebufferStatusEXT(target); -} - -void GraphicsContext3D::clearColor(double r, double g, double b, double a) -{ - ensureContext(m_contextObj); - ::glClearColor(static_cast<float>(r), static_cast<float>(g), static_cast<float>(b), static_cast<float>(a)); -} - -void GraphicsContext3D::clear(unsigned long mask) -{ - ensureContext(m_contextObj); - ::glClear(mask); -} - -void GraphicsContext3D::clearDepth(double depth) -{ - ensureContext(m_contextObj); - ::glClearDepth(depth); -} - -void GraphicsContext3D::clearStencil(long s) -{ - ensureContext(m_contextObj); - ::glClearStencil(s); -} - -void GraphicsContext3D::colorMask(bool red, bool green, bool blue, bool alpha) -{ - ensureContext(m_contextObj); - ::glColorMask(red, green, blue, alpha); -} - -void GraphicsContext3D::compileShader(Platform3DObject shader) -{ - ASSERT(shader); - ensureContext(m_contextObj); - - int GLshaderType; - ANGLEShaderType shaderType; - - glGetShaderiv(shader, SHADER_TYPE, &GLshaderType); - - if (GLshaderType == VERTEX_SHADER) - shaderType = SHADER_TYPE_VERTEX; - else if (GLshaderType == FRAGMENT_SHADER) - shaderType = SHADER_TYPE_FRAGMENT; - else - return; // Invalid shader type. - - HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader); - - if (result == m_shaderSourceMap.end()) - return; - - ShaderSourceEntry& entry = result->second; - - String translatedShaderSource; - String shaderInfoLog; - - bool isValid = m_compiler.validateShaderSource(entry.source.utf8().data(), shaderType, translatedShaderSource, shaderInfoLog); - - entry.log = shaderInfoLog; - entry.isValid = isValid; - - if (!isValid) - return; // Shader didn't validate, don't move forward with compiling translated source - - int translatedShaderLength = translatedShaderSource.length(); - - const CString& translatedShaderCString = translatedShaderSource.utf8(); - const char* translatedShaderPtr = translatedShaderCString.data(); - - ::glShaderSource((GLuint) shader, 1, &translatedShaderPtr, &translatedShaderLength); - - ::glCompileShader((GLuint) shader); - - int GLCompileSuccess; - - ::glGetShaderiv((GLuint) shader, COMPILE_STATUS, &GLCompileSuccess); - - // ASSERT that ANGLE generated GLSL will be accepted by OpenGL - ASSERT(GLCompileSuccess == GL_TRUE); -} - -void GraphicsContext3D::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border) -{ - ensureContext(m_contextObj); - if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) { - ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); - ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); - ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); - ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); - } - ::glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); - if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) - ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); -} - -void GraphicsContext3D::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height) -{ - ensureContext(m_contextObj); - if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) { - ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); - ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); - ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); - ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); - } - ::glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); - if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) - ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); -} - -void GraphicsContext3D::cullFace(unsigned long mode) -{ - ensureContext(m_contextObj); - ::glCullFace(mode); -} - -void GraphicsContext3D::depthFunc(unsigned long func) -{ - ensureContext(m_contextObj); - ::glDepthFunc(func); -} - -void GraphicsContext3D::depthMask(bool flag) -{ - ensureContext(m_contextObj); - ::glDepthMask(flag); -} - -void GraphicsContext3D::depthRange(double zNear, double zFar) -{ - ensureContext(m_contextObj); - ::glDepthRange(zNear, zFar); -} - -void GraphicsContext3D::detachShader(Platform3DObject program, Platform3DObject shader) -{ - ASSERT(program); - ASSERT(shader); - ensureContext(m_contextObj); - ::glDetachShader((GLuint) program, (GLuint) shader); -} - -void GraphicsContext3D::disable(unsigned long cap) -{ - ensureContext(m_contextObj); - ::glDisable(cap); -} - -void GraphicsContext3D::disableVertexAttribArray(unsigned long index) -{ - ensureContext(m_contextObj); - ::glDisableVertexAttribArray(index); -} - -void GraphicsContext3D::drawArrays(unsigned long mode, long first, long count) -{ - ensureContext(m_contextObj); - ::glDrawArrays(mode, first, count); -} - -void GraphicsContext3D::drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset) -{ - ensureContext(m_contextObj); - ::glDrawElements(mode, count, type, reinterpret_cast<void*>(static_cast<intptr_t>(offset))); -} - -void GraphicsContext3D::enable(unsigned long cap) -{ - ensureContext(m_contextObj); - ::glEnable(cap); -} - -void GraphicsContext3D::enableVertexAttribArray(unsigned long index) -{ - ensureContext(m_contextObj); - ::glEnableVertexAttribArray(index); -} - -void GraphicsContext3D::finish() -{ - ensureContext(m_contextObj); - ::glFinish(); -} - -void GraphicsContext3D::flush() -{ - ensureContext(m_contextObj); - ::glFlush(); -} - -void GraphicsContext3D::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, Platform3DObject buffer) -{ - ensureContext(m_contextObj); - GLuint renderbuffer = (GLuint) buffer; - if (attachment == DEPTH_STENCIL_ATTACHMENT) { - ::glFramebufferRenderbufferEXT(target, DEPTH_ATTACHMENT, renderbuffertarget, renderbuffer); - ::glFramebufferRenderbufferEXT(target, STENCIL_ATTACHMENT, renderbuffertarget, renderbuffer); - } else - ::glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer); -} - -void GraphicsContext3D::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, Platform3DObject texture, long level) -{ - ensureContext(m_contextObj); - ::glFramebufferTexture2DEXT(target, attachment, textarget, (GLuint) texture, level); -} - -void GraphicsContext3D::frontFace(unsigned long mode) -{ - ensureContext(m_contextObj); - ::glFrontFace(mode); -} - -void GraphicsContext3D::generateMipmap(unsigned long target) -{ - ensureContext(m_contextObj); - ::glGenerateMipmapEXT(target); -} - -bool GraphicsContext3D::getActiveAttrib(Platform3DObject program, unsigned long index, ActiveInfo& info) -{ - if (!program) { - synthesizeGLError(INVALID_VALUE); - return false; - } - ensureContext(m_contextObj); - GLint maxAttributeSize = 0; - ::glGetProgramiv(static_cast<GLuint>(program), GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttributeSize); - GLchar name[maxAttributeSize]; // GL_ACTIVE_ATTRIBUTE_MAX_LENGTH includes null termination - GLsizei nameLength = 0; - GLint size = 0; - GLenum type = 0; - ::glGetActiveAttrib(static_cast<GLuint>(program), index, maxAttributeSize, &nameLength, &size, &type, name); - if (!nameLength) - return false; - info.name = String(name, nameLength); - info.type = type; - info.size = size; - return true; -} - -bool GraphicsContext3D::getActiveUniform(Platform3DObject program, unsigned long index, ActiveInfo& info) -{ - if (!program) { - synthesizeGLError(INVALID_VALUE); - return false; - } - ensureContext(m_contextObj); - GLint maxUniformSize = 0; - ::glGetProgramiv(static_cast<GLuint>(program), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformSize); - GLchar name[maxUniformSize]; // GL_ACTIVE_UNIFORM_MAX_LENGTH includes null termination - GLsizei nameLength = 0; - GLint size = 0; - GLenum type = 0; - ::glGetActiveUniform(static_cast<GLuint>(program), index, maxUniformSize, &nameLength, &size, &type, name); - if (!nameLength) - return false; - info.name = String(name, nameLength); - info.type = type; - info.size = size; - return true; -} - -void GraphicsContext3D::getAttachedShaders(Platform3DObject program, int maxCount, int* count, unsigned int* shaders) -{ - if (!program) { - synthesizeGLError(INVALID_VALUE); - return; - } - ensureContext(m_contextObj); - ::glGetAttachedShaders(static_cast<GLuint>(program), maxCount, count, shaders); -} - -int GraphicsContext3D::getAttribLocation(Platform3DObject program, const String& name) -{ - if (!program) - return -1; - - ensureContext(m_contextObj); - return ::glGetAttribLocation((GLuint) program, name.utf8().data()); -} - -GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes() -{ - return m_attrs; -} - -unsigned long GraphicsContext3D::getError() -{ - if (m_syntheticErrors.size() > 0) { - ListHashSet<unsigned long>::iterator iter = m_syntheticErrors.begin(); - unsigned long err = *iter; - m_syntheticErrors.remove(iter); - return err; - } - - ensureContext(m_contextObj); - return ::glGetError(); -} - -String GraphicsContext3D::getString(unsigned long name) -{ - ensureContext(m_contextObj); - return String((const char*) ::glGetString(name)); -} - -void GraphicsContext3D::hint(unsigned long target, unsigned long mode) -{ - ensureContext(m_contextObj); - ::glHint(target, mode); -} - -bool GraphicsContext3D::isBuffer(Platform3DObject buffer) -{ - if (!buffer) - return false; - - ensureContext(m_contextObj); - return ::glIsBuffer((GLuint) buffer); -} - -bool GraphicsContext3D::isEnabled(unsigned long cap) -{ - ensureContext(m_contextObj); - return ::glIsEnabled(cap); -} - -bool GraphicsContext3D::isFramebuffer(Platform3DObject framebuffer) -{ - if (!framebuffer) - return false; - - ensureContext(m_contextObj); - return ::glIsFramebufferEXT((GLuint) framebuffer); -} - -bool GraphicsContext3D::isProgram(Platform3DObject program) -{ - if (!program) - return false; - - ensureContext(m_contextObj); - return ::glIsProgram((GLuint) program); -} - -bool GraphicsContext3D::isRenderbuffer(Platform3DObject renderbuffer) -{ - if (!renderbuffer) - return false; - - ensureContext(m_contextObj); - return ::glIsRenderbufferEXT((GLuint) renderbuffer); -} - -bool GraphicsContext3D::isShader(Platform3DObject shader) -{ - if (!shader) - return false; - - ensureContext(m_contextObj); - return ::glIsShader((GLuint) shader); -} - -bool GraphicsContext3D::isTexture(Platform3DObject texture) -{ - if (!texture) - return false; - - ensureContext(m_contextObj); - return ::glIsTexture((GLuint) texture); -} - -void GraphicsContext3D::lineWidth(double width) -{ - ensureContext(m_contextObj); - ::glLineWidth(static_cast<float>(width)); -} - -void GraphicsContext3D::linkProgram(Platform3DObject program) -{ - ASSERT(program); - ensureContext(m_contextObj); - ::glLinkProgram((GLuint) program); -} - -void GraphicsContext3D::pixelStorei(unsigned long pname, long param) -{ - ensureContext(m_contextObj); - ::glPixelStorei(pname, param); -} - -void GraphicsContext3D::polygonOffset(double factor, double units) -{ - ensureContext(m_contextObj); - ::glPolygonOffset(static_cast<float>(factor), static_cast<float>(units)); -} - -void GraphicsContext3D::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* data) -{ - // FIXME: remove the two glFlush calls when the driver bug is fixed, i.e., - // all previous rendering calls should be done before reading pixels. - ensureContext(m_contextObj); - ::glFlush(); - if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) { - ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); - ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); - ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); - ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); - ::glFlush(); - } - ::glReadPixels(x, y, width, height, format, type, data); - if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) - ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); -} - -void GraphicsContext3D::releaseShaderCompiler() -{ - // FIXME: This is not implemented on desktop OpenGL. We need to have ifdefs for the different GL variants - ensureContext(m_contextObj); - //::glReleaseShaderCompiler(); -} - -void GraphicsContext3D::renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height) -{ - ensureContext(m_contextObj); - switch (internalformat) { - case DEPTH_STENCIL: - internalformat = GL_DEPTH24_STENCIL8_EXT; - break; - case DEPTH_COMPONENT16: - internalformat = GL_DEPTH_COMPONENT; - break; - case RGBA4: - case RGB5_A1: - internalformat = GL_RGBA; - break; - case RGB565: - internalformat = GL_RGB; - break; - } - ::glRenderbufferStorageEXT(target, internalformat, width, height); -} - -void GraphicsContext3D::sampleCoverage(double value, bool invert) -{ - ensureContext(m_contextObj); - ::glSampleCoverage(static_cast<float>(value), invert); -} - -void GraphicsContext3D::scissor(long x, long y, unsigned long width, unsigned long height) -{ - ensureContext(m_contextObj); - ::glScissor(x, y, width, height); -} - -void GraphicsContext3D::shaderSource(Platform3DObject shader, const String& string) -{ - ASSERT(shader); - - ensureContext(m_contextObj); - - ShaderSourceEntry entry; - - entry.source = string; - - m_shaderSourceMap.set(shader, entry); -} - -void GraphicsContext3D::stencilFunc(unsigned long func, long ref, unsigned long mask) -{ - ensureContext(m_contextObj); - ::glStencilFunc(func, ref, mask); -} - -void GraphicsContext3D::stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask) -{ - ensureContext(m_contextObj); - ::glStencilFuncSeparate(face, func, ref, mask); -} - -void GraphicsContext3D::stencilMask(unsigned long mask) -{ - ensureContext(m_contextObj); - ::glStencilMask(mask); -} - -void GraphicsContext3D::stencilMaskSeparate(unsigned long face, unsigned long mask) -{ - ensureContext(m_contextObj); - ::glStencilMaskSeparate(face, mask); -} - -void GraphicsContext3D::stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass) -{ - ensureContext(m_contextObj); - ::glStencilOp(fail, zfail, zpass); -} - -void GraphicsContext3D::stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass) -{ - ensureContext(m_contextObj); - ::glStencilOpSeparate(face, fail, zfail, zpass); -} - -void GraphicsContext3D::texParameterf(unsigned target, unsigned pname, float value) -{ - ensureContext(m_contextObj); - ::glTexParameterf(target, pname, static_cast<float>(value)); -} - -void GraphicsContext3D::texParameteri(unsigned target, unsigned pname, int value) -{ - ensureContext(m_contextObj); - ::glTexParameteri(target, pname, static_cast<float>(value)); -} - -void GraphicsContext3D::uniform1f(long location, float v0) -{ - ensureContext(m_contextObj); - ::glUniform1f(location, v0); -} - -void GraphicsContext3D::uniform1fv(long location, float* array, int size) -{ - ensureContext(m_contextObj); - ::glUniform1fv(location, size, array); -} - -void GraphicsContext3D::uniform2f(long location, float v0, float v1) -{ - ensureContext(m_contextObj); - ::glUniform2f(location, v0, v1); -} - -void GraphicsContext3D::uniform2fv(long location, float* array, int size) -{ - // FIXME: length needs to be a multiple of 2 - ensureContext(m_contextObj); - ::glUniform2fv(location, size, array); -} - -void GraphicsContext3D::uniform3f(long location, float v0, float v1, float v2) -{ - ensureContext(m_contextObj); - ::glUniform3f(location, v0, v1, v2); -} - -void GraphicsContext3D::uniform3fv(long location, float* array, int size) -{ - // FIXME: length needs to be a multiple of 3 - ensureContext(m_contextObj); - ::glUniform3fv(location, size, array); -} - -void GraphicsContext3D::uniform4f(long location, float v0, float v1, float v2, float v3) -{ - ensureContext(m_contextObj); - ::glUniform4f(location, v0, v1, v2, v3); -} - -void GraphicsContext3D::uniform4fv(long location, float* array, int size) -{ - // FIXME: length needs to be a multiple of 4 - ensureContext(m_contextObj); - ::glUniform4fv(location, size, array); -} - -void GraphicsContext3D::uniform1i(long location, int v0) -{ - ensureContext(m_contextObj); - ::glUniform1i(location, v0); -} - -void GraphicsContext3D::uniform1iv(long location, int* array, int size) -{ - ensureContext(m_contextObj); - ::glUniform1iv(location, size, array); -} - -void GraphicsContext3D::uniform2i(long location, int v0, int v1) -{ - ensureContext(m_contextObj); - ::glUniform2i(location, v0, v1); -} - -void GraphicsContext3D::uniform2iv(long location, int* array, int size) -{ - // FIXME: length needs to be a multiple of 2 - ensureContext(m_contextObj); - ::glUniform2iv(location, size, array); -} - -void GraphicsContext3D::uniform3i(long location, int v0, int v1, int v2) -{ - ensureContext(m_contextObj); - ::glUniform3i(location, v0, v1, v2); -} - -void GraphicsContext3D::uniform3iv(long location, int* array, int size) -{ - // FIXME: length needs to be a multiple of 3 - ensureContext(m_contextObj); - ::glUniform3iv(location, size, array); -} - -void GraphicsContext3D::uniform4i(long location, int v0, int v1, int v2, int v3) -{ - ensureContext(m_contextObj); - ::glUniform4i(location, v0, v1, v2, v3); -} - -void GraphicsContext3D::uniform4iv(long location, int* array, int size) -{ - // FIXME: length needs to be a multiple of 4 - ensureContext(m_contextObj); - ::glUniform4iv(location, size, array); -} - -void GraphicsContext3D::uniformMatrix2fv(long location, bool transpose, float* array, int size) -{ - // FIXME: length needs to be a multiple of 4 - ensureContext(m_contextObj); - ::glUniformMatrix2fv(location, size, transpose, array); -} - -void GraphicsContext3D::uniformMatrix3fv(long location, bool transpose, float* array, int size) -{ - // FIXME: length needs to be a multiple of 9 - ensureContext(m_contextObj); - ::glUniformMatrix3fv(location, size, transpose, array); -} - -void GraphicsContext3D::uniformMatrix4fv(long location, bool transpose, float* array, int size) -{ - // FIXME: length needs to be a multiple of 16 - ensureContext(m_contextObj); - ::glUniformMatrix4fv(location, size, transpose, array); -} - -void GraphicsContext3D::useProgram(Platform3DObject program) -{ - ensureContext(m_contextObj); - ::glUseProgram((GLuint) program); -} - -void GraphicsContext3D::validateProgram(Platform3DObject program) -{ - ASSERT(program); - ensureContext(m_contextObj); - ::glValidateProgram((GLuint) program); -} - -void GraphicsContext3D::vertexAttrib1f(unsigned long indx, float v0) -{ - ensureContext(m_contextObj); - ::glVertexAttrib1f(indx, v0); -} - -void GraphicsContext3D::vertexAttrib1fv(unsigned long indx, float* array) -{ - ensureContext(m_contextObj); - ::glVertexAttrib1fv(indx, array); -} - -void GraphicsContext3D::vertexAttrib2f(unsigned long indx, float v0, float v1) -{ - ensureContext(m_contextObj); - ::glVertexAttrib2f(indx, v0, v1); -} - -void GraphicsContext3D::vertexAttrib2fv(unsigned long indx, float* array) -{ - ensureContext(m_contextObj); - ::glVertexAttrib2fv(indx, array); -} - -void GraphicsContext3D::vertexAttrib3f(unsigned long indx, float v0, float v1, float v2) -{ - ensureContext(m_contextObj); - ::glVertexAttrib3f(indx, v0, v1, v2); -} - -void GraphicsContext3D::vertexAttrib3fv(unsigned long indx, float* array) -{ - ensureContext(m_contextObj); - ::glVertexAttrib3fv(indx, array); -} - -void GraphicsContext3D::vertexAttrib4f(unsigned long indx, float v0, float v1, float v2, float v3) -{ - ensureContext(m_contextObj); - ::glVertexAttrib4f(indx, v0, v1, v2, v3); -} - -void GraphicsContext3D::vertexAttrib4fv(unsigned long indx, float* array) -{ - ensureContext(m_contextObj); - ::glVertexAttrib4fv(indx, array); -} - -void GraphicsContext3D::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, unsigned long stride, unsigned long offset) -{ - ensureContext(m_contextObj); - ::glVertexAttribPointer(indx, size, type, normalized, stride, reinterpret_cast<void*>(static_cast<intptr_t>(offset))); -} - -void GraphicsContext3D::viewport(long x, long y, unsigned long width, unsigned long height) -{ - ensureContext(m_contextObj); - ::glViewport(static_cast<GLint>(x), static_cast<GLint>(y), static_cast<GLsizei>(width), static_cast<GLsizei>(height)); -} - -void GraphicsContext3D::getBooleanv(unsigned long pname, unsigned char* value) -{ - ensureContext(m_contextObj); - ::glGetBooleanv(pname, value); -} - -void GraphicsContext3D::getBufferParameteriv(unsigned long target, unsigned long pname, int* value) -{ - ensureContext(m_contextObj); - ::glGetBufferParameteriv(target, pname, value); -} - -void GraphicsContext3D::getFloatv(unsigned long pname, float* value) -{ - ensureContext(m_contextObj); - ::glGetFloatv(pname, value); -} - -void GraphicsContext3D::getFramebufferAttachmentParameteriv(unsigned long target, unsigned long attachment, unsigned long pname, int* value) -{ - ensureContext(m_contextObj); - if (attachment == DEPTH_STENCIL_ATTACHMENT) - attachment = DEPTH_ATTACHMENT; // Or STENCIL_ATTACHMENT, either works. - ::glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value); -} - -void GraphicsContext3D::getIntegerv(unsigned long pname, int* value) -{ - // Need to emulate IMPLEMENTATION_COLOR_READ_FORMAT/TYPE for GL. Any valid - // combination should work, but GL_RGB/GL_UNSIGNED_BYTE might be the most - // useful for desktop WebGL users. - // Need to emulate MAX_FRAGMENT/VERTEX_UNIFORM_VECTORS and MAX_VARYING_VECTORS - // because desktop GL's corresponding queries return the number of components - // whereas GLES2 return the number of vectors (each vector has 4 components). - // Therefore, the value returned by desktop GL needs to be divided by 4. - ensureContext(m_contextObj); - switch (pname) { - case IMPLEMENTATION_COLOR_READ_FORMAT: - *value = GL_RGB; - break; - case IMPLEMENTATION_COLOR_READ_TYPE: - *value = GL_UNSIGNED_BYTE; - break; - case MAX_FRAGMENT_UNIFORM_VECTORS: - ::glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, value); - *value /= 4; - break; - case MAX_VERTEX_UNIFORM_VECTORS: - ::glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, value); - *value /= 4; - break; - case MAX_VARYING_VECTORS: - ::glGetIntegerv(GL_MAX_VARYING_FLOATS, value); - *value /= 4; - break; - default: - ::glGetIntegerv(pname, value); - } -} - -void GraphicsContext3D::getProgramiv(Platform3DObject program, unsigned long pname, int* value) -{ - ensureContext(m_contextObj); - ::glGetProgramiv((GLuint) program, pname, value); -} - -String GraphicsContext3D::getProgramInfoLog(Platform3DObject program) -{ - ASSERT(program); - - ensureContext(m_contextObj); - GLint length; - ::glGetProgramiv((GLuint) program, GL_INFO_LOG_LENGTH, &length); - - GLsizei size; - GLchar* info = (GLchar*) fastMalloc(length); - if (!info) - return ""; - - ::glGetProgramInfoLog((GLuint) program, length, &size, info); - String s(info); - fastFree(info); - return s; -} - -void GraphicsContext3D::getRenderbufferParameteriv(unsigned long target, unsigned long pname, int* value) -{ - ensureContext(m_contextObj); - ::glGetRenderbufferParameterivEXT(target, pname, value); -} - -void GraphicsContext3D::getShaderiv(Platform3DObject shader, unsigned long pname, int* value) -{ - ASSERT(shader); - - ensureContext(m_contextObj); - - HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader); - - switch (pname) { - case DELETE_STATUS: - case SHADER_TYPE: - // Let OpenGL handle these. - - ::glGetShaderiv((GLuint) shader, pname, value); - break; - - case COMPILE_STATUS: - if (result == m_shaderSourceMap.end()) { - (*value) = static_cast<int>(false); - return; - } - - (*value) = static_cast<int>(result->second.isValid); - break; - - case INFO_LOG_LENGTH: - if (result == m_shaderSourceMap.end()) { - (*value) = 0; - return; - } - - (*value) = getShaderInfoLog(shader).length(); - break; - - case SHADER_SOURCE_LENGTH: - (*value) = getShaderSource(shader).length(); - break; - - default: - synthesizeGLError(INVALID_ENUM); - } -} - -String GraphicsContext3D::getShaderInfoLog(Platform3DObject shader) -{ - ASSERT(shader); - - ensureContext(m_contextObj); - GLint length; - ::glGetShaderiv((GLuint) shader, GL_INFO_LOG_LENGTH, &length); - - HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader); - - if (result == m_shaderSourceMap.end()) - return ""; - - ShaderSourceEntry entry = result->second; - - if (entry.isValid) { - GLint length; - ::glGetShaderiv((GLuint) shader, GL_INFO_LOG_LENGTH, &length); - - GLsizei size; - GLchar* info = (GLchar*) fastMalloc(length); - if (!info) - return ""; - - ::glGetShaderInfoLog((GLuint) shader, length, &size, info); - - String s(info); - fastFree(info); - return s; - } - else { - return entry.log; - } -} - -String GraphicsContext3D::getShaderSource(Platform3DObject shader) -{ - ASSERT(shader); - - ensureContext(m_contextObj); - - HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader); - - if (result == m_shaderSourceMap.end()) - return ""; - - return result->second.source; -} - - -void GraphicsContext3D::getTexParameterfv(unsigned long target, unsigned long pname, float* value) -{ - ensureContext(m_contextObj); - ::glGetTexParameterfv(target, pname, value); -} - -void GraphicsContext3D::getTexParameteriv(unsigned long target, unsigned long pname, int* value) -{ - ensureContext(m_contextObj); - ::glGetTexParameteriv(target, pname, value); -} - -void GraphicsContext3D::getUniformfv(Platform3DObject program, long location, float* value) -{ - ensureContext(m_contextObj); - ::glGetUniformfv((GLuint) program, location, value); -} - -void GraphicsContext3D::getUniformiv(Platform3DObject program, long location, int* value) -{ - ensureContext(m_contextObj); - ::glGetUniformiv((GLuint) program, location, value); -} - -long GraphicsContext3D::getUniformLocation(Platform3DObject program, const String& name) -{ - ASSERT(program); - - ensureContext(m_contextObj); - return ::glGetUniformLocation((GLuint) program, name.utf8().data()); -} - -void GraphicsContext3D::getVertexAttribfv(unsigned long index, unsigned long pname, float* value) -{ - ensureContext(m_contextObj); - ::glGetVertexAttribfv(index, pname, value); -} - -void GraphicsContext3D::getVertexAttribiv(unsigned long index, unsigned long pname, int* value) -{ - ensureContext(m_contextObj); - ::glGetVertexAttribiv(index, pname, value); -} - -long GraphicsContext3D::getVertexAttribOffset(unsigned long index, unsigned long pname) -{ - ensureContext(m_contextObj); - - void* pointer; - ::glGetVertexAttribPointerv(index, pname, &pointer); - return reinterpret_cast<long>(pointer); -} - -int GraphicsContext3D::texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, void* pixels) -{ - ensureContext(m_contextObj); - - ::glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); - return 0; -} - -int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, unsigned width, unsigned height, unsigned format, unsigned type, void* pixels) -{ - ensureContext(m_contextObj); - - // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size - ::glTexSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels); - return 0; -} - -unsigned GraphicsContext3D::createBuffer() -{ - ensureContext(m_contextObj); - GLuint o; - glGenBuffers(1, &o); - return o; -} - -unsigned GraphicsContext3D::createFramebuffer() -{ - ensureContext(m_contextObj); - GLuint o; - glGenFramebuffersEXT(1, &o); - return o; -} - -unsigned GraphicsContext3D::createProgram() -{ - ensureContext(m_contextObj); - return glCreateProgram(); -} - -unsigned GraphicsContext3D::createRenderbuffer() -{ - ensureContext(m_contextObj); - GLuint o; - glGenRenderbuffersEXT(1, &o); - return o; -} - -unsigned GraphicsContext3D::createShader(unsigned long type) -{ - ensureContext(m_contextObj); - return glCreateShader((type == FRAGMENT_SHADER) ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER); -} - -unsigned GraphicsContext3D::createTexture() -{ - ensureContext(m_contextObj); - GLuint o; - glGenTextures(1, &o); - return o; -} - -void GraphicsContext3D::deleteBuffer(unsigned buffer) -{ - ensureContext(m_contextObj); - glDeleteBuffers(1, &buffer); -} - -void GraphicsContext3D::deleteFramebuffer(unsigned framebuffer) -{ - ensureContext(m_contextObj); - glDeleteFramebuffersEXT(1, &framebuffer); -} - -void GraphicsContext3D::deleteProgram(unsigned program) -{ - ensureContext(m_contextObj); - glDeleteProgram(program); -} - -void GraphicsContext3D::deleteRenderbuffer(unsigned renderbuffer) -{ - ensureContext(m_contextObj); - glDeleteRenderbuffersEXT(1, &renderbuffer); -} - -void GraphicsContext3D::deleteShader(unsigned shader) -{ - ensureContext(m_contextObj); - glDeleteShader(shader); -} - -void GraphicsContext3D::deleteTexture(unsigned texture) -{ - ensureContext(m_contextObj); - glDeleteTextures(1, &texture); -} - -int GraphicsContext3D::sizeInBytes(int type) -{ - switch (type) { - case GL_BYTE: - return sizeof(GLbyte); - case GL_UNSIGNED_BYTE: - return sizeof(GLubyte); - case GL_SHORT: - return sizeof(GLshort); - case GL_UNSIGNED_SHORT: - return sizeof(GLushort); - case GL_INT: - return sizeof(GLint); - case GL_UNSIGNED_INT: - return sizeof(GLuint); - case GL_FLOAT: - return sizeof(GLfloat); - default: - return 0; - } -} - -void GraphicsContext3D::synthesizeGLError(unsigned long error) -{ - m_syntheticErrors.add(error); -} } diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.h b/WebCore/platform/graphics/mac/GraphicsLayerCA.h index a9f747a..6ff3ff0 100644 --- a/WebCore/platform/graphics/mac/GraphicsLayerCA.h +++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.h @@ -112,8 +112,6 @@ public: virtual void setDebugBackgroundColor(const Color&); virtual void setDebugBorder(const Color&, float borderWidth); - virtual void setGeometryOrientation(CompositingCoordinatesOrientation); - virtual void didDisplay(PlatformLayer*); void recursiveCommitChanges(); @@ -259,7 +257,6 @@ private: void updateContentsMediaLayer(); void updateContentsCanvasLayer(); void updateContentsRect(); - void updateGeometryOrientation(); void updateMaskLayer(); void updateReplicatedLayers(); @@ -304,10 +301,9 @@ private: ContentsMediaLayerChanged = 1 << 18, ContentsCanvasLayerChanged = 1 << 19, ContentsRectChanged = 1 << 20, - GeometryOrientationChanged = 1 << 21, - MaskLayerChanged = 1 << 22, - ReplicatedLayerChanged = 1 << 23, - ContentsNeedsDisplay = 1 << 24 + MaskLayerChanged = 1 << 21, + ReplicatedLayerChanged = 1 << 22, + ContentsNeedsDisplay = 1 << 23 }; typedef unsigned LayerChangeFlags; void noteLayerPropertyChanged(LayerChangeFlags flags); diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm index 5fedaff..395a691 100644 --- a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm +++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm @@ -263,15 +263,6 @@ static String animationIdentifier(AnimatedPropertyID property, const String& key return builder.toString(); } -#if !HAVE_MODERN_QUARTZCORE -static TransformationMatrix flipTransform() -{ - TransformationMatrix flipper; - flipper.flipY(); - return flipper; -} -#endif - static CAMediaTimingFunction* getCAMediaTimingFunction(const TimingFunction* timingFunction) { // By this point, timing functions can only be linear or cubic, not steps. @@ -332,11 +323,6 @@ static bool forceSoftwareAnimation() return forceSoftwareAnimation; } -GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayer::compositingCoordinatesOrientation() -{ - return CompositingCoordinatesBottomUp; -} - static NSDictionary* nullActionsDictionary() { NSNull* nullValue = [NSNull null]; @@ -831,28 +817,6 @@ void GraphicsLayerCA::setContentsToMedia(PlatformLayer* mediaLayer) noteLayerPropertyChanged(ContentsMediaLayerChanged); } -void GraphicsLayerCA::setGeometryOrientation(CompositingCoordinatesOrientation orientation) -{ - if (orientation == m_geometryOrientation) - return; - - GraphicsLayer::setGeometryOrientation(orientation); - noteLayerPropertyChanged(GeometryOrientationChanged); - -#if !HAVE_MODERN_QUARTZCORE - // Geometry orientation is mapped onto children transform in older QuartzCores. - switch (m_geometryOrientation) { - case CompositingCoordinatesTopDown: - setChildrenTransform(TransformationMatrix()); - break; - - case CompositingCoordinatesBottomUp: - setChildrenTransform(flipTransform()); - break; - } -#endif -} - void GraphicsLayerCA::didDisplay(PlatformLayer* layer) { CALayer* sourceLayer; @@ -984,9 +948,6 @@ void GraphicsLayerCA::commitLayerChangesBeforeSublayers() if (m_uncommittedChanges & ContentsRectChanged) updateContentsRect(); - if (m_uncommittedChanges & GeometryOrientationChanged) - updateGeometryOrientation(); - if (m_uncommittedChanges & MaskLayerChanged) updateMaskLayer(); @@ -1461,23 +1422,6 @@ void GraphicsLayerCA::updateContentsRect() } } -void GraphicsLayerCA::updateGeometryOrientation() -{ -#if HAVE_MODERN_QUARTZCORE - switch (geometryOrientation()) { - case CompositingCoordinatesTopDown: - [m_layer.get() setGeometryFlipped:NO]; - break; - - case CompositingCoordinatesBottomUp: - [m_layer.get() setGeometryFlipped:YES]; - break; - } - // Geometry orientation is mapped onto children transform in older QuartzCores, - // so is handled via setGeometryOrientation(). -#endif -} - void GraphicsLayerCA::updateMaskLayer() { CALayer *maskCALayer = m_maskLayer ? m_maskLayer->platformLayer() : 0; @@ -2226,11 +2170,7 @@ void GraphicsLayerCA::swapFromOrToTiledLayer(bool useTiledLayer) [tiledLayer setTileSize:tileSize]; [tiledLayer setLevelsOfDetail:1]; [tiledLayer setLevelsOfDetailBias:0]; - - if (GraphicsLayer::compositingCoordinatesOrientation() == GraphicsLayer::CompositingCoordinatesBottomUp) - [tiledLayer setContentsGravity:@"bottomLeft"]; - else - [tiledLayer setContentsGravity:@"topLeft"]; + [tiledLayer setContentsGravity:@"bottomLeft"]; #if !HAVE_MODERN_QUARTZCORE // Tiled layer has issues with flipped coordinates. diff --git a/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp b/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp new file mode 100644 index 0000000..53d9b86 --- /dev/null +++ b/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp @@ -0,0 +1,1454 @@ +/* + * Copyright (C) 2010 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 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" + +#if ENABLE(3D_CANVAS) + +#include "GraphicsContext3D.h" + +#include "ArrayBuffer.h" +#include "ArrayBufferView.h" +#include "WebGLObject.h" +#include "CanvasRenderingContext.h" +#include "Float32Array.h" +#include "GraphicsContext.h" +#include "HTMLCanvasElement.h" +#include "ImageBuffer.h" +#include "Int32Array.h" +#include "NotImplemented.h" +#include "Uint8Array.h" + +#if PLATFORM(MAC) +#include <OpenGL/gl.h> +#endif + +#include <wtf/UnusedParam.h> +#include <wtf/text/CString.h> + +namespace WebCore { + +void GraphicsContext3D::validateAttributes() +{ + const char* extensions = reinterpret_cast<const char*>(::glGetString(GL_EXTENSIONS)); + if (m_attrs.stencil) { + if (std::strstr(extensions, "GL_EXT_packed_depth_stencil")) { + if (!m_attrs.depth) + m_attrs.depth = true; + } else + m_attrs.stencil = false; + } + if (m_attrs.antialias) { + bool isValidVendor = true; + // Currently in Mac we only turn on antialias if vendor is NVIDIA. + const char* vendor = reinterpret_cast<const char*>(::glGetString(GL_VENDOR)); + if (!std::strstr(vendor, "NVIDIA")) + isValidVendor = false; + if (!isValidVendor || !std::strstr(extensions, "GL_EXT_framebuffer_multisample")) + m_attrs.antialias = false; + } + // FIXME: instead of enforcing premultipliedAlpha = true, implement the + // correct behavior when premultipliedAlpha = false is requested. + m_attrs.premultipliedAlpha = true; +} + +void GraphicsContext3D::paintRenderingResultsToCanvas(CanvasRenderingContext* context) +{ + HTMLCanvasElement* canvas = context->canvas(); + ImageBuffer* imageBuffer = canvas->buffer(); + + int rowBytes = m_currentWidth * 4; + int totalBytes = rowBytes * m_currentHeight; + + OwnArrayPtr<unsigned char> pixels(new unsigned char[totalBytes]); + if (!pixels) + return; + + makeContextCurrent(); + + bool mustRestoreFBO = false; + if (m_attrs.antialias) { + ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); + ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); + ::glBlitFramebufferEXT(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + mustRestoreFBO = true; + } else { + if (m_boundFBO != m_fbo) { + mustRestoreFBO = true; + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + } + } + + GLint packAlignment = 4; + bool mustRestorePackAlignment = false; + ::glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment); + if (packAlignment > 4) { + ::glPixelStorei(GL_PACK_ALIGNMENT, 4); + mustRestorePackAlignment = true; + } + + ::glReadPixels(0, 0, m_currentWidth, m_currentHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels.get()); + + if (mustRestorePackAlignment) + ::glPixelStorei(GL_PACK_ALIGNMENT, packAlignment); + + if (mustRestoreFBO) + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); + + paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight, + canvas->width(), canvas->height(), imageBuffer->context()->platformContext()); +} + +void GraphicsContext3D::reshape(int width, int height) +{ + if (width == m_currentWidth && height == m_currentHeight || !m_contextObj) + return; + + m_currentWidth = width; + m_currentHeight = height; + + makeContextCurrent(); + + GLuint internalColorFormat, colorFormat, internalDepthStencilFormat = 0; + if (m_attrs.alpha) { + internalColorFormat = GL_RGBA8; + colorFormat = GL_RGBA; + } else { + internalColorFormat = GL_RGB8; + 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_COMPONENT; + } + + bool mustRestoreFBO = false; + + // resize multisample FBO + if (m_attrs.antialias) { + GLint maxSampleCount; + ::glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount); + GLint sampleCount = std::min(8, maxSampleCount); + if (sampleCount > maxSampleCount) + sampleCount = maxSampleCount; + if (m_boundFBO != m_multisampleFBO) { + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); + mustRestoreFBO = true; + } + ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); + ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height); + ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); + if (m_attrs.stencil || m_attrs.depth) { + ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); + ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height); + if (m_attrs.stencil) + ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); + if (m_attrs.depth) + ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); + } + ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) { + // FIXME: cleanup. + notImplemented(); + } + } + + // resize regular FBO + if (m_boundFBO != m_fbo) { + mustRestoreFBO = true; + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + } + ::glBindTexture(GL_TEXTURE_2D, m_texture); + ::glTexImage2D(GL_TEXTURE_2D, 0, internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0); + ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0); + ::glBindTexture(GL_TEXTURE_2D, 0); + if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth)) { + ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer); + ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height); + 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); + } + if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) { + // FIXME: cleanup + notImplemented(); + } + + if (m_attrs.antialias) { + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); + if (m_boundFBO == m_multisampleFBO) + mustRestoreFBO = false; + } + + // Initialize renderbuffers to 0. + GLboolean colorMask[] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}, depthMask = GL_TRUE, stencilMask = GL_TRUE; + GLboolean isScissorEnabled = GL_FALSE; + GLboolean isDitherEnabled = GL_FALSE; + GLbitfield clearMask = GL_COLOR_BUFFER_BIT; + ::glGetBooleanv(GL_COLOR_WRITEMASK, colorMask); + ::glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + if (m_attrs.depth) { + ::glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask); + ::glDepthMask(GL_TRUE); + clearMask |= GL_DEPTH_BUFFER_BIT; + } + if (m_attrs.stencil) { + ::glGetBooleanv(GL_STENCIL_WRITEMASK, &stencilMask); + ::glStencilMask(GL_TRUE); + clearMask |= GL_STENCIL_BUFFER_BIT; + } + isScissorEnabled = ::glIsEnabled(GL_SCISSOR_TEST); + ::glDisable(GL_SCISSOR_TEST); + isDitherEnabled = ::glIsEnabled(GL_DITHER); + ::glDisable(GL_DITHER); + + ::glClear(clearMask); + + ::glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]); + if (m_attrs.depth) + ::glDepthMask(depthMask); + if (m_attrs.stencil) + ::glStencilMask(stencilMask); + if (isScissorEnabled) + ::glEnable(GL_SCISSOR_TEST); + else + ::glDisable(GL_SCISSOR_TEST); + if (isDitherEnabled) + ::glEnable(GL_DITHER); + else + ::glDisable(GL_DITHER); + + if (mustRestoreFBO) + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); + + ::glFlush(); +} + +void GraphicsContext3D::prepareTexture() +{ + makeContextCurrent(); + if (m_attrs.antialias) { + ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); + ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); + ::glBlitFramebufferEXT(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); + } + ::glFinish(); +} + +void GraphicsContext3D::activeTexture(unsigned long texture) +{ + makeContextCurrent(); + ::glActiveTexture(texture); +} + +void GraphicsContext3D::attachShader(Platform3DObject program, Platform3DObject shader) +{ + ASSERT(program); + ASSERT(shader); + makeContextCurrent(); + ::glAttachShader((GLuint) program, (GLuint) shader); +} + +void GraphicsContext3D::bindAttribLocation(Platform3DObject program, unsigned long index, const String& name) +{ + ASSERT(program); + makeContextCurrent(); + ::glBindAttribLocation((GLuint) program, index, name.utf8().data()); +} + +void GraphicsContext3D::bindBuffer(unsigned long target, Platform3DObject buffer) +{ + makeContextCurrent(); + ::glBindBuffer(target, (GLuint) buffer); +} + + +void GraphicsContext3D::bindFramebuffer(unsigned long target, Platform3DObject buffer) +{ + makeContextCurrent(); + GLuint fbo; + if (buffer) + fbo = (GLuint)buffer; + else + fbo = (m_attrs.antialias ? m_multisampleFBO : m_fbo); + if (fbo != m_boundFBO) { + ::glBindFramebufferEXT(target, fbo); + m_boundFBO = fbo; + } +} + +void GraphicsContext3D::bindRenderbuffer(unsigned long target, Platform3DObject renderbuffer) +{ + makeContextCurrent(); + ::glBindRenderbufferEXT(target, (GLuint) renderbuffer); +} + + +void GraphicsContext3D::bindTexture(unsigned long target, Platform3DObject texture) +{ + makeContextCurrent(); + ::glBindTexture(target, (GLuint) texture); +} + +void GraphicsContext3D::blendColor(double red, double green, double blue, double alpha) +{ + makeContextCurrent(); + ::glBlendColor(static_cast<float>(red), static_cast<float>(green), static_cast<float>(blue), static_cast<float>(alpha)); +} + +void GraphicsContext3D::blendEquation( unsigned long mode ) +{ + makeContextCurrent(); + ::glBlendEquation(mode); +} + +void GraphicsContext3D::blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha) +{ + makeContextCurrent(); + ::glBlendEquationSeparate(modeRGB, modeAlpha); +} + + +void GraphicsContext3D::blendFunc(unsigned long sfactor, unsigned long dfactor) +{ + makeContextCurrent(); + ::glBlendFunc(sfactor, dfactor); +} + +void GraphicsContext3D::blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha) +{ + makeContextCurrent(); + ::glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); +} + +void GraphicsContext3D::bufferData(unsigned long target, int size, unsigned long usage) +{ + makeContextCurrent(); + ::glBufferData(target, size, 0, usage); +} + +void GraphicsContext3D::bufferData(unsigned long target, int size, const void* data, unsigned long usage) +{ + makeContextCurrent(); + ::glBufferData(target, size, data, usage); +} + +void GraphicsContext3D::bufferSubData(unsigned long target, long offset, int size, const void* data) +{ + makeContextCurrent(); + ::glBufferSubData(target, offset, size, data); +} + +unsigned long GraphicsContext3D::checkFramebufferStatus(unsigned long target) +{ + makeContextCurrent(); + return ::glCheckFramebufferStatusEXT(target); +} + +void GraphicsContext3D::clearColor(double r, double g, double b, double a) +{ + makeContextCurrent(); + ::glClearColor(static_cast<float>(r), static_cast<float>(g), static_cast<float>(b), static_cast<float>(a)); +} + +void GraphicsContext3D::clear(unsigned long mask) +{ + makeContextCurrent(); + ::glClear(mask); +} + +void GraphicsContext3D::clearDepth(double depth) +{ + makeContextCurrent(); + ::glClearDepth(depth); +} + +void GraphicsContext3D::clearStencil(long s) +{ + makeContextCurrent(); + ::glClearStencil(s); +} + +void GraphicsContext3D::colorMask(bool red, bool green, bool blue, bool alpha) +{ + makeContextCurrent(); + ::glColorMask(red, green, blue, alpha); +} + +void GraphicsContext3D::compileShader(Platform3DObject shader) +{ + ASSERT(shader); + makeContextCurrent(); + + int GLshaderType; + ANGLEShaderType shaderType; + + glGetShaderiv(shader, SHADER_TYPE, &GLshaderType); + + if (GLshaderType == VERTEX_SHADER) + shaderType = SHADER_TYPE_VERTEX; + else if (GLshaderType == FRAGMENT_SHADER) + shaderType = SHADER_TYPE_FRAGMENT; + else + return; // Invalid shader type. + + HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader); + + if (result == m_shaderSourceMap.end()) + return; + + ShaderSourceEntry& entry = result->second; + + String translatedShaderSource; + String shaderInfoLog; + + bool isValid = m_compiler.validateShaderSource(entry.source.utf8().data(), shaderType, translatedShaderSource, shaderInfoLog); + + entry.log = shaderInfoLog; + entry.isValid = isValid; + + if (!isValid) + return; // Shader didn't validate, don't move forward with compiling translated source + + int translatedShaderLength = translatedShaderSource.length(); + + const CString& translatedShaderCString = translatedShaderSource.utf8(); + const char* translatedShaderPtr = translatedShaderCString.data(); + + ::glShaderSource((GLuint) shader, 1, &translatedShaderPtr, &translatedShaderLength); + + ::glCompileShader((GLuint) shader); + + int GLCompileSuccess; + + ::glGetShaderiv((GLuint) shader, COMPILE_STATUS, &GLCompileSuccess); + + // ASSERT that ANGLE generated GLSL will be accepted by OpenGL + ASSERT(GLCompileSuccess == GL_TRUE); +} + +void GraphicsContext3D::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border) +{ + makeContextCurrent(); + if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) { + ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); + ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); + ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + } + ::glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); + if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); +} + +void GraphicsContext3D::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height) +{ + makeContextCurrent(); + if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) { + ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); + ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); + ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + } + ::glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); + if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); +} + +void GraphicsContext3D::cullFace(unsigned long mode) +{ + makeContextCurrent(); + ::glCullFace(mode); +} + +void GraphicsContext3D::depthFunc(unsigned long func) +{ + makeContextCurrent(); + ::glDepthFunc(func); +} + +void GraphicsContext3D::depthMask(bool flag) +{ + makeContextCurrent(); + ::glDepthMask(flag); +} + +void GraphicsContext3D::depthRange(double zNear, double zFar) +{ + makeContextCurrent(); + ::glDepthRange(zNear, zFar); +} + +void GraphicsContext3D::detachShader(Platform3DObject program, Platform3DObject shader) +{ + ASSERT(program); + ASSERT(shader); + makeContextCurrent(); + ::glDetachShader((GLuint) program, (GLuint) shader); +} + +void GraphicsContext3D::disable(unsigned long cap) +{ + makeContextCurrent(); + ::glDisable(cap); +} + +void GraphicsContext3D::disableVertexAttribArray(unsigned long index) +{ + makeContextCurrent(); + ::glDisableVertexAttribArray(index); +} + +void GraphicsContext3D::drawArrays(unsigned long mode, long first, long count) +{ + makeContextCurrent(); + ::glDrawArrays(mode, first, count); +} + +void GraphicsContext3D::drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset) +{ + makeContextCurrent(); + ::glDrawElements(mode, count, type, reinterpret_cast<void*>(static_cast<intptr_t>(offset))); +} + +void GraphicsContext3D::enable(unsigned long cap) +{ + makeContextCurrent(); + ::glEnable(cap); +} + +void GraphicsContext3D::enableVertexAttribArray(unsigned long index) +{ + makeContextCurrent(); + ::glEnableVertexAttribArray(index); +} + +void GraphicsContext3D::finish() +{ + makeContextCurrent(); + ::glFinish(); +} + +void GraphicsContext3D::flush() +{ + makeContextCurrent(); + ::glFlush(); +} + +void GraphicsContext3D::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, Platform3DObject buffer) +{ + makeContextCurrent(); + GLuint renderbuffer = (GLuint) buffer; + if (attachment == DEPTH_STENCIL_ATTACHMENT) { + ::glFramebufferRenderbufferEXT(target, DEPTH_ATTACHMENT, renderbuffertarget, renderbuffer); + ::glFramebufferRenderbufferEXT(target, STENCIL_ATTACHMENT, renderbuffertarget, renderbuffer); + } else + ::glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer); +} + +void GraphicsContext3D::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, Platform3DObject texture, long level) +{ + makeContextCurrent(); + ::glFramebufferTexture2DEXT(target, attachment, textarget, (GLuint) texture, level); +} + +void GraphicsContext3D::frontFace(unsigned long mode) +{ + makeContextCurrent(); + ::glFrontFace(mode); +} + +void GraphicsContext3D::generateMipmap(unsigned long target) +{ + makeContextCurrent(); + ::glGenerateMipmapEXT(target); +} + +bool GraphicsContext3D::getActiveAttrib(Platform3DObject program, unsigned long index, ActiveInfo& info) +{ + if (!program) { + synthesizeGLError(INVALID_VALUE); + return false; + } + makeContextCurrent(); + GLint maxAttributeSize = 0; + ::glGetProgramiv(static_cast<GLuint>(program), GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttributeSize); + GLchar name[maxAttributeSize]; // GL_ACTIVE_ATTRIBUTE_MAX_LENGTH includes null termination + GLsizei nameLength = 0; + GLint size = 0; + GLenum type = 0; + ::glGetActiveAttrib(static_cast<GLuint>(program), index, maxAttributeSize, &nameLength, &size, &type, name); + if (!nameLength) + return false; + info.name = String(name, nameLength); + info.type = type; + info.size = size; + return true; +} + +bool GraphicsContext3D::getActiveUniform(Platform3DObject program, unsigned long index, ActiveInfo& info) +{ + if (!program) { + synthesizeGLError(INVALID_VALUE); + return false; + } + makeContextCurrent(); + GLint maxUniformSize = 0; + ::glGetProgramiv(static_cast<GLuint>(program), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformSize); + GLchar name[maxUniformSize]; // GL_ACTIVE_UNIFORM_MAX_LENGTH includes null termination + GLsizei nameLength = 0; + GLint size = 0; + GLenum type = 0; + ::glGetActiveUniform(static_cast<GLuint>(program), index, maxUniformSize, &nameLength, &size, &type, name); + if (!nameLength) + return false; + info.name = String(name, nameLength); + info.type = type; + info.size = size; + return true; +} + +void GraphicsContext3D::getAttachedShaders(Platform3DObject program, int maxCount, int* count, unsigned int* shaders) +{ + if (!program) { + synthesizeGLError(INVALID_VALUE); + return; + } + makeContextCurrent(); + ::glGetAttachedShaders(static_cast<GLuint>(program), maxCount, count, shaders); +} + +int GraphicsContext3D::getAttribLocation(Platform3DObject program, const String& name) +{ + if (!program) + return -1; + + makeContextCurrent(); + return ::glGetAttribLocation((GLuint) program, name.utf8().data()); +} + +GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes() +{ + return m_attrs; +} + +unsigned long GraphicsContext3D::getError() +{ + if (m_syntheticErrors.size() > 0) { + ListHashSet<unsigned long>::iterator iter = m_syntheticErrors.begin(); + unsigned long err = *iter; + m_syntheticErrors.remove(iter); + return err; + } + + makeContextCurrent(); + return ::glGetError(); +} + +String GraphicsContext3D::getString(unsigned long name) +{ + makeContextCurrent(); + return String((const char*) ::glGetString(name)); +} + +void GraphicsContext3D::hint(unsigned long target, unsigned long mode) +{ + makeContextCurrent(); + ::glHint(target, mode); +} + +bool GraphicsContext3D::isBuffer(Platform3DObject buffer) +{ + if (!buffer) + return false; + + makeContextCurrent(); + return ::glIsBuffer((GLuint) buffer); +} + +bool GraphicsContext3D::isEnabled(unsigned long cap) +{ + makeContextCurrent(); + return ::glIsEnabled(cap); +} + +bool GraphicsContext3D::isFramebuffer(Platform3DObject framebuffer) +{ + if (!framebuffer) + return false; + + makeContextCurrent(); + return ::glIsFramebufferEXT((GLuint) framebuffer); +} + +bool GraphicsContext3D::isProgram(Platform3DObject program) +{ + if (!program) + return false; + + makeContextCurrent(); + return ::glIsProgram((GLuint) program); +} + +bool GraphicsContext3D::isRenderbuffer(Platform3DObject renderbuffer) +{ + if (!renderbuffer) + return false; + + makeContextCurrent(); + return ::glIsRenderbufferEXT((GLuint) renderbuffer); +} + +bool GraphicsContext3D::isShader(Platform3DObject shader) +{ + if (!shader) + return false; + + makeContextCurrent(); + return ::glIsShader((GLuint) shader); +} + +bool GraphicsContext3D::isTexture(Platform3DObject texture) +{ + if (!texture) + return false; + + makeContextCurrent(); + return ::glIsTexture((GLuint) texture); +} + +void GraphicsContext3D::lineWidth(double width) +{ + makeContextCurrent(); + ::glLineWidth(static_cast<float>(width)); +} + +void GraphicsContext3D::linkProgram(Platform3DObject program) +{ + ASSERT(program); + makeContextCurrent(); + ::glLinkProgram((GLuint) program); +} + +void GraphicsContext3D::pixelStorei(unsigned long pname, long param) +{ + makeContextCurrent(); + ::glPixelStorei(pname, param); +} + +void GraphicsContext3D::polygonOffset(double factor, double units) +{ + makeContextCurrent(); + ::glPolygonOffset(static_cast<float>(factor), static_cast<float>(units)); +} + +void GraphicsContext3D::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* data) +{ + // FIXME: remove the two glFlush calls when the driver bug is fixed, i.e., + // all previous rendering calls should be done before reading pixels. + makeContextCurrent(); + ::glFlush(); + if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) { + ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); + ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); + ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + ::glFlush(); + } + ::glReadPixels(x, y, width, height, format, type, data); + if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); +} + +void GraphicsContext3D::releaseShaderCompiler() +{ + // FIXME: This is not implemented on desktop OpenGL. We need to have ifdefs for the different GL variants + makeContextCurrent(); + //::glReleaseShaderCompiler(); +} + +void GraphicsContext3D::renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height) +{ + makeContextCurrent(); + switch (internalformat) { + case DEPTH_STENCIL: + internalformat = GL_DEPTH24_STENCIL8_EXT; + break; + case DEPTH_COMPONENT16: + internalformat = GL_DEPTH_COMPONENT; + break; + case RGBA4: + case RGB5_A1: + internalformat = GL_RGBA; + break; + case RGB565: + internalformat = GL_RGB; + break; + } + ::glRenderbufferStorageEXT(target, internalformat, width, height); +} + +void GraphicsContext3D::sampleCoverage(double value, bool invert) +{ + makeContextCurrent(); + ::glSampleCoverage(static_cast<float>(value), invert); +} + +void GraphicsContext3D::scissor(long x, long y, unsigned long width, unsigned long height) +{ + makeContextCurrent(); + ::glScissor(x, y, width, height); +} + +void GraphicsContext3D::shaderSource(Platform3DObject shader, const String& string) +{ + ASSERT(shader); + + makeContextCurrent(); + + ShaderSourceEntry entry; + + entry.source = string; + + m_shaderSourceMap.set(shader, entry); +} + +void GraphicsContext3D::stencilFunc(unsigned long func, long ref, unsigned long mask) +{ + makeContextCurrent(); + ::glStencilFunc(func, ref, mask); +} + +void GraphicsContext3D::stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask) +{ + makeContextCurrent(); + ::glStencilFuncSeparate(face, func, ref, mask); +} + +void GraphicsContext3D::stencilMask(unsigned long mask) +{ + makeContextCurrent(); + ::glStencilMask(mask); +} + +void GraphicsContext3D::stencilMaskSeparate(unsigned long face, unsigned long mask) +{ + makeContextCurrent(); + ::glStencilMaskSeparate(face, mask); +} + +void GraphicsContext3D::stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass) +{ + makeContextCurrent(); + ::glStencilOp(fail, zfail, zpass); +} + +void GraphicsContext3D::stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass) +{ + makeContextCurrent(); + ::glStencilOpSeparate(face, fail, zfail, zpass); +} + +void GraphicsContext3D::texParameterf(unsigned target, unsigned pname, float value) +{ + makeContextCurrent(); + ::glTexParameterf(target, pname, static_cast<float>(value)); +} + +void GraphicsContext3D::texParameteri(unsigned target, unsigned pname, int value) +{ + makeContextCurrent(); + ::glTexParameteri(target, pname, static_cast<float>(value)); +} + +void GraphicsContext3D::uniform1f(long location, float v0) +{ + makeContextCurrent(); + ::glUniform1f(location, v0); +} + +void GraphicsContext3D::uniform1fv(long location, float* array, int size) +{ + makeContextCurrent(); + ::glUniform1fv(location, size, array); +} + +void GraphicsContext3D::uniform2f(long location, float v0, float v1) +{ + makeContextCurrent(); + ::glUniform2f(location, v0, v1); +} + +void GraphicsContext3D::uniform2fv(long location, float* array, int size) +{ + // FIXME: length needs to be a multiple of 2 + makeContextCurrent(); + ::glUniform2fv(location, size, array); +} + +void GraphicsContext3D::uniform3f(long location, float v0, float v1, float v2) +{ + makeContextCurrent(); + ::glUniform3f(location, v0, v1, v2); +} + +void GraphicsContext3D::uniform3fv(long location, float* array, int size) +{ + // FIXME: length needs to be a multiple of 3 + makeContextCurrent(); + ::glUniform3fv(location, size, array); +} + +void GraphicsContext3D::uniform4f(long location, float v0, float v1, float v2, float v3) +{ + makeContextCurrent(); + ::glUniform4f(location, v0, v1, v2, v3); +} + +void GraphicsContext3D::uniform4fv(long location, float* array, int size) +{ + // FIXME: length needs to be a multiple of 4 + makeContextCurrent(); + ::glUniform4fv(location, size, array); +} + +void GraphicsContext3D::uniform1i(long location, int v0) +{ + makeContextCurrent(); + ::glUniform1i(location, v0); +} + +void GraphicsContext3D::uniform1iv(long location, int* array, int size) +{ + makeContextCurrent(); + ::glUniform1iv(location, size, array); +} + +void GraphicsContext3D::uniform2i(long location, int v0, int v1) +{ + makeContextCurrent(); + ::glUniform2i(location, v0, v1); +} + +void GraphicsContext3D::uniform2iv(long location, int* array, int size) +{ + // FIXME: length needs to be a multiple of 2 + makeContextCurrent(); + ::glUniform2iv(location, size, array); +} + +void GraphicsContext3D::uniform3i(long location, int v0, int v1, int v2) +{ + makeContextCurrent(); + ::glUniform3i(location, v0, v1, v2); +} + +void GraphicsContext3D::uniform3iv(long location, int* array, int size) +{ + // FIXME: length needs to be a multiple of 3 + makeContextCurrent(); + ::glUniform3iv(location, size, array); +} + +void GraphicsContext3D::uniform4i(long location, int v0, int v1, int v2, int v3) +{ + makeContextCurrent(); + ::glUniform4i(location, v0, v1, v2, v3); +} + +void GraphicsContext3D::uniform4iv(long location, int* array, int size) +{ + // FIXME: length needs to be a multiple of 4 + makeContextCurrent(); + ::glUniform4iv(location, size, array); +} + +void GraphicsContext3D::uniformMatrix2fv(long location, bool transpose, float* array, int size) +{ + // FIXME: length needs to be a multiple of 4 + makeContextCurrent(); + ::glUniformMatrix2fv(location, size, transpose, array); +} + +void GraphicsContext3D::uniformMatrix3fv(long location, bool transpose, float* array, int size) +{ + // FIXME: length needs to be a multiple of 9 + makeContextCurrent(); + ::glUniformMatrix3fv(location, size, transpose, array); +} + +void GraphicsContext3D::uniformMatrix4fv(long location, bool transpose, float* array, int size) +{ + // FIXME: length needs to be a multiple of 16 + makeContextCurrent(); + ::glUniformMatrix4fv(location, size, transpose, array); +} + +void GraphicsContext3D::useProgram(Platform3DObject program) +{ + makeContextCurrent(); + ::glUseProgram((GLuint) program); +} + +void GraphicsContext3D::validateProgram(Platform3DObject program) +{ + ASSERT(program); + + makeContextCurrent(); + ::glValidateProgram((GLuint) program); +} + +void GraphicsContext3D::vertexAttrib1f(unsigned long indx, float v0) +{ + makeContextCurrent(); + ::glVertexAttrib1f(indx, v0); +} + +void GraphicsContext3D::vertexAttrib1fv(unsigned long indx, float* array) +{ + makeContextCurrent(); + ::glVertexAttrib1fv(indx, array); +} + +void GraphicsContext3D::vertexAttrib2f(unsigned long indx, float v0, float v1) +{ + makeContextCurrent(); + ::glVertexAttrib2f(indx, v0, v1); +} + +void GraphicsContext3D::vertexAttrib2fv(unsigned long indx, float* array) +{ + makeContextCurrent(); + ::glVertexAttrib2fv(indx, array); +} + +void GraphicsContext3D::vertexAttrib3f(unsigned long indx, float v0, float v1, float v2) +{ + makeContextCurrent(); + ::glVertexAttrib3f(indx, v0, v1, v2); +} + +void GraphicsContext3D::vertexAttrib3fv(unsigned long indx, float* array) +{ + makeContextCurrent(); + ::glVertexAttrib3fv(indx, array); +} + +void GraphicsContext3D::vertexAttrib4f(unsigned long indx, float v0, float v1, float v2, float v3) +{ + makeContextCurrent(); + ::glVertexAttrib4f(indx, v0, v1, v2, v3); +} + +void GraphicsContext3D::vertexAttrib4fv(unsigned long indx, float* array) +{ + makeContextCurrent(); + ::glVertexAttrib4fv(indx, array); +} + +void GraphicsContext3D::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, unsigned long stride, unsigned long offset) +{ + makeContextCurrent(); + ::glVertexAttribPointer(indx, size, type, normalized, stride, reinterpret_cast<void*>(static_cast<intptr_t>(offset))); +} + +void GraphicsContext3D::viewport(long x, long y, unsigned long width, unsigned long height) +{ + makeContextCurrent(); + ::glViewport(static_cast<GLint>(x), static_cast<GLint>(y), static_cast<GLsizei>(width), static_cast<GLsizei>(height)); +} + +void GraphicsContext3D::getBooleanv(unsigned long pname, unsigned char* value) +{ + makeContextCurrent(); + ::glGetBooleanv(pname, value); +} + +void GraphicsContext3D::getBufferParameteriv(unsigned long target, unsigned long pname, int* value) +{ + makeContextCurrent(); + ::glGetBufferParameteriv(target, pname, value); +} + +void GraphicsContext3D::getFloatv(unsigned long pname, float* value) +{ + makeContextCurrent(); + ::glGetFloatv(pname, value); +} + +void GraphicsContext3D::getFramebufferAttachmentParameteriv(unsigned long target, unsigned long attachment, unsigned long pname, int* value) +{ + makeContextCurrent(); + if (attachment == DEPTH_STENCIL_ATTACHMENT) + attachment = DEPTH_ATTACHMENT; // Or STENCIL_ATTACHMENT, either works. + ::glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value); +} + +void GraphicsContext3D::getIntegerv(unsigned long pname, int* value) +{ + // Need to emulate IMPLEMENTATION_COLOR_READ_FORMAT/TYPE for GL. Any valid + // combination should work, but GL_RGB/GL_UNSIGNED_BYTE might be the most + // useful for desktop WebGL users. + // Need to emulate MAX_FRAGMENT/VERTEX_UNIFORM_VECTORS and MAX_VARYING_VECTORS + // because desktop GL's corresponding queries return the number of components + // whereas GLES2 return the number of vectors (each vector has 4 components). + // Therefore, the value returned by desktop GL needs to be divided by 4. + makeContextCurrent(); + switch (pname) { + case IMPLEMENTATION_COLOR_READ_FORMAT: + *value = GL_RGB; + break; + case IMPLEMENTATION_COLOR_READ_TYPE: + *value = GL_UNSIGNED_BYTE; + break; + case MAX_FRAGMENT_UNIFORM_VECTORS: + ::glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, value); + *value /= 4; + break; + case MAX_VERTEX_UNIFORM_VECTORS: + ::glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, value); + *value /= 4; + break; + case MAX_VARYING_VECTORS: + ::glGetIntegerv(GL_MAX_VARYING_FLOATS, value); + *value /= 4; + break; + default: + ::glGetIntegerv(pname, value); + } +} + +void GraphicsContext3D::getProgramiv(Platform3DObject program, unsigned long pname, int* value) +{ + makeContextCurrent(); + ::glGetProgramiv((GLuint) program, pname, value); +} + +String GraphicsContext3D::getProgramInfoLog(Platform3DObject program) +{ + ASSERT(program); + + makeContextCurrent(); + GLint length; + ::glGetProgramiv((GLuint) program, GL_INFO_LOG_LENGTH, &length); + + GLsizei size; + GLchar* info = (GLchar*) fastMalloc(length); + if (!info) + return ""; + + ::glGetProgramInfoLog((GLuint) program, length, &size, info); + String s(info); + fastFree(info); + return s; +} + +void GraphicsContext3D::getRenderbufferParameteriv(unsigned long target, unsigned long pname, int* value) +{ + makeContextCurrent(); + ::glGetRenderbufferParameterivEXT(target, pname, value); +} + +void GraphicsContext3D::getShaderiv(Platform3DObject shader, unsigned long pname, int* value) +{ + ASSERT(shader); + + makeContextCurrent(); + + HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader); + + switch (pname) { + case DELETE_STATUS: + case SHADER_TYPE: + // Let OpenGL handle these. + + ::glGetShaderiv((GLuint) shader, pname, value); + break; + + case COMPILE_STATUS: + if (result == m_shaderSourceMap.end()) { + (*value) = static_cast<int>(false); + return; + } + + (*value) = static_cast<int>(result->second.isValid); + break; + + case INFO_LOG_LENGTH: + if (result == m_shaderSourceMap.end()) { + (*value) = 0; + return; + } + + (*value) = getShaderInfoLog(shader).length(); + break; + + case SHADER_SOURCE_LENGTH: + (*value) = getShaderSource(shader).length(); + break; + + default: + synthesizeGLError(INVALID_ENUM); + } +} + +String GraphicsContext3D::getShaderInfoLog(Platform3DObject shader) +{ + ASSERT(shader); + + makeContextCurrent(); + GLint length; + ::glGetShaderiv((GLuint) shader, GL_INFO_LOG_LENGTH, &length); + + HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader); + + if (result == m_shaderSourceMap.end()) + return ""; + + ShaderSourceEntry entry = result->second; + + if (entry.isValid) { + GLint length; + ::glGetShaderiv((GLuint) shader, GL_INFO_LOG_LENGTH, &length); + + GLsizei size; + GLchar* info = (GLchar*) fastMalloc(length); + if (!info) + return ""; + + ::glGetShaderInfoLog((GLuint) shader, length, &size, info); + + String s(info); + fastFree(info); + return s; + } + else { + return entry.log; + } +} + +String GraphicsContext3D::getShaderSource(Platform3DObject shader) +{ + ASSERT(shader); + + makeContextCurrent(); + + HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader); + + if (result == m_shaderSourceMap.end()) + return ""; + + return result->second.source; +} + + +void GraphicsContext3D::getTexParameterfv(unsigned long target, unsigned long pname, float* value) +{ + makeContextCurrent(); + ::glGetTexParameterfv(target, pname, value); +} + +void GraphicsContext3D::getTexParameteriv(unsigned long target, unsigned long pname, int* value) +{ + makeContextCurrent(); + ::glGetTexParameteriv(target, pname, value); +} + +void GraphicsContext3D::getUniformfv(Platform3DObject program, long location, float* value) +{ + makeContextCurrent(); + ::glGetUniformfv((GLuint) program, location, value); +} + +void GraphicsContext3D::getUniformiv(Platform3DObject program, long location, int* value) +{ + makeContextCurrent(); + ::glGetUniformiv((GLuint) program, location, value); +} + +long GraphicsContext3D::getUniformLocation(Platform3DObject program, const String& name) +{ + ASSERT(program); + + makeContextCurrent(); + return ::glGetUniformLocation((GLuint) program, name.utf8().data()); +} + +void GraphicsContext3D::getVertexAttribfv(unsigned long index, unsigned long pname, float* value) +{ + makeContextCurrent(); + ::glGetVertexAttribfv(index, pname, value); +} + +void GraphicsContext3D::getVertexAttribiv(unsigned long index, unsigned long pname, int* value) +{ + makeContextCurrent(); + ::glGetVertexAttribiv(index, pname, value); +} + +long GraphicsContext3D::getVertexAttribOffset(unsigned long index, unsigned long pname) +{ + makeContextCurrent(); + + void* pointer; + ::glGetVertexAttribPointerv(index, pname, &pointer); + return reinterpret_cast<long>(pointer); +} + +int GraphicsContext3D::texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, void* pixels) +{ + makeContextCurrent(); + + ::glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + return 0; +} + +int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, unsigned width, unsigned height, unsigned format, unsigned type, void* pixels) +{ + makeContextCurrent(); + + // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size + ::glTexSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels); + return 0; +} + +unsigned GraphicsContext3D::createBuffer() +{ + makeContextCurrent(); + GLuint o; + glGenBuffers(1, &o); + return o; +} + +unsigned GraphicsContext3D::createFramebuffer() +{ + makeContextCurrent(); + GLuint o; + glGenFramebuffersEXT(1, &o); + return o; +} + +unsigned GraphicsContext3D::createProgram() +{ + makeContextCurrent(); + return glCreateProgram(); +} + +unsigned GraphicsContext3D::createRenderbuffer() +{ + makeContextCurrent(); + GLuint o; + glGenRenderbuffersEXT(1, &o); + return o; +} + +unsigned GraphicsContext3D::createShader(unsigned long type) +{ + makeContextCurrent(); + return glCreateShader((type == FRAGMENT_SHADER) ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER); +} + +unsigned GraphicsContext3D::createTexture() +{ + makeContextCurrent(); + GLuint o; + glGenTextures(1, &o); + return o; +} + +void GraphicsContext3D::deleteBuffer(unsigned buffer) +{ + makeContextCurrent(); + glDeleteBuffers(1, &buffer); +} + +void GraphicsContext3D::deleteFramebuffer(unsigned framebuffer) +{ + makeContextCurrent(); + glDeleteFramebuffersEXT(1, &framebuffer); +} + +void GraphicsContext3D::deleteProgram(unsigned program) +{ + makeContextCurrent(); + glDeleteProgram(program); +} + +void GraphicsContext3D::deleteRenderbuffer(unsigned renderbuffer) +{ + makeContextCurrent(); + glDeleteRenderbuffersEXT(1, &renderbuffer); +} + +void GraphicsContext3D::deleteShader(unsigned shader) +{ + makeContextCurrent(); + glDeleteShader(shader); +} + +void GraphicsContext3D::deleteTexture(unsigned texture) +{ + makeContextCurrent(); + glDeleteTextures(1, &texture); +} + +int GraphicsContext3D::sizeInBytes(int type) +{ + switch (type) { + case GL_BYTE: + return sizeof(GLbyte); + case GL_UNSIGNED_BYTE: + return sizeof(GLubyte); + case GL_SHORT: + return sizeof(GLshort); + case GL_UNSIGNED_SHORT: + return sizeof(GLushort); + case GL_INT: + return sizeof(GLint); + case GL_UNSIGNED_INT: + return sizeof(GLuint); + case GL_FLOAT: + return sizeof(GLfloat); + default: + return 0; + } +} + +void GraphicsContext3D::synthesizeGLError(unsigned long error) +{ + m_syntheticErrors.add(error); +} + +} + +#endif // ENABLE(3D_CANVAS) diff --git a/WebCore/platform/graphics/qt/ContextShadow.cpp b/WebCore/platform/graphics/qt/ContextShadow.cpp index 829ca82..4609923 100644 --- a/WebCore/platform/graphics/qt/ContextShadow.cpp +++ b/WebCore/platform/graphics/qt/ContextShadow.cpp @@ -139,134 +139,80 @@ void ContextShadow::clear() offset = QPointF(0, 0); } -// Instead of integer division, we use 18.14 for fixed-point division. -static const int BlurSumShift = 14; +// Instead of integer division, we use 17.15 for fixed-point division. +static const int BlurSumShift = 15; -// Note: image must be RGB32 format -static void blurHorizontal(QImage& image, int radius, bool swap = false) -{ - Q_ASSERT(image.format() == QImage::Format_ARGB32_Premultiplied); +// Check http://www.w3.org/TR/SVG/filters.html#feGaussianBlur. +// As noted in the SVG filter specification, running box blur 3x +// approximates a real gaussian blur nicely. +void shadowBlur(QImage& image, int radius, const QColor& shadowColor) +{ // See comments in http://webkit.org/b/40793, it seems sensible - // to follow Skia's limit of 128 pixels of blur radius - radius = qMin(128, radius); - - int imgWidth = image.width(); - int imgHeight = image.height(); + // to follow Skia's limit of 128 pixels for the blur radius. + if (radius > 128) + radius = 128; - // Check http://www.w3.org/TR/SVG/filters.html#feGaussianBlur - // for the approaches when the box-blur radius is even vs odd. + int channels[4] = { 3, 0, 1, 3 }; int dmax = radius >> 1; - int dmin = qMax(0, dmax - 1 + (radius & 1)); - - for (int y = 0; y < imgHeight; ++y) { - - unsigned char* pixels = image.scanLine(y); - - int left; - int right; - int pixelCount; - int prev; - int next; - int firstAlpha; - int lastAlpha; - int totalAlpha; - unsigned char* target; - unsigned char* prevPtr; - unsigned char* nextPtr; - - int invCount; - - static const int alphaChannel = 3; - static const int blueChannel = 0; - static const int greenChannel = 1; - - // For each step, we use sliding window algorithm. This is much more - // efficient than computing the sum of each pixels covered by the box - // kernel size for each x. - - // As noted in the SVG filter specification, running box blur 3x - // approximates a real gaussian blur nicely. - - // Step 1: blur alpha channel and store the result in the blue channel. - left = swap ? dmax : dmin; - right = swap ? dmin : dmax; - pixelCount = left + 1 + right; - invCount = (1 << BlurSumShift) / pixelCount; - prev = -left; - next = 1 + right; - firstAlpha = pixels[alphaChannel]; - lastAlpha = pixels[(imgWidth - 1) * 4 + alphaChannel]; - totalAlpha = 0; - for (int i = 0; i < pixelCount; ++i) - totalAlpha += pixels[qBound(0, i - left, imgWidth - 1) * 4 + alphaChannel]; - target = pixels + blueChannel; - prevPtr = pixels + prev * 4 + alphaChannel; - nextPtr = pixels + next * 4 + alphaChannel; - for (int x = 0; x < imgWidth; ++x, ++prev, ++next, target += 4, prevPtr += 4, nextPtr += 4) { - *target = (totalAlpha * invCount) >> BlurSumShift; - int delta = ((next < imgWidth) ? *nextPtr : lastAlpha) - - ((prev > 0) ? *prevPtr : firstAlpha); - totalAlpha += delta; - } - - // Step 2: blur blue channel and store the result in the green channel. - left = swap ? dmin : dmax; - right = swap ? dmax : dmin; - pixelCount = left + 1 + right; - invCount = (1 << BlurSumShift) / pixelCount; - prev = -left; - next = 1 + right; - firstAlpha = pixels[blueChannel]; - lastAlpha = pixels[(imgWidth - 1) * 4 + blueChannel]; - totalAlpha = 0; - for (int i = 0; i < pixelCount; ++i) - totalAlpha += pixels[qBound(0, i - left, imgWidth - 1) * 4 + blueChannel]; - target = pixels + greenChannel; - prevPtr = pixels + prev * 4 + blueChannel; - nextPtr = pixels + next * 4 + blueChannel; - for (int x = 0; x < imgWidth; ++x, ++prev, ++next, target += 4, prevPtr += 4, nextPtr += 4) { - *target = (totalAlpha * invCount) >> BlurSumShift; - int delta = ((next < imgWidth) ? *nextPtr : lastAlpha) - - ((prev > 0) ? *prevPtr : firstAlpha); - totalAlpha += delta; - } - - // Step 3: blur green channel and store the result in the alpha channel. - left = dmax; - right = dmax; - pixelCount = left + 1 + right; - invCount = (1 << BlurSumShift) / pixelCount; - prev = -left; - next = 1 + right; - firstAlpha = pixels[greenChannel]; - lastAlpha = pixels[(imgWidth - 1) * 4 + greenChannel]; - totalAlpha = 0; - for (int i = 0; i < pixelCount; ++i) - totalAlpha += pixels[qBound(0, i - left, imgWidth - 1) * 4 + greenChannel]; - target = pixels + alphaChannel; - prevPtr = pixels + prev * 4 + greenChannel; - nextPtr = pixels + next * 4 + greenChannel; - for (int x = 0; x < imgWidth; ++x, ++prev, ++next, target += 4, prevPtr += 4, nextPtr += 4) { - *target = (totalAlpha * invCount) >> BlurSumShift; - int delta = ((next < imgWidth) ? *nextPtr : lastAlpha) - - ((prev > 0) ? *prevPtr : firstAlpha); - totalAlpha += delta; + int dmin = dmax - 1 + (radius & 1); + if (dmin < 0) + dmin = 0; + + // Two stages: horizontal and vertical + for (int k = 0; k < 2; ++k) { + + unsigned char* pixels = image.bits(); + int stride = (!k) ? 4 : image.bytesPerLine(); + int delta = (!k) ? image.bytesPerLine() : 4; + int jfinal = (!k) ? image.height() : image.width(); + int dim = (!k) ? image.width() : image.height(); + + for (int j = 0; j < jfinal; ++j, pixels += delta) { + + // For each step, we blur the alpha in a channel and store the result + // in another channel for the subsequent step. + // We use sliding window algorithm to accumulate the alpha values. + // This is much more efficient than computing the sum of each pixels + // covered by the box kernel size for each x. + + for (int step = 0; step < 3; ++step) { + int side1 = (!step) ? dmin : dmax; + int side2 = (step == 1) ? dmin : dmax; + int pixelCount = side1 + 1 + side2; + int invCount = ((1 << BlurSumShift) + pixelCount - 1) / pixelCount; + int ofs = 1 + side2; + int alpha1 = pixels[channels[step]]; + int alpha2 = pixels[(dim - 1) * stride + channels[step]]; + unsigned char* ptr = pixels + channels[step + 1]; + unsigned char* prev = pixels + stride + channels[step]; + unsigned char* next = pixels + ofs * stride + channels[step]; + + int i; + int sum = side1 * alpha1 + alpha1; + int limit = (dim < side2 + 1) ? dim : side2 + 1; + for (i = 1; i < limit; ++i, prev += stride) + sum += *prev; + if (limit <= side2) + sum += (side2 - limit + 1) * alpha2; + + limit = (side1 < dim) ? side1 : dim; + for (i = 0; i < limit; ptr += stride, next += stride, ++i, ++ofs) { + *ptr = (sum * invCount) >> BlurSumShift; + sum += ((ofs < dim) ? *next : alpha2) - alpha1; + } + prev = pixels + channels[step]; + for (; ofs < dim; ptr += stride, prev += stride, next += stride, ++i, ++ofs) { + *ptr = (sum * invCount) >> BlurSumShift; + sum += (*next) - (*prev); + } + for (; i < dim; ptr += stride, prev += stride, ++i) { + *ptr = (sum * invCount) >> BlurSumShift; + sum += alpha2 - (*prev); + } + } } } -} - -static void shadowBlur(QImage& image, int radius, const QColor& shadowColor) -{ - blurHorizontal(image, radius); - - QTransform transform; - transform.rotate(90); - image = image.transformed(transform); - blurHorizontal(image, radius, true); - transform.reset(); - transform.rotate(270); - image = image.transformed(transform); // "Colorize" with the right shadow color. QPainter p(&image); diff --git a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp index 7918378..0756aa7 100644 --- a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp @@ -491,13 +491,16 @@ void* GraphicsContext3DInternal::getProcAddress(const String& proc) return 0; } -PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow) +PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle) { - OwnPtr<GraphicsContext3D> context(new GraphicsContext3D(attrs, hostWindow)); + // This implementation doesn't currently support rendering directly to the HostWindow. + if (renderStyle == RenderDirectlyToHostWindow) + return 0; + OwnPtr<GraphicsContext3D> context(new GraphicsContext3D(attrs, hostWindow, false)); return context->m_internal ? context.release() : 0; } -GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow) +GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, bool) : m_internal(new GraphicsContext3DInternal(attrs, hostWindow)) { if (!m_internal->isContextValid()) diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index c9c74dd..5a29ad4 100644 --- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -174,14 +174,10 @@ public: GraphicsContextPlatformPrivate(QPainter* painter); ~GraphicsContextPlatformPrivate(); - inline QPainter* p() + inline QPainter* p() const { - if (layers.isEmpty()) { - if (redirect) - return redirect; - + if (layers.isEmpty()) return painter; - } return &layers.top()->painter; } @@ -191,7 +187,6 @@ public: // Counting real layers. Required by inTransparencyLayer() calls // For example, layers with valid alphaMask are not real layers int layerCount; - QPainter* redirect; // reuse this brush for solid color (to prevent expensive QBrush construction) QBrush solidColor; @@ -212,9 +207,9 @@ public: QRectF clipBoundingRect() const { #if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0) - return painter->clipBoundingRect(); + return p()->clipBoundingRect(); #else - return painter->clipRegion().boundingRect(); + return p()->clipRegion().boundingRect(); #endif } @@ -227,7 +222,6 @@ GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate(QPainter* p) { painter = p; layerCount = 0; - redirect = 0; solidColor = QBrush(Qt::black); diff --git a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp index e164f8c..079d8ba 100644 --- a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp @@ -130,22 +130,21 @@ public: TransformChange = (1L << 6), ContentChange = (1L << 7), - GeometryOrientationChange = (1L << 8), - ContentsOrientationChange = (1L << 9), - OpacityChange = (1L << 10), - ContentsRectChange = (1L << 11), - - Preserves3DChange = (1L << 12), - MasksToBoundsChange = (1L << 13), - DrawsContentChange = (1L << 14), - ContentsOpaqueChange = (1L << 15), - - BackfaceVisibilityChange = (1L << 16), - ChildrenTransformChange = (1L << 17), - DisplayChange = (1L << 18), - BackgroundColorChange = (1L << 19), - - DistributesOpacityChange = (1L << 20) + ContentsOrientationChange = (1L << 8), + OpacityChange = (1L << 9), + ContentsRectChange = (1L << 10), + + Preserves3DChange = (1L << 11), + MasksToBoundsChange = (1L << 12), + DrawsContentChange = (1L << 13), + ContentsOpaqueChange = (1L << 14), + + BackfaceVisibilityChange = (1L << 15), + ChildrenTransformChange = (1L << 16), + DisplayChange = (1L << 17), + BackgroundColorChange = (1L << 18), + + DistributesOpacityChange = (1L << 19) }; // The compositor lets us special-case images and colors, so we try to do so. @@ -250,7 +249,6 @@ public: TransformationMatrix childrenTransform; Color backgroundColor; Color currentColor; - GraphicsLayer::CompositingCoordinatesOrientation geoOrientation; GraphicsLayer::CompositingCoordinatesOrientation contentsOrientation; float opacity; QRect contentsRect; @@ -777,7 +775,6 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform m_state.anchorPoint = m_layer->anchorPoint(); m_state.size = m_layer->size(); m_state.transform = m_layer->transform(); - m_state.geoOrientation = m_layer->geometryOrientation(); m_state.contentsOrientation =m_layer->contentsOrientation(); m_state.opacity = m_layer->opacity(); m_state.contentsRect = m_layer->contentsRect(); @@ -837,13 +834,6 @@ PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client) return new GraphicsLayerQt(client); } -/* \reimp (GraphicsLayer.h): Qt is top-down -*/ -GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayer::compositingCoordinatesOrientation() -{ - return CompositingCoordinatesTopDown; -} - /* \reimp (GraphicsLayer.h): The current size might change, thus we need to update the whole display. */ void GraphicsLayerQt::setNeedsDisplay() @@ -1149,14 +1139,6 @@ void GraphicsLayerQt::setContentsToMedia(PlatformLayer* media) /* \reimp (GraphicsLayer.h) */ -void GraphicsLayerQt::setGeometryOrientation(CompositingCoordinatesOrientation orientation) -{ - m_impl->notifyChange(GraphicsLayerQtImpl::GeometryOrientationChange); - GraphicsLayer::setGeometryOrientation(orientation); -} - -/* \reimp (GraphicsLayer.h) -*/ void GraphicsLayerQt::setContentsOrientation(CompositingCoordinatesOrientation orientation) { m_impl->notifyChange(GraphicsLayerQtImpl::ContentsOrientationChange); diff --git a/WebCore/platform/graphics/qt/GraphicsLayerQt.h b/WebCore/platform/graphics/qt/GraphicsLayerQt.h index 4282e64..75ca498 100644 --- a/WebCore/platform/graphics/qt/GraphicsLayerQt.h +++ b/WebCore/platform/graphics/qt/GraphicsLayerQt.h @@ -81,7 +81,6 @@ public: virtual void setContentsToGraphicsContext3D(const GraphicsContext3D*); virtual void setGraphicsContext3DNeedsDisplay(); #endif - virtual void setGeometryOrientation(CompositingCoordinatesOrientation orientation); virtual void setContentsOrientation(CompositingCoordinatesOrientation orientation); virtual void distributeOpacity(float); virtual float accumulatedOpacity() const; diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp b/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp index 605dcb7..1bf1a3d 100644 --- a/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp +++ b/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp @@ -25,6 +25,7 @@ #include "GraphicsContext.h" #include "HTMLMediaElement.h" #include "HTMLVideoElement.h" +#include "NetworkingContext.h" #include "NotImplemented.h" #include "TimeRanges.h" #include "Widget.h" @@ -192,8 +193,8 @@ void MediaPlayerPrivate::commitLoad(const String& url) // Grab the frame and network manager Frame* frame = document ? document->frame() : 0; + QNetworkAccessManager* manager = frame ? frame->loader()->networkingContext()->networkAccessManager() : 0; FrameLoaderClientQt* frameLoader = frame ? static_cast<FrameLoaderClientQt*>(frame->loader()->client()) : 0; - QNetworkAccessManager* manager = frameLoader ? frameLoader->webFrame()->page()->networkAccessManager() : 0; if (document && manager) { // Set the cookies diff --git a/WebCore/platform/graphics/qt/PathQt.cpp b/WebCore/platform/graphics/qt/PathQt.cpp index df54684..b8b9d5e 100644 --- a/WebCore/platform/graphics/qt/PathQt.cpp +++ b/WebCore/platform/graphics/qt/PathQt.cpp @@ -51,7 +51,6 @@ namespace WebCore { Path::Path() - : m_lastMoveToIndex(0) { } @@ -61,14 +60,12 @@ Path::~Path() Path::Path(const Path& other) : m_path(other.m_path) - , m_lastMoveToIndex(other.m_lastMoveToIndex) { } Path& Path::operator=(const Path& other) { m_path = other.m_path; - m_lastMoveToIndex = other.m_lastMoveToIndex; return *this; } @@ -183,7 +180,6 @@ FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) void Path::moveTo(const FloatPoint& point) { - m_lastMoveToIndex = m_path.elementCount(); m_path.moveTo(point); } @@ -267,30 +263,6 @@ void Path::closeSubpath() m_path.closeSubpath(); } -void Path::closeCanvasSubpath() -{ - const int elementCount = m_path.elementCount(); - - if (!elementCount) - return; - - QPointF lastMoveToPoint = m_path.elementAt(m_lastMoveToIndex); - int elementsInLastSubpath = 0; - - for (int i = m_lastMoveToIndex; i < elementCount; ++i) { - QPainterPath::Element element = m_path.elementAt(i); - if (element.isLineTo() || element.isCurveTo()) { - // All we need to know is if there are 1 or more elements in the last subpath. - if (++elementsInLastSubpath == 2) { - m_path.lineTo(lastMoveToPoint); - return; - } - } - } - - moveTo(lastMoveToPoint); -} - #define DEGREES(t) ((t) * 180.0 / M_PI) void Path::addArc(const FloatPoint& p, float r, float sar, float ear, bool anticlockwise) { diff --git a/WebCore/platform/graphics/qt/TransparencyLayer.h b/WebCore/platform/graphics/qt/TransparencyLayer.h index 1a614ac..6bdfb39 100644 --- a/WebCore/platform/graphics/qt/TransparencyLayer.h +++ b/WebCore/platform/graphics/qt/TransparencyLayer.h @@ -61,9 +61,6 @@ struct TransparencyLayer : FastAllocBase { painter.setFont(p->font()); if (painter.paintEngine()->hasFeature(QPaintEngine::PorterDuff)) painter.setCompositionMode(p->compositionMode()); - // if the path is an empty region, this assignment disables all painting - if (!p->clipPath().isEmpty()) - painter.setClipPath(p->clipPath()); } TransparencyLayer() diff --git a/WebCore/platform/graphics/skia/ImageSkia.cpp b/WebCore/platform/graphics/skia/ImageSkia.cpp index 9625b34..0b96d80 100644 --- a/WebCore/platform/graphics/skia/ImageSkia.cpp +++ b/WebCore/platform/graphics/skia/ImageSkia.cpp @@ -33,7 +33,6 @@ #include "AffineTransform.h" #include "BitmapImage.h" #include "BitmapImageSingleFrameSkia.h" -#include "ChromiumBridge.h" #include "FloatConversion.h" #include "FloatRect.h" #include "GLES2Canvas.h" @@ -311,11 +310,6 @@ bool FrameData::clear(bool clearMetadata) return false; } -PassRefPtr<Image> Image::loadPlatformResource(const char *name) -{ - return ChromiumBridge::loadPlatformImageResource(name); -} - void Image::drawPattern(GraphicsContext* context, const FloatRect& floatSrcRect, const AffineTransform& patternTransform, diff --git a/WebCore/platform/graphics/skia/NativeImageSkia.cpp b/WebCore/platform/graphics/skia/NativeImageSkia.cpp index 28e0758..3cc89cc 100644 --- a/WebCore/platform/graphics/skia/NativeImageSkia.cpp +++ b/WebCore/platform/graphics/skia/NativeImageSkia.cpp @@ -35,6 +35,7 @@ #endif #include "NativeImageSkia.h" +#include "SharedGraphicsContext3D.h" #include "SkiaUtils.h" namespace WebCore { @@ -54,6 +55,12 @@ NativeImageSkia::NativeImageSkia(const SkBitmap& other) { } + +NativeImageSkia::~NativeImageSkia() +{ + SharedGraphicsContext3D::removeTexturesFor(this); +} + int NativeImageSkia::decodedSize() const { return getSize() + m_resizedImage.getSize(); diff --git a/WebCore/platform/graphics/skia/NativeImageSkia.h b/WebCore/platform/graphics/skia/NativeImageSkia.h index e26a5ea..00b0a68 100644 --- a/WebCore/platform/graphics/skia/NativeImageSkia.h +++ b/WebCore/platform/graphics/skia/NativeImageSkia.h @@ -42,6 +42,7 @@ namespace WebCore { class NativeImageSkia : public SkBitmap { public: NativeImageSkia(); + ~NativeImageSkia(); // This constructor does a shallow copy of the passed-in SkBitmap (ie., it // references the same pixel data and bumps the refcount). Use only when diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp index 88fbcdd..88fbcdd 100755..100644 --- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp +++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp diff --git a/WebCore/platform/graphics/win/FontPlatformDataCairoWin.h b/WebCore/platform/graphics/win/FontPlatformDataCairoWin.h new file mode 100644 index 0000000..05f9eab --- /dev/null +++ b/WebCore/platform/graphics/win/FontPlatformDataCairoWin.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2006, 2007, 2008 Apple Inc. + * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com + * Copyright (C) 2007 Holger Hans Peter Freyther + * Copyright (C) 2007 Pioneer Research Center USA, Inc. + * All rights reserved. + * + * 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 FontPlatformDataCairoWin_h +#define FontPlatformDataCairoWin_h + +#include "FontDescription.h" +#include "GlyphBuffer.h" +#include "RefCountedGDIHandle.h" +#include "StringImpl.h" +#include <cairo-win32.h> +#include <cairo.h> +#include <wtf/Forward.h> + +typedef struct HFONT__* HFONT; + +namespace WebCore { + +class FontPlatformData { +public: + FontPlatformData(WTF::HashTableDeletedValueType) + : m_fontFace(0) + , m_useGDI(false) + , m_font(WTF::HashTableDeletedValue) + , m_size(0) + , m_syntheticBold(false) + , m_syntheticOblique(false) + , m_scaledFont(0) + { } + + FontPlatformData() + : m_fontFace(0) + , m_useGDI(false) + , m_size(0) + , m_syntheticBold(false) + , m_syntheticOblique(false) + , m_scaledFont(0) + { } + + FontPlatformData(HFONT, float size, bool bold, bool oblique, bool useGDI); + FontPlatformData(cairo_font_face_t* fontFace, float size, bool bold, bool italic); + FontPlatformData(float size, bool bold, bool italic); + FontPlatformData(const FontPlatformData&); + ~FontPlatformData(); + + HFONT hfont() const { return m_font->handle(); } + bool useGDI() const { return m_useGDI; } + cairo_font_face_t* fontFace() const { return m_fontFace; } + + bool isFixedPitch(); + float size() const { return m_size; } + void setSize(float size) { m_size = size; } + bool syntheticBold() const { return m_syntheticBold; } + bool syntheticOblique() const { return m_syntheticOblique; } + cairo_scaled_font_t* scaledFont() const { return m_scaledFont; } + + unsigned hash() const + { + return m_font->hash(); + } + + bool operator==(const FontPlatformData&) const; + FontPlatformData& operator=(const FontPlatformData&); + bool isHashTableDeletedValue() const + { + return m_font.isHashTableDeletedValue(); + } + +#ifndef NDEBUG + String description() const; +#endif + +private: + void platformDataInit(HFONT, float size, HDC, WCHAR* faceName); + + RefPtr<RefCountedGDIHandle<HFONT> > m_font; + cairo_font_face_t* m_fontFace; + bool m_useGDI; + float m_size; + bool m_syntheticBold; + bool m_syntheticOblique; + cairo_scaled_font_t* m_scaledFont; +}; + +} + +#endif // FontPlatformDataCairoWin_h diff --git a/WebCore/platform/graphics/win/GraphicsLayerCACF.cpp b/WebCore/platform/graphics/win/GraphicsLayerCACF.cpp index 96ac0c1..dad5da1 100644 --- a/WebCore/platform/graphics/win/GraphicsLayerCACF.cpp +++ b/WebCore/platform/graphics/win/GraphicsLayerCACF.cpp @@ -121,11 +121,6 @@ static void clearLayerBackgroundColor(WKCACFLayer* layer) layer->setBackgroundColor(0); } -GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayer::compositingCoordinatesOrientation() -{ - return CompositingCoordinatesBottomUp; -} - PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client) { return new GraphicsLayerCACF(client); @@ -395,15 +390,6 @@ void GraphicsLayerCACF::setContentsToMedia(PlatformLayer* mediaLayer) updateSublayerList(); } -void GraphicsLayerCACF::setGeometryOrientation(CompositingCoordinatesOrientation orientation) -{ - if (orientation == m_geometryOrientation) - return; - - GraphicsLayer::setGeometryOrientation(orientation); - updateGeometryOrientation(); -} - PlatformLayer* GraphicsLayerCACF::hostLayerForSublayers() const { return m_transformLayer ? m_transformLayer.get() : m_layer.get(); @@ -461,13 +447,6 @@ void GraphicsLayerCACF::swapFromOrToTiledLayer(bool useTiledLayer) m_layer = WebLayer::create(WKCACFLayer::Layer, this); m_usingTiledLayer = useTiledLayer; - - if (useTiledLayer) { - if (GraphicsLayer::compositingCoordinatesOrientation() == GraphicsLayer::CompositingCoordinatesBottomUp) - m_layer->setContentsGravity(WKCACFLayer::BottomLeft); - else - m_layer->setContentsGravity(WKCACFLayer::TopLeft); - } m_layer->adoptSublayers(oldLayer.get()); if (oldLayer->superlayer()) @@ -738,21 +717,6 @@ void GraphicsLayerCACF::updateContentsRect() m_contentsLayer->setBounds(rect); } -void GraphicsLayerCACF::updateGeometryOrientation() -{ - switch (geometryOrientation()) { - case CompositingCoordinatesTopDown: - m_layer->setGeometryFlipped(false); - break; - - case CompositingCoordinatesBottomUp: - m_layer->setGeometryFlipped(true); - break; - } - // Geometry orientation is mapped onto children transform in older QuartzCores, - // so is handled via setGeometryOrientation(). -} - void GraphicsLayerCACF::setupContentsLayer(WKCACFLayer* contentsLayer) { if (contentsLayer == m_contentsLayer) diff --git a/WebCore/platform/graphics/win/GraphicsLayerCACF.h b/WebCore/platform/graphics/win/GraphicsLayerCACF.h index 0b74266..c18a6e9 100644 --- a/WebCore/platform/graphics/win/GraphicsLayerCACF.h +++ b/WebCore/platform/graphics/win/GraphicsLayerCACF.h @@ -89,8 +89,6 @@ public: virtual void setDebugBackgroundColor(const Color&); virtual void setDebugBorder(const Color&, float borderWidth); - virtual void setGeometryOrientation(CompositingCoordinatesOrientation); - private: void updateOpacityOnLayer(); @@ -118,7 +116,6 @@ private: void updateContentsImage(); void updateContentsMedia(); void updateContentsRect(); - void updateGeometryOrientation(); void setupContentsLayer(WKCACFLayer*); WKCACFLayer* contentsLayer() const { return m_contentsLayer.get(); } diff --git a/WebCore/platform/graphics/win/LocalWindowsContext.h b/WebCore/platform/graphics/win/LocalWindowsContext.h index c216140..c216140 100755..100644 --- a/WebCore/platform/graphics/win/LocalWindowsContext.h +++ b/WebCore/platform/graphics/win/LocalWindowsContext.h diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp index e664f2a..4a7e45e 100644..100755 --- a/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp +++ b/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp @@ -107,7 +107,6 @@ void MediaPlayerPrivateFullscreenWindow::setRootChildLayer(PassRefPtr<WKCACFLaye WKCACFLayer* rootLayer = m_rootChild->rootLayer(); CGRect rootBounds = m_rootChild->rootLayer()->bounds(); m_rootChild->setFrame(rootBounds); - m_layerRenderer->setScrollFrame(IntPoint(rootBounds.origin), IntSize(rootBounds.size)); m_rootChild->setBackgroundColor(CGColorGetConstantColor(kCGColorBlack)); #ifndef NDEBUG RetainPtr<CGColorRef> redColor(AdoptCF, CGColorCreateGenericRGB(1, 0, 0, 1)); @@ -165,7 +164,6 @@ LRESULT MediaPlayerPrivateFullscreenWindow::wndProc(HWND hWnd, UINT message, WPA CGRect rootBounds = m_rootChild->rootLayer()->bounds(); m_rootChild->setFrame(rootBounds); m_rootChild->setNeedsLayout(); - m_layerRenderer->setScrollFrame(IntPoint(rootBounds.origin), IntSize(rootBounds.size)); #endif } break; diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp index 9bc68d1..354e0bf 100644 --- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp +++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp @@ -97,6 +97,39 @@ public: private: MediaPlayerPrivateQuickTimeVisualContext* m_parent; }; + +class MediaPlayerPrivateQuickTimeVisualContext::LayoutClient : public WKCACFLayerLayoutClient { +public: + LayoutClient(MediaPlayerPrivateQuickTimeVisualContext* parent) : m_parent(parent) {} + virtual void layoutSublayersOfLayer(WKCACFLayer*); +private: + MediaPlayerPrivateQuickTimeVisualContext* m_parent; +}; + +void MediaPlayerPrivateQuickTimeVisualContext::LayoutClient::layoutSublayersOfLayer(WKCACFLayer* layer) +{ + ASSERT(m_parent); + ASSERT(m_parent->m_transformLayer->platformLayer() == layer); + + CGSize parentSize = layer->bounds().size; + CGSize naturalSize = m_parent->naturalSize(); + + // Calculate the ratio of these two sizes and use that ratio to scale the qtVideoLayer: + CGSize ratio = CGSizeMake(parentSize.width / naturalSize.width, parentSize.height / naturalSize.height); + + int videoWidth = 0; + int videoHeight = 0; + m_parent->m_movie->getNaturalSize(videoWidth, videoHeight); + CGRect videoBounds = CGRectMake(0, 0, videoWidth * ratio.width, videoHeight * ratio.height); + CGPoint videoAnchor = m_parent->m_qtVideoLayer->anchorPoint(); + + // Calculate the new position based on the parent's size: + CGPoint position = CGPointMake(parentSize.width * 0.5 - videoBounds.size.width * (0.5 - videoAnchor.x), + parentSize.height * 0.5 - videoBounds.size.height * (0.5 - videoAnchor.y)); + + m_parent->m_qtVideoLayer->setBounds(videoBounds); + m_parent->m_qtVideoLayer->setPosition(position); +} #endif class MediaPlayerPrivateQuickTimeVisualContext::VisualContextClient : public QTMovieVisualContextClient { @@ -137,6 +170,8 @@ MediaPlayerPrivateQuickTimeVisualContext::MediaPlayerPrivateQuickTimeVisualConte , m_movieClient(new MediaPlayerPrivateQuickTimeVisualContext::MovieClient(this)) #if USE(ACCELERATED_COMPOSITING) , m_layerClient(new MediaPlayerPrivateQuickTimeVisualContext::LayerClient(this)) + , m_layoutClient(new MediaPlayerPrivateQuickTimeVisualContext::LayoutClient(this)) + , m_movieTransform(CGAffineTransformIdentity) #endif , m_visualContextClient(new MediaPlayerPrivateQuickTimeVisualContext::VisualContextClient(this)) { @@ -169,7 +204,7 @@ PlatformMedia MediaPlayerPrivateQuickTimeVisualContext::platformMedia() const #if USE(ACCELERATED_COMPOSITING) PlatformLayer* MediaPlayerPrivateQuickTimeVisualContext::platformLayer() const { - return m_qtVideoLayer ? m_qtVideoLayer->platformLayer() : 0; + return m_transformLayer ? m_transformLayer->platformLayer() : 0; } #endif @@ -263,6 +298,24 @@ void MediaPlayerPrivateQuickTimeVisualContext::setUpCookiesForQuickTime(const St } } +static void disableComponentsOnce() +{ + static bool sComponentsDisabled = false; + if (sComponentsDisabled) + return; + sComponentsDisabled = true; + + uint32_t componentsToDisable[][5] = { + {'eat ', 'TEXT', 'text', 0, 0}, + {'eat ', 'TXT ', 'text', 0, 0}, + {'eat ', 'utxt', 'text', 0, 0}, + {'eat ', 'TEXT', 'tx3g', 0, 0}, + }; + + for (size_t i = 0; i < sizeof(componentsToDisable) / sizeof(componentsToDisable[0]); ++i) + QTMovie::disableComponent(componentsToDisable[i]); +} + void MediaPlayerPrivateQuickTimeVisualContext::load(const String& url) { if (!QTMovie::initializeQuickTime()) { @@ -272,6 +325,8 @@ void MediaPlayerPrivateQuickTimeVisualContext::load(const String& url) return; } + disableComponentsOnce(); + // Initialize the task timer. MediaPlayerPrivateTaskTimer::initialize(); @@ -404,7 +459,13 @@ IntSize MediaPlayerPrivateQuickTimeVisualContext::naturalSize() const int width; int height; m_movie->getNaturalSize(width, height); +#if USE(ACCELERATED_COMPOSITING) + CGSize originalSize = {width, height}; + CGSize transformedSize = CGSizeApplyAffineTransform(originalSize, m_movieTransform); + return IntSize(abs(transformedSize.width), abs(transformedSize.height)); +#else return IntSize(width, height); +#endif } bool MediaPlayerPrivateQuickTimeVisualContext::hasVideo() const @@ -763,7 +824,7 @@ void MediaPlayerPrivateQuickTimeVisualContext::retrieveCurrentImage() if (!buffer.pixelBufferRef()) return; - WKCACFLayer* layer = static_cast<WKCACFLayer*>(m_qtVideoLayer->platformLayer()); + WKCACFLayer* layer = m_qtVideoLayer.get(); if (!buffer.lockBaseAddress()) { if (requiredDllsAvailable()) { @@ -1017,6 +1078,40 @@ bool MediaPlayerPrivateQuickTimeVisualContext::hasSetUpVideoRendering() const #endif } +void MediaPlayerPrivateQuickTimeVisualContext::retrieveAndResetMovieTransform() +{ +#if USE(ACCELERATED_COMPOSITING) + // First things first, reset the total movie transform so that + // we can bail out early: + m_movieTransform = CGAffineTransformIdentity; + + if (!m_movie || !m_movie->hasVideo()) + return; + + // This trick will only work on movies with a single video track, + // so bail out early if the video contains more than one (or zero) + // video tracks. + QTTrackArray videoTracks = m_movie->videoTracks(); + if (videoTracks.size() != 1) + return; + + QTTrack* track = videoTracks[0].get(); + ASSERT(track); + + CGAffineTransform movieTransform = m_movie->getTransform(); + if (!CGAffineTransformEqualToTransform(movieTransform, CGAffineTransformIdentity)) + m_movie->resetTransform(); + + CGAffineTransform trackTransform = track->getTransform(); + if (!CGAffineTransformEqualToTransform(trackTransform, CGAffineTransformIdentity)) + track->resetTransform(); + + // Multiply the two transforms together, taking care to + // do so in the correct order, track * movie = final: + m_movieTransform = CGAffineTransformConcat(trackTransform, movieTransform); +#endif +} + void MediaPlayerPrivateQuickTimeVisualContext::createLayerForMovie() { #if USE(ACCELERATED_COMPOSITING) @@ -1028,17 +1123,35 @@ void MediaPlayerPrivateQuickTimeVisualContext::createLayerForMovie() // Create a GraphicsLayer that won't be inserted directly into the render tree, but will used // as a wrapper for a WKCACFLayer which gets inserted as the content layer of the video // renderer's GraphicsLayer. - m_qtVideoLayer.set(new GraphicsLayerCACF(m_layerClient.get())); - if (!m_qtVideoLayer) + m_transformLayer.set(new GraphicsLayerCACF(m_layerClient.get())); + if (!m_transformLayer) return; // Mark the layer as drawing itself, anchored in the top left, and bottom-up. - m_qtVideoLayer->setDrawsContent(true); - m_qtVideoLayer->setAnchorPoint(FloatPoint3D()); - m_qtVideoLayer->setContentsOrientation(GraphicsLayer::CompositingCoordinatesBottomUp); + m_transformLayer->setDrawsContent(false); + m_transformLayer->setAnchorPoint(FloatPoint3D()); + m_transformLayer->setContentsOrientation(GraphicsLayer::CompositingCoordinatesBottomUp); + m_transformLayer->platformLayer()->setLayoutClient(m_layoutClient.get()); + + m_qtVideoLayer = WKCACFLayer::create(WKCACFLayer::Layer); + if (!m_qtVideoLayer) + return; + + if (CGAffineTransformEqualToTransform(m_movieTransform, CGAffineTransformIdentity)) + retrieveAndResetMovieTransform(); + CGAffineTransform t = m_movieTransform; + + // Remove the translation portion of the transform, since we will always rotate about + // the layer's center point. In our limited use-case (a single video track), this is + // safe: + t.tx = t.ty = 0; + m_qtVideoLayer->setTransform(CATransform3DMakeAffineTransform(t)); + #ifndef NDEBUG m_qtVideoLayer->setName("Video layer"); #endif + m_transformLayer->platformLayer()->addSublayer(m_qtVideoLayer.get()); + m_transformLayer->platformLayer()->setNeedsLayout(); // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration(). #endif @@ -1052,8 +1165,13 @@ void MediaPlayerPrivateQuickTimeVisualContext::createLayerForMovie() void MediaPlayerPrivateQuickTimeVisualContext::destroyLayerForMovie() { #if USE(ACCELERATED_COMPOSITING) - if (m_qtVideoLayer) + if (m_qtVideoLayer) { + m_qtVideoLayer->removeFromSuperlayer(); m_qtVideoLayer = 0; + } + + if (m_transformLayer) + m_transformLayer = 0; if (m_imageQueue) m_imageQueue = 0; diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h index 9c449dd..272b90f 100644 --- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h +++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h @@ -50,6 +50,7 @@ class IntSize; class IntRect; #if USE(ACCELERATED_COMPOSITING) +class WKCACFLayer; class WKCAImageQueue; #endif @@ -154,17 +155,25 @@ private: class LayerClient; friend class LayerClient; OwnPtr<LayerClient> m_layerClient; + + class LayoutClient; + friend class LayoutClient; + OwnPtr<LayoutClient> m_layoutClient; #endif class VisualContextClient; friend class VisualContextClient; OwnPtr<VisualContextClient> m_visualContextClient; + void retrieveAndResetMovieTransform(); + MediaPlayer* m_player; RefPtr<QTMovie> m_movie; #if USE(ACCELERATED_COMPOSITING) - OwnPtr<GraphicsLayer> m_qtVideoLayer; + RefPtr<WKCACFLayer> m_qtVideoLayer; + OwnPtr<GraphicsLayer> m_transformLayer; OwnPtr<WKCAImageQueue> m_imageQueue; + CGAffineTransform m_movieTransform; #endif RefPtr<QTMovieVisualContext> m_visualContext; float m_seekTo; @@ -185,6 +194,7 @@ private: double m_timeStartedPlaying; double m_timeStoppedPlaying; #endif + }; } diff --git a/WebCore/platform/graphics/win/QTMovie.cpp b/WebCore/platform/graphics/win/QTMovie.cpp index cc1349a..375d8c2 100644 --- a/WebCore/platform/graphics/win/QTMovie.cpp +++ b/WebCore/platform/graphics/win/QTMovie.cpp @@ -28,6 +28,7 @@ #include "QTMovieTask.h" #include "QTMovieWinTimer.h" +#include <FixMath.h> #include <GXMath.h> #include <Movies.h> #include <QTML.h> @@ -279,6 +280,16 @@ QTMovie::~QTMovie() delete m_private; } +void QTMovie::disableComponent(uint32_t cd[5]) +{ + ComponentDescription nullDesc = {'null', 'base', kAppleManufacturer, 0, 0}; + Component nullComp = FindNextComponent(0, &nullDesc); + Component disabledComp = 0; + + while (disabledComp = FindNextComponent(disabledComp, (ComponentDescription*)&cd[0])) + CaptureComponent(disabledComp, nullComp); +} + void QTMovie::addClient(QTMovieClient* client) { if (client) @@ -696,6 +707,16 @@ bool QTMovie::hasAudio() const return (GetMovieIndTrackType(m_private->m_movie, 1, AudioMediaCharacteristic, movieTrackCharacteristic | movieTrackEnabledOnly)); } +QTTrackArray QTMovie::videoTracks() const +{ + QTTrackArray tracks; + long trackIndex = 1; + + while (Track theTrack = GetMovieIndTrackType(m_private->m_movie, trackIndex++, VisualMediaCharacteristic, movieTrackCharacteristic | movieTrackEnabledOnly)) + tracks.append(QTTrack::create(theTrack)); + + return tracks; +} bool QTMovie::hasClosedCaptions() const { @@ -830,6 +851,45 @@ void QTMovie::getSupportedType(unsigned index, const UChar*& str, unsigned& len) } +CGAffineTransform QTMovie::getTransform() const +{ + ASSERT(m_private->m_movie); + MatrixRecord m = {0}; + GetMovieMatrix(m_private->m_movie, &m); + + ASSERT(!m.matrix[0][2]); + ASSERT(!m.matrix[1][2]); + CGAffineTransform transform = CGAffineTransformMake( + Fix2X(m.matrix[0][0]), + Fix2X(m.matrix[0][1]), + Fix2X(m.matrix[1][0]), + Fix2X(m.matrix[1][1]), + Fix2X(m.matrix[2][0]), + Fix2X(m.matrix[2][1])); + return transform; +} + +void QTMovie::setTransform(CGAffineTransform t) +{ + ASSERT(m_private->m_movie); + MatrixRecord m = {{ + {X2Fix(t.a), X2Fix(t.b), 0}, + {X2Fix(t.c), X2Fix(t.d), 0}, + {X2Fix(t.tx), X2Fix(t.ty), fract1}, + }}; + + SetMovieMatrix(m_private->m_movie, &m); + m_private->cacheMovieScale(); +} + +void QTMovie::resetTransform() +{ + ASSERT(m_private->m_movie); + SetMovieMatrix(m_private->m_movie, 0); + m_private->cacheMovieScale(); +} + + bool QTMovie::initializeQuickTime() { static bool initialized = false; diff --git a/WebCore/platform/graphics/win/QTMovie.h b/WebCore/platform/graphics/win/QTMovie.h index 8fa4b6e..e205b68 100644 --- a/WebCore/platform/graphics/win/QTMovie.h +++ b/WebCore/platform/graphics/win/QTMovie.h @@ -26,9 +26,8 @@ #ifndef QTMovie_h #define QTMovie_h -#include <Unicode.h> -#include <windows.h> -#include <wtf/RefCounted.h> +#include "QTTrack.h" +#include <WTF/Vector.h> #ifdef QTMOVIEWIN_EXPORTS #define QTMOVIEWIN_API __declspec(dllexport) @@ -39,6 +38,7 @@ class QTMovie; class QTMoviePrivate; typedef struct MovieType** Movie; +typedef Vector<RefPtr<QTTrack>> QTTrackArray; class QTMovieClient { public: @@ -62,6 +62,8 @@ public: static bool initializeQuickTime(); static void taskTimerFired(); + static void disableComponent(uint32_t[5]); + QTMovie(QTMovieClient*); ~QTMovie(); @@ -99,12 +101,18 @@ public: bool hasVideo() const; bool hasAudio() const; + QTTrackArray videoTracks() const; + bool hasClosedCaptions() const; void setClosedCaptionsVisible(bool); static unsigned countSupportedTypes(); static void getSupportedType(unsigned index, const UChar*& str, unsigned& len); + CGAffineTransform getTransform() const; + void setTransform(CGAffineTransform); + void resetTransform(); + Movie getMovieHandle() const; private: diff --git a/WebCore/platform/graphics/win/QTTrack.cpp b/WebCore/platform/graphics/win/QTTrack.cpp new file mode 100644 index 0000000..09142bc --- /dev/null +++ b/WebCore/platform/graphics/win/QTTrack.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2007, 2008, 2009, 2010 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 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 "QTTrack.h" + +#include <Movies.h> +#include <QTML.h> + +using namespace std; + +class QTTrackPrivate : public Noncopyable { +public: + QTTrackPrivate(); + ~QTTrackPrivate(); + + QTTrack* m_track; + Track m_trackHandle; +}; + +QTTrackPrivate::QTTrackPrivate() + : m_track(0) + , m_trackHandle(0) +{ +} + +QTTrackPrivate::~QTTrackPrivate() +{ + m_trackHandle = 0; +} + +PassRefPtr<QTTrack> QTTrack::create(Track trackHandle) +{ + return adoptRef(new QTTrack(trackHandle)); +} + +QTTrack::QTTrack(Track trackHandle) + : m_private(new QTTrackPrivate()) +{ + m_private->m_track = this; + m_private->m_trackHandle = trackHandle; +} + +QTTrack::~QTTrack() +{ + delete m_private; +} + +bool QTTrack::isEnabled() const +{ + ASSERT(m_private->m_track); + return GetTrackEnabled(m_private->m_trackHandle); +} + +void QTTrack::setEnabled(bool enabled) +{ + ASSERT(m_private->m_trackHandle); + SetTrackEnabled(m_private->m_trackHandle, enabled); +} + +CGAffineTransform QTTrack::getTransform() const +{ + ASSERT(m_private->m_trackHandle); + MatrixRecord m = {0}; + GetTrackMatrix(m_private->m_trackHandle, &m); + + ASSERT(!m.matrix[0][2]); + ASSERT(!m.matrix[1][2]); + CGAffineTransform transform = CGAffineTransformMake( + Fix2X(m.matrix[0][0]), + Fix2X(m.matrix[0][1]), + Fix2X(m.matrix[1][0]), + Fix2X(m.matrix[1][1]), + Fix2X(m.matrix[2][0]), + Fix2X(m.matrix[2][1])); + + return transform; +} + +void QTTrack::setTransform(CGAffineTransform t) +{ + ASSERT(m_private->m_trackHandle); + MatrixRecord m = {{ + {X2Fix(t.a), X2Fix(t.b), 0}, + {X2Fix(t.c), X2Fix(t.d), 0}, + {X2Fix(t.tx), X2Fix(t.ty), fract1}, + }}; + + SetTrackMatrix(m_private->m_trackHandle, &m); +} + +void QTTrack::resetTransform() +{ + ASSERT(m_private->m_trackHandle); + SetTrackMatrix(m_private->m_trackHandle, 0); +} + diff --git a/WebCore/platform/graphics/win/QTTrack.h b/WebCore/platform/graphics/win/QTTrack.h new file mode 100644 index 0000000..bda5644 --- /dev/null +++ b/WebCore/platform/graphics/win/QTTrack.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2007, 2008, 2009, 2010 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 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 QTTrack_h +#define QTTrack_h + +#include <Unicode.h> +#include <windows.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> + +// We must include this after <Unicode.h>, or the definition of OSErr will change: +#include <CoreGraphics/CGAffineTransform.h> + +#ifdef QTMOVIEWIN_EXPORTS +#define QTMOVIEWIN_API __declspec(dllexport) +#else +#define QTMOVIEWIN_API __declspec(dllimport) +#endif + +class QTTrack; +class QTTrackPrivate; +typedef struct TrackType** Track; + +class QTMOVIEWIN_API QTTrack : public RefCounted<QTTrack> { +public: + static PassRefPtr<QTTrack> create(Track); + ~QTTrack(); + + CGAffineTransform getTransform() const; + void setTransform(CGAffineTransform); + void resetTransform(); + + bool isEnabled() const; + void setEnabled(bool); + + Track getTrackHandle() const; +private: + QTTrack(Track); + QTTrackPrivate* m_private; + friend class QTTrackPrivate; +}; + +#endif diff --git a/WebCore/platform/graphics/win/WKCACFLayer.cpp b/WebCore/platform/graphics/win/WKCACFLayer.cpp index bbe5883..bf47925 100644 --- a/WebCore/platform/graphics/win/WKCACFLayer.cpp +++ b/WebCore/platform/graphics/win/WKCACFLayer.cpp @@ -355,6 +355,9 @@ void WKCACFLayer::setBounds(const CGRect& rect) if (m_needsDisplayOnBoundsChange) setNeedsDisplay(); + + if (m_layoutClient) + setNeedsLayout(); } void WKCACFLayer::setFrame(const CGRect& rect) @@ -368,6 +371,9 @@ void WKCACFLayer::setFrame(const CGRect& rect) if (m_needsDisplayOnBoundsChange && !CGSizeEqualToSize(rect.size, oldFrame.size)) setNeedsDisplay(); + + if (m_layoutClient) + setNeedsLayout(); } void WKCACFLayer::setContentsGravity(ContentsGravityType type) diff --git a/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp b/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp index 630a8af..4f39b13 100644..100755 --- a/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp +++ b/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp @@ -226,15 +226,11 @@ WKCACFLayerRenderer::WKCACFLayerRenderer(WKCACFLayerRendererClient* client) : m_client(client) , m_mightBeAbleToCreateDeviceLater(true) , m_rootLayer(WKCACFRootLayer::create(this)) - , m_scrollLayer(WKCACFLayer::create(WKCACFLayer::Layer)) - , m_clipLayer(WKCACFLayer::create(WKCACFLayer::Layer)) , m_context(AdoptCF, CACFContextCreate(0)) , m_renderContext(static_cast<CARenderContext*>(CACFContextGetRenderContext(m_context.get()))) , m_renderer(0) , m_hostWindow(0) , m_renderTimer(this, &WKCACFLayerRenderer::renderTimerFired) - , m_scrollPosition(0, 0) - , m_scrollSize(1, 1) , m_backingStoreDirty(false) , m_mustResetLostDeviceBeforeRendering(false) { @@ -250,15 +246,8 @@ WKCACFLayerRenderer::WKCACFLayerRenderer(WKCACFLayerRendererClient* client) // Scrolling will affect only the position of the scroll layer without affecting the bounds. m_rootLayer->setName("WKCACFLayerRenderer rootLayer"); - m_clipLayer->setName("WKCACFLayerRenderer clipLayer"); - m_scrollLayer->setName("WKCACFLayerRenderer scrollLayer"); - - m_rootLayer->addSublayer(m_clipLayer); - m_clipLayer->addSublayer(m_scrollLayer); - m_clipLayer->setMasksToBounds(true); m_rootLayer->setAnchorPoint(CGPointMake(0, 0)); - m_scrollLayer->setAnchorPoint(CGPointMake(0, 1)); - m_clipLayer->setAnchorPoint(CGPointMake(0, 1)); + m_rootLayer->setGeometryFlipped(true); #ifndef NDEBUG CGColorRef debugColor = createCGColor(Color(255, 0, 0, 204)); @@ -285,26 +274,6 @@ WKCACFLayer* WKCACFLayerRenderer::rootLayer() const return m_rootLayer.get(); } -void WKCACFLayerRenderer::setScrollFrame(const IntPoint& position, const IntSize& size) -{ - m_scrollSize = size; - m_scrollPosition = position; - - updateScrollFrame(); -} - -void WKCACFLayerRenderer::updateScrollFrame() -{ - CGRect frameBounds = bounds(); - m_clipLayer->setBounds(CGRectMake(0, 0, m_scrollSize.width(), m_scrollSize.height())); - m_clipLayer->setPosition(CGPointMake(0, frameBounds.size.height)); - if (m_rootChildLayer) { - CGRect rootBounds = m_rootChildLayer->bounds(); - m_scrollLayer->setBounds(rootBounds); - } - m_scrollLayer->setPosition(CGPointMake(-m_scrollPosition.x(), m_scrollPosition.y() + m_scrollSize.height())); -} - void WKCACFLayerRenderer::setRootContents(CGImageRef image) { ASSERT(m_rootLayer); @@ -321,16 +290,10 @@ void WKCACFLayerRenderer::setRootContentsAndDisplay(CGImageRef image) void WKCACFLayerRenderer::setRootChildLayer(WKCACFLayer* layer) { - if (!m_scrollLayer) - return; - - m_scrollLayer->removeAllSublayers(); + m_rootLayer->removeAllSublayers(); m_rootChildLayer = layer; - if (layer) { - m_scrollLayer->addSublayer(layer); - // Adjust the scroll frame accordingly - updateScrollFrame(); - } + if (m_rootChildLayer) + m_rootLayer->addSublayer(m_rootChildLayer); } void WKCACFLayerRenderer::layerTreeDidChange() @@ -435,8 +398,6 @@ void WKCACFLayerRenderer::destroyRenderer() s_d3d = 0; m_rootLayer = 0; - m_clipLayer = 0; - m_scrollLayer = 0; m_rootChildLayer = 0; m_mightBeAbleToCreateDeviceLater = true; @@ -454,7 +415,6 @@ void WKCACFLayerRenderer::resize() if (m_rootLayer) { m_rootLayer->setBounds(bounds()); WKCACFContextFlusher::shared().flushAllContexts(); - updateScrollFrame(); } } diff --git a/WebCore/platform/graphics/win/WKCACFLayerRenderer.h b/WebCore/platform/graphics/win/WKCACFLayerRenderer.h index 2647c5f..1d73b99 100644..100755 --- a/WebCore/platform/graphics/win/WKCACFLayerRenderer.h +++ b/WebCore/platform/graphics/win/WKCACFLayerRenderer.h @@ -66,7 +66,6 @@ public: static bool acceleratedCompositingAvailable(); static void didFlushContext(CACFContextRef); - void setScrollFrame(const IntPoint&, const IntSize&); void setRootContents(CGImageRef); void setRootContentsAndDisplay(CGImageRef); void setRootChildLayer(WKCACFLayer* layer); @@ -78,7 +77,6 @@ public: void destroyRenderer(); void resize(); void renderSoon(); - void updateScrollFrame(); protected: WKCACFLayer* rootLayer() const; @@ -105,16 +103,12 @@ private: bool m_mightBeAbleToCreateDeviceLater; COMPtr<IDirect3DDevice9> m_d3dDevice; RefPtr<WKCACFRootLayer> m_rootLayer; - RefPtr<WKCACFLayer> m_scrollLayer; RefPtr<WKCACFLayer> m_rootChildLayer; - RefPtr<WKCACFLayer> m_clipLayer; RetainPtr<CACFContextRef> m_context; CARenderContext* m_renderContext; CARenderOGLContext* m_renderer; HWND m_hostWindow; Timer<WKCACFLayerRenderer> m_renderTimer; - IntPoint m_scrollPosition; - IntSize m_scrollSize; bool m_backingStoreDirty; bool m_mustResetLostDeviceBeforeRendering; #ifndef NDEBUG diff --git a/WebCore/platform/graphics/win/WebLayer.cpp b/WebCore/platform/graphics/win/WebLayer.cpp index 70a522d..70a522d 100755..100644 --- a/WebCore/platform/graphics/win/WebLayer.cpp +++ b/WebCore/platform/graphics/win/WebLayer.cpp diff --git a/WebCore/platform/graphics/win/WebTiledLayer.cpp b/WebCore/platform/graphics/win/WebTiledLayer.cpp index 01dd6ae..01dd6ae 100755..100644 --- a/WebCore/platform/graphics/win/WebTiledLayer.cpp +++ b/WebCore/platform/graphics/win/WebTiledLayer.cpp diff --git a/WebCore/platform/graphics/wince/ColorWince.cpp b/WebCore/platform/graphics/wince/ColorWinCE.cpp index 820b9d2..820b9d2 100644 --- a/WebCore/platform/graphics/wince/ColorWince.cpp +++ b/WebCore/platform/graphics/wince/ColorWinCE.cpp diff --git a/WebCore/platform/graphics/wince/FontCacheWince.cpp b/WebCore/platform/graphics/wince/FontCacheWinCE.cpp index 6b5dfa5..ccfc063 100644 --- a/WebCore/platform/graphics/wince/FontCacheWince.cpp +++ b/WebCore/platform/graphics/wince/FontCacheWinCE.cpp @@ -348,5 +348,4 @@ void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigne copyToVector(procData.m_traitsMasks, traitsMasks); } -} - +} // namespace WebCore diff --git a/WebCore/platform/graphics/wince/FontWince.cpp b/WebCore/platform/graphics/wince/FontWinCE.cpp index c0948c0..e2ff067 100644 --- a/WebCore/platform/graphics/wince/FontWince.cpp +++ b/WebCore/platform/graphics/wince/FontWinCE.cpp @@ -334,4 +334,4 @@ bool Font::canReturnFallbackFontsForComplexText() return false; } -} +} // namespace WebCore diff --git a/WebCore/platform/graphics/wince/GlyphPageTreeNodeWince.cpp b/WebCore/platform/graphics/wince/GlyphPageTreeNodeWinCE.cpp index 27c4e15..1c22f23 100644 --- a/WebCore/platform/graphics/wince/GlyphPageTreeNodeWince.cpp +++ b/WebCore/platform/graphics/wince/GlyphPageTreeNodeWinCE.cpp @@ -75,5 +75,4 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b return true; } -} - +} // namespace WebCore diff --git a/WebCore/platform/graphics/wince/GradientWince.cpp b/WebCore/platform/graphics/wince/GradientWinCE.cpp index 49fa970..d735881 100644 --- a/WebCore/platform/graphics/wince/GradientWince.cpp +++ b/WebCore/platform/graphics/wince/GradientWinCE.cpp @@ -34,7 +34,7 @@ static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::Co return a.stop < b.stop; } -const Vector<Gradient::ColorStop>& Gradient::getStops() const +const Vector<Gradient::ColorStop, 2>& Gradient::getStops() const { if (!m_stopsSorted) { if (m_stops.size()) @@ -49,4 +49,4 @@ void Gradient::fill(GraphicsContext* c, const FloatRect& r) c->fillRect(r, this); } -} +} // namespace WebCore diff --git a/WebCore/platform/graphics/wince/GraphicsContextWince.cpp b/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp index 990a31d..a91b988 100644 --- a/WebCore/platform/graphics/wince/GraphicsContextWince.cpp +++ b/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp @@ -29,7 +29,7 @@ #include "GraphicsContextPrivate.h" #include "NotImplemented.h" #include "Path.h" -#include "PlatformPathWince.h" +#include "PlatformPathWinCE.h" #include "SharedBitmap.h" #include "SimpleFontData.h" #include <wtf/OwnPtr.h> diff --git a/WebCore/platform/graphics/wince/ImageBufferWince.cpp b/WebCore/platform/graphics/wince/ImageBufferWinCE.cpp index 10e502d..15720f3 100644 --- a/WebCore/platform/graphics/wince/ImageBufferWince.cpp +++ b/WebCore/platform/graphics/wince/ImageBufferWinCE.cpp @@ -25,9 +25,7 @@ #include "GraphicsContext.h" #include "Image.h" #include "ImageData.h" -#include "JPEGEncoder.h" #include "NotImplemented.h" -#include "PNGEncoder.h" #include "SharedBitmap.h" #include "UnusedParam.h" #include <wtf/UnusedParam.h> @@ -250,28 +248,8 @@ String ImageBuffer::toDataURL(const String& mimeType, const double*) const if (!m_data.m_bitmap->bytes()) return "data:,"; - Vector<char> output; - const char* header; - if (mimeType.lower() == "image/png") { - if (!compressBitmapToPng(m_data.m_bitmap.get(), output)) - return "data:,"; - header = "data:image/png;base64,"; - } else { - if (!compressBitmapToJpeg(m_data.m_bitmap.get(), output)) - return "data:,"; - header = "data:image/jpeg;base64,"; - } - - Vector<char> base64; - base64Encode(output, base64); - - output.clear(); - - Vector<char> url; - url.append(header, strlen(header)); - url.append(base64); - - return String(url.data(), url.size()); + notImplemented(); + return String(); } -} +} // namespace WebCore diff --git a/WebCore/platform/graphics/wince/ImageWinCE.cpp b/WebCore/platform/graphics/wince/ImageWinCE.cpp new file mode 100644 index 0000000..61ec954 --- /dev/null +++ b/WebCore/platform/graphics/wince/ImageWinCE.cpp @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007-2009 Torch Mobile Inc. + * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.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 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 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 "Image.h" + +#include "BitmapImage.h" +#include "GraphicsContext.h" +#include "ImageDecoder.h" +#include "NotImplemented.h" +#include "PlatformString.h" +#include "SharedBuffer.h" +#include "TransformationMatrix.h" +#include "WinceGraphicsExtras.h" +#include <wtf/OwnPtr.h> + +#include <windows.h> + +namespace WebCore { + +NativeImagePtr RGBA32Buffer::asNewNativeImage() const +{ + NativeImagePtr image = SharedBitmap::createInstance(false, width(), height(), false); + + memcpy(image->bytes(), m_bytes.data(), m_bytes.size() * sizeof(PixelData)); + + return image; +} + +bool FrameData::clear(bool clearMetaData) +{ + if (clearMetaData) + m_haveMetadata = false; + + if (m_frame) { + m_frame = 0; + return true; + } + + return false; +} + +bool BitmapImage::getHBITMAPOfSize(HBITMAP bmp, LPSIZE size) +{ + if (!bmp) + return false; + + BITMAP bmpInfo; + GetObject(bmp, sizeof(BITMAP), &bmpInfo); + + ASSERT(bmpInfo.bmBitsPixel == 32); + int bufferSize = bmpInfo.bmWidthBytes * bmpInfo.bmHeight; + + OwnPtr<HDC> hdc(CreateCompatibleDC(0)); + HGDIOBJ hOldBmp = SelectObject(hdc.get(), bmp); + + { + GraphicsContext gc(hdc.get()); + + IntSize imageSize = BitmapImage::size(); + if (size) + drawFrameMatchingSourceSize(&gc, FloatRect(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight), IntSize(*size), DeviceColorSpace, CompositeCopy); + else + draw(&gc, FloatRect(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight), FloatRect(0, 0, imageSize.width(), imageSize.height()), DeviceColorSpace, CompositeCopy); + } + + SelectObject(hdc.get(), hOldBmp); + + return true; +} + +void BitmapImage::drawFrameMatchingSourceSize(GraphicsContext* ctxt, const FloatRect& dstRect, const IntSize& srcSize, ColorSpace styleColorSpace, CompositeOperator compositeOp) +{ + int frames = frameCount(); + for (int i = 0; i < frames; ++i) { + RefPtr<SharedBitmap> bmp = frameAtIndex(i); + if (!bmp || bmp->height() != static_cast<unsigned>(srcSize.height()) || bmp->width() != static_cast<unsigned>(srcSize.width())) + continue; + + size_t currentFrame = m_currentFrame; + m_currentFrame = i; + draw(ctxt, dstRect, FloatRect(0, 0, srcSize.width(), srcSize.height()), styleColorSpace, compositeOp); + m_currentFrame = currentFrame; + return; + } + + // No image of the correct size was found, fallback to drawing the current frame + IntSize imageSize = BitmapImage::size(); + draw(ctxt, dstRect, FloatRect(0, 0, imageSize.width(), imageSize.height()), styleColorSpace, compositeOp); +} + +void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, const FloatRect& srcRectIn, ColorSpace styleColorSpace, CompositeOperator compositeOp) +{ + if (!m_source.initialized()) + return; + + if (mayFillWithSolidColor()) + fillWithSolidColor(ctxt, dstRect, solidColor(), styleColorSpace, compositeOp); + else { + IntRect intSrcRect(srcRectIn); + RefPtr<SharedBitmap> bmp = frameAtIndex(m_currentFrame); + + if (bmp->width() != m_source.size().width()) { + double scaleFactor = static_cast<double>(bmp->width()) / m_source.size().width(); + + intSrcRect.setX(stableRound(srcRectIn.x() * scaleFactor)); + intSrcRect.setWidth(stableRound(srcRectIn.width() * scaleFactor)); + intSrcRect.setY(stableRound(srcRectIn.y() * scaleFactor)); + intSrcRect.setHeight(stableRound(srcRectIn.height() * scaleFactor)); + } + bmp->draw(ctxt, enclosingIntRect(dstRect), intSrcRect, styleColorSpace, compositeOp); + } + + startAnimation(); +} + +void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform, + const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) +{ + notImplemented(); +} + +void BitmapImage::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRectIn, const AffineTransform& patternTransform, + const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) +{ + RefPtr<SharedBitmap> bmp = nativeImageForCurrentFrame(); + if (!bmp) + return; + + bmp->drawPattern(ctxt, tileRectIn, patternTransform, phase, styleColorSpace, op, destRect, m_source.size()); +} + +void BitmapImage::checkForSolidColor() +{ + if (m_checkedForSolidColor) + return; + + if (frameCount() != 1) { + m_isSolidColor = false; + m_checkedForSolidColor = true; + return; + } + + RefPtr<SharedBitmap> bmp = frameAtIndex(0); + if (!bmp || !bmp->validHeight()) { + m_isSolidColor = false; + return; + } + + if (bmp->width() != 1 || bmp->validHeight() != 1) { + m_isSolidColor = false; + m_checkedForSolidColor = true; + return; + } + + m_isSolidColor = true; + + if (bmp->is16bit()) { + unsigned short c = ((unsigned short *)bmp->bytes())[0]; + int r = (c >> 7) & 0xF8; + int g = (c >> 2) & 0xF8; + int b = (c << 3) & 0xF8; + if (bmp->usesTransparentColor() && bmp->transparentColor() == RGB(r, g, b)) + m_solidColor = Color(r, g, b, 0); + else + m_solidColor = Color(r, g, b); + } else { + unsigned c = ((unsigned *)bmp->bytes())[0]; + m_solidColor = Color(c); + } + + if (bmp->validHeight() == bmp->height()) + m_checkedForSolidColor = true; +} + +} // namespace WebCore diff --git a/WebCore/platform/graphics/wince/MediaPlayerPrivateWince.h b/WebCore/platform/graphics/wince/MediaPlayerPrivateWinCE.h index e86b8a9..f49d8e2 100644 --- a/WebCore/platform/graphics/wince/MediaPlayerPrivateWince.h +++ b/WebCore/platform/graphics/wince/MediaPlayerPrivateWinCE.h @@ -24,8 +24,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MediaPlayerPrivateWince_h -#define MediaPlayerPrivateWince_h +#ifndef MediaPlayerPrivateWinCE_h +#define MediaPlayerPrivateWinCE_h #if ENABLE(VIDEO) @@ -120,6 +120,6 @@ namespace WebCore { } -#endif +#endif // ENABLE(VIDEO) -#endif +#endif // MediaPlayerPrivateWinCE_h diff --git a/WebCore/platform/graphics/wince/PathWince.cpp b/WebCore/platform/graphics/wince/PathWinCE.cpp index 6aa2864..4f0195c 100644 --- a/WebCore/platform/graphics/wince/PathWince.cpp +++ b/WebCore/platform/graphics/wince/PathWinCE.cpp @@ -23,7 +23,7 @@ #include "AffineTransform.h" #include "FloatRect.h" #include "NotImplemented.h" -#include "PlatformPathWince.h" +#include "PlatformPathWinCE.h" #include "PlatformString.h" #include <wtf/OwnPtr.h> diff --git a/WebCore/platform/graphics/wince/PlatformPathWince.cpp b/WebCore/platform/graphics/wince/PlatformPathWinCE.cpp index b42b52c..4072a18 100644 --- a/WebCore/platform/graphics/wince/PlatformPathWince.cpp +++ b/WebCore/platform/graphics/wince/PlatformPathWinCE.cpp @@ -18,14 +18,14 @@ */ #include "config.h" -#include "PlatformPathWince.h" +#include "PlatformPathWinCE.h" #include "AffineTransform.h" #include "FloatRect.h" #include "GraphicsContext.h" #include "Path.h" #include "PlatformString.h" -#include "WinceGraphicsExtras.h" +#include "WinCEGraphicsExtras.h" #include <wtf/MathExtras.h> #include <wtf/OwnPtr.h> @@ -33,7 +33,7 @@ namespace WebCore { -// Implemented in GraphicsContextWince.cpp +// Implemented in GraphicsContextWinCE.cpp void getEllipsePointByAngle(double angle, double a, double b, float& x, float& y); static void quadCurve(int segments, Vector<PathPoint>& pts, const PathPoint* control) diff --git a/WebCore/platform/graphics/wince/PlatformPathWince.h b/WebCore/platform/graphics/wince/PlatformPathWinCE.h index 614e8c5..3414b04 100644 --- a/WebCore/platform/graphics/wince/PlatformPathWince.h +++ b/WebCore/platform/graphics/wince/PlatformPathWinCE.h @@ -17,8 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef PlatformPathWince_h -#define PlatformPathWince_h +#ifndef PlatformPathWinCE_h +#define PlatformPathWinCE_h #include "FloatPoint.h" #include "FloatRect.h" @@ -180,4 +180,4 @@ namespace WebCore { } -#endif // PlatformPathWince_h +#endif // PlatformPathWinCE_h diff --git a/WebCore/platform/graphics/wince/SimpleFontDataWince.cpp b/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp index 6c815fc..c8c5474 100644 --- a/WebCore/platform/graphics/wince/SimpleFontDataWince.cpp +++ b/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp @@ -163,4 +163,4 @@ void SimpleFontData::platformCharWidthInit() m_maxCharWidth = (tm.tmMaxCharWidth * m_platformData.size() + 36) / 72; } -} +} // namespace WebCore diff --git a/WebCore/platform/graphics/wince/WinceGraphicsExtras.h b/WebCore/platform/graphics/wince/WinCEGraphicsExtras.h index 2a6fae1..4cab21c 100644 --- a/WebCore/platform/graphics/wince/WinceGraphicsExtras.h +++ b/WebCore/platform/graphics/wince/WinCEGraphicsExtras.h @@ -17,8 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef WinceGraphicsExtras_h -#define WinceGraphicsExtras_h +#ifndef WinCEGraphicsExtras_h +#define WinCEGraphicsExtras_h // This file is used to contain small utilities used by WINCE graphics code. @@ -36,4 +36,4 @@ namespace WebCore { } } -#endif WinceGraphicsExtras_h +#endif WinCEGraphicsExtras_h diff --git a/WebCore/platform/gtk/ClipboardGtk.cpp b/WebCore/platform/gtk/ClipboardGtk.cpp index 3fe5ba1..327f069 100644 --- a/WebCore/platform/gtk/ClipboardGtk.cpp +++ b/WebCore/platform/gtk/ClipboardGtk.cpp @@ -265,9 +265,8 @@ PassRefPtr<FileList> ClipboardGtk::files() const RefPtr<FileList> fileList = FileList::create(); Vector<String> fileVector(m_dataObject->files()); - ScriptExecutionContext* scriptExecutionContext = m_frame->document()->scriptExecutionContext(); for (size_t i = 0; i < fileVector.size(); i++) - fileList->append(File::create(scriptExecutionContext, fileVector[i])); + fileList->append(File::create(fileVector[i])); return fileList.release(); } diff --git a/WebCore/platform/gtk/DragImageGtk.cpp b/WebCore/platform/gtk/DragImageGtk.cpp index 4c77830..9d0d838 100644 --- a/WebCore/platform/gtk/DragImageGtk.cpp +++ b/WebCore/platform/gtk/DragImageGtk.cpp @@ -1,4 +1,6 @@ /* + * 2010 Igalia S.L + * * 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 @@ -19,15 +21,15 @@ #include "CachedImage.h" #include "Image.h" - -#include <gtk/gtk.h> +#include "PlatformRefPtrCairo.h" +#include <cairo.h> namespace WebCore { IntSize dragImageSize(DragImageRef image) { if (image) - return IntSize(gdk_pixbuf_get_width(image), gdk_pixbuf_get_height(image)); + return IntSize(cairo_image_surface_get_width(image), cairo_image_surface_get_height(image)); return IntSize(0, 0); } @@ -35,32 +37,45 @@ IntSize dragImageSize(DragImageRef image) void deleteDragImage(DragImageRef image) { if (image) - g_object_unref(image); + cairo_surface_destroy(image); } DragImageRef scaleDragImage(DragImageRef image, FloatSize scale) { - if (image) { - IntSize imageSize = dragImageSize(image); - GdkPixbuf* scaledImage = gdk_pixbuf_scale_simple(image, - imageSize.width() * scale.width(), - imageSize.height() * scale.height(), - GDK_INTERP_BILINEAR); - deleteDragImage(image); - return scaledImage; - } + if (!image) + return 0; - return 0; + int newWidth = scale.width() * cairo_image_surface_get_width(image); + int newHeight = scale.height() * cairo_image_surface_get_height(image); + cairo_surface_t* scaledSurface = cairo_surface_create_similar(image, CAIRO_CONTENT_COLOR_ALPHA, newWidth, newHeight); + + PlatformRefPtr<cairo_t> context = adoptPlatformRef(cairo_create(scaledSurface)); + cairo_scale(context.get(), scale.width(), scale.height()); + cairo_pattern_set_extend(cairo_get_source(context.get()), CAIRO_EXTEND_PAD); + cairo_pattern_set_filter(cairo_get_source(context.get()), CAIRO_FILTER_BEST); + cairo_set_operator(context.get(), CAIRO_OPERATOR_SOURCE); + cairo_set_source_surface(context.get(), image, 0, 0); + cairo_paint(context.get()); + + deleteDragImage(image); + return scaledSurface; } -DragImageRef dissolveDragImageToFraction(DragImageRef image, float) +DragImageRef dissolveDragImageToFraction(DragImageRef image, float fraction) { + if (!image) + return 0; + + PlatformRefPtr<cairo_t> context = adoptPlatformRef(cairo_create(image)); + cairo_set_operator(context.get(), CAIRO_OPERATOR_DEST_IN); + cairo_set_source_rgba(context.get(), 0, 0, 0, fraction); + cairo_paint(context.get()); return image; } DragImageRef createDragImageFromImage(Image* image) { - return image->getGdkPixbuf(); + return cairo_surface_reference(image->nativeImageForCurrentFrame()); } DragImageRef createDragImageIconForCachedImage(CachedImage*) diff --git a/WebCore/platform/gtk/GtkVersioning.h b/WebCore/platform/gtk/GtkVersioning.h index eac3cb5..867e14f 100644 --- a/WebCore/platform/gtk/GtkVersioning.h +++ b/WebCore/platform/gtk/GtkVersioning.h @@ -23,9 +23,17 @@ #include <gtk/gtk.h> +#ifndef GTK_API_VERSION_2 +#include <gdk/gdkkeysyms-compat.h> +#endif + G_BEGIN_DECLS // Macros to avoid deprecation checking churn +#ifndef GTK_API_VERSION_2 +#define GDK_DISPLAY() (GDK_DISPLAY_XDISPLAY(gdk_display_get_default())) +#endif + #if !GTK_CHECK_VERSION(2, 21, 2) #define gdk_visual_get_depth(visual) (visual)->depth #define gdk_visual_get_bits_per_rgb(visual) (visual)->bits_per_rgb @@ -34,6 +42,7 @@ G_BEGIN_DECLS #endif // GTK_CHECK_VERSION(2, 21, 2) #if !GTK_CHECK_VERSION(2, 20, 0) +#define gtk_widget_get_realized(widget) GTK_WIDGET_REALIZED(widget) #define gtk_widget_set_realized(widget, TRUE) GTK_WIDGET_SET_FLAGS((widget), GTK_REALIZED) #define gtk_range_get_min_slider_size(range) (range)->min_slider_size #endif // GTK_CHECK_VERSION(2, 20, 0) diff --git a/WebCore/platform/gtk/KeyEventGtk.cpp b/WebCore/platform/gtk/KeyEventGtk.cpp index f90647d..50dfa4c 100644 --- a/WebCore/platform/gtk/KeyEventGtk.cpp +++ b/WebCore/platform/gtk/KeyEventGtk.cpp @@ -30,6 +30,7 @@ #include "config.h" #include "PlatformKeyboardEvent.h" +#include "GtkVersioning.h" #include "NotImplemented.h" #include "TextEncoding.h" #include "WindowsKeyboardCodes.h" diff --git a/WebCore/platform/gtk/PopupMenuGtk.cpp b/WebCore/platform/gtk/PopupMenuGtk.cpp index ca067d9..d3e933d 100644 --- a/WebCore/platform/gtk/PopupMenuGtk.cpp +++ b/WebCore/platform/gtk/PopupMenuGtk.cpp @@ -87,7 +87,12 @@ void PopupMenuGtk::show(const IntRect& rect, FrameView* view, int index) // The size calls are directly copied from gtkcombobox.c which is LGPL GtkRequisition requisition; gtk_widget_set_size_request(GTK_WIDGET(m_popup.get()), -1, -1); +#ifdef GTK_API_VERSION_2 gtk_widget_size_request(GTK_WIDGET(m_popup.get()), &requisition); +#else + gtk_size_request_get_size(GTK_SIZE_REQUEST(m_popup.get()), &requisition, NULL); +#endif + gtk_widget_set_size_request(GTK_WIDGET(m_popup.get()), std::max(rect.width(), requisition.width), -1); GList* children = gtk_container_get_children(GTK_CONTAINER(m_popup.get())); @@ -99,7 +104,11 @@ void PopupMenuGtk::show(const IntRect& rect, FrameView* view, int index) GtkWidget* item = reinterpret_cast<GtkWidget*>(p->data); GtkRequisition itemRequisition; +#ifdef GTK_API_VERSION_2 gtk_widget_get_child_requisition(item, &itemRequisition); +#else + gtk_size_request_get_size(GTK_SIZE_REQUEST(item), &itemRequisition, NULL); +#endif m_menuPosition.setY(m_menuPosition.y() - itemRequisition.height); p = g_list_next(p); diff --git a/WebCore/platform/gtk/gtk2drawing.c b/WebCore/platform/gtk/gtk2drawing.c index ba69cdc..fd770d2 100644 --- a/WebCore/platform/gtk/gtk2drawing.c +++ b/WebCore/platform/gtk/gtk2drawing.c @@ -1265,7 +1265,9 @@ moz_gtk_scrollbar_thumb_paint(GtkThemeWidgetType widget, GtkStyle* style; GtkScrollbar *scrollbar; GtkAdjustment *adj; +#ifdef GTK_API_VERSION_2 gboolean activate_slider; +#endif ensure_scrollbar_widget(); @@ -1317,6 +1319,7 @@ moz_gtk_scrollbar_thumb_paint(GtkThemeWidgetType widget, style = gtk_widget_get_style(GTK_WIDGET(scrollbar)); +#ifdef GTK_API_VERSION_2 gtk_widget_style_get(GTK_WIDGET(scrollbar), "activate-slider", &activate_slider, NULL); @@ -1324,6 +1327,7 @@ moz_gtk_scrollbar_thumb_paint(GtkThemeWidgetType widget, shadow_type = GTK_SHADOW_IN; state_type = GTK_STATE_ACTIVE; } +#endif TSOffsetStyleGCs(style, rect->x, rect->y); @@ -1812,7 +1816,11 @@ moz_gtk_combo_box_paint(GdkDrawable* drawable, GdkRectangle* rect, rect, &arrow_rect, direction, ishtml); /* Now arrow_rect contains the inner rect ; we want to correct the width * to what the arrow needs (see gtk_combo_box_size_allocate) */ +#ifdef GTK_API_VERSION_2 gtk_widget_size_request(gParts->comboBoxArrowWidget, &arrow_req); +#else + gtk_size_request_get_size(GTK_SIZE_REQUEST(gParts->comboBoxArrowWidget), &arrow_req, NULL); +#endif if (direction == GTK_TEXT_DIR_LTR) arrow_rect.x += arrow_rect.width - arrow_req.width; arrow_rect.width = arrow_req.width; @@ -2783,8 +2791,11 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, XTHICKNESS(style); } +#ifdef GTK_API_VERSION_2 gtk_widget_size_request(gParts->comboBoxArrowWidget, &arrow_req); - +#else + gtk_size_request_get_size(GTK_SIZE_REQUEST(gParts->comboBoxArrowWidget), &arrow_req, NULL); +#endif if (direction == GTK_TEXT_DIR_RTL) *left += separator_width + arrow_req.width; else @@ -2948,7 +2959,12 @@ moz_gtk_get_combo_box_entry_button_size(gint* width, gint* height) GtkRequisition requisition; ensure_combo_box_entry_widgets(); +#ifdef GTK_API_VERSION_2 gtk_widget_size_request(gParts->comboBoxEntryButtonWidget, &requisition); +#else + gtk_size_request_get_size(GTK_SIZE_REQUEST(gParts->comboBoxEntryButtonWidget), &requisition, NULL); +#endif + *width = requisition.width; *height = requisition.height; @@ -2976,7 +2992,12 @@ moz_gtk_get_downarrow_size(gint* width, gint* height) GtkRequisition requisition; ensure_button_arrow_widget(); +#ifdef GTK_API_VERSION_2 gtk_widget_size_request(gParts->buttonArrowWidget, &requisition); +#else + gtk_size_request_get_size(GTK_SIZE_REQUEST(gParts->buttonArrowWidget), &requisition, NULL); +#endif + *width = requisition.width; *height = requisition.height; diff --git a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp index a2397ee..4d2a92d 100644 --- a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp +++ b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp @@ -197,8 +197,8 @@ bool GIFImageDecoder::haveDecodedRow(unsigned frameIndex, unsigned char* rowBuff // row's X-coordinates. int xBegin = upperBoundScaledX(frameReader->x_offset); int yBegin = upperBoundScaledY(frameReader->y_offset + rowNumber); - int xEnd = lowerBoundScaledX(std::min(xBegin + static_cast<int>(rowEnd - rowBuffer), size().width()) - 1, xBegin + 1) + 1; - int yEnd = lowerBoundScaledY(std::min(yBegin + static_cast<int>(repeatCount), size().height()) - 1, yBegin + 1) + 1; + int xEnd = lowerBoundScaledX(std::min(static_cast<int>(frameReader->x_offset + (rowEnd - rowBuffer)), size().width()) - 1, xBegin + 1) + 1; + int yEnd = lowerBoundScaledY(std::min(static_cast<int>(frameReader->y_offset + rowNumber + repeatCount), size().height()) - 1, yBegin + 1) + 1; if (!rowBuffer || (xBegin < 0) || (yBegin < 0) || (xEnd <= xBegin) || (yEnd <= yBegin)) return true; diff --git a/WebCore/platform/image-encoders/JPEGImageEncoder.cpp b/WebCore/platform/image-encoders/JPEGImageEncoder.cpp new file mode 100644 index 0000000..d707aa8 --- /dev/null +++ b/WebCore/platform/image-encoders/JPEGImageEncoder.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2009 Torch Mobile, Inc. All rights reserved. + * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. + * + * 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 "JPEGImageEncoder.h" + +#include "IntSize.h" +// FIXME: jpeglib.h requires stdio.h to be included first for FILE +#include <stdio.h> +#include "jpeglib.h" +#include <setjmp.h> + +namespace WebCore { + +class JPEGDestinationManager : public jpeg_destination_mgr { +public: + explicit JPEGDestinationManager(Vector<char>& toDump) + : m_dump(toDump) + { + // Zero base class memory. + jpeg_destination_mgr* base = this; + memset(base, 0, sizeof(jpeg_destination_mgr)); + } + Vector<char> m_buffer; + Vector<char>& m_dump; +}; + +class JPEGCompressErrorMgr : public jpeg_error_mgr { +public: + JPEGCompressErrorMgr() + { + // Zero memory + memset(this, 0, sizeof(JPEGCompressErrorMgr)); + } + + jmp_buf m_setjmpBuffer; +}; + +static void jpegInitializeDestination(j_compress_ptr compressData) +{ + JPEGDestinationManager* dest = static_cast<JPEGDestinationManager*>(compressData->dest); + dest->m_buffer.resize(4096); + dest->next_output_byte = reinterpret_cast<JOCTET*>(dest->m_buffer.data()); + dest->free_in_buffer = dest->m_buffer.size(); +} + +static boolean jpegEmptyOutputBuffer(j_compress_ptr compressData) +{ + JPEGDestinationManager* dest = static_cast<JPEGDestinationManager*>(compressData->dest); + dest->m_dump.append(dest->m_buffer.data(), dest->m_buffer.size() - dest->free_in_buffer); + dest->next_output_byte = reinterpret_cast<JOCTET*>(dest->m_buffer.data()); + dest->free_in_buffer = dest->m_buffer.size(); + return TRUE; +} + +static void jpegTerminateDestination(j_compress_ptr compressData) +{ + JPEGDestinationManager* dest = static_cast<JPEGDestinationManager*>(compressData->dest); + dest->m_dump.append(dest->m_buffer.data(), dest->m_buffer.size() - dest->free_in_buffer); +} + +static void jpegErrorExit(j_common_ptr compressData) +{ + JPEGCompressErrorMgr* err = static_cast<JPEGCompressErrorMgr*>(compressData->err); + longjmp(err->m_setjmpBuffer, -1); +} + +bool compressRGBABigEndianToJPEG(unsigned char* rgbaBigEndianData, const IntSize& size, Vector<char>& jpegData) +{ + struct jpeg_compress_struct compressData = { 0 }; + JPEGCompressErrorMgr err; + compressData.err = jpeg_std_error(&err); + err.error_exit = jpegErrorExit; + + jpeg_create_compress(&compressData); + + JPEGDestinationManager dest(jpegData); + compressData.dest = &dest; + dest.init_destination = jpegInitializeDestination; + dest.empty_output_buffer = jpegEmptyOutputBuffer; + dest.term_destination = jpegTerminateDestination; + + compressData.image_width = size.width(); + compressData.image_height = size.height(); + compressData.input_components = 3; + compressData.in_color_space = JCS_RGB; + jpeg_set_defaults(&compressData); + jpeg_set_quality(&compressData, 65, FALSE); + + // rowBuffer must be defined here so that its destructor is always called even when "setjmp" catches an error. + Vector<JSAMPLE, 600 * 3> rowBuffer; + + if (setjmp(err.m_setjmpBuffer)) + return false; + + jpeg_start_compress(&compressData, TRUE); + rowBuffer.resize(compressData.image_width * 3); + + const unsigned char* pixel = rgbaBigEndianData; + const unsigned char* pixelEnd = pixel + compressData.image_width * compressData.image_height * 4; + while (pixel < pixelEnd) { + JSAMPLE* output = rowBuffer.data(); + for (const unsigned char* rowEnd = pixel + compressData.image_width * 4; pixel < rowEnd;) { + *output++ = static_cast<JSAMPLE>(*pixel++ & 0xFF); // red + *output++ = static_cast<JSAMPLE>(*pixel++ & 0xFF); // green + *output++ = static_cast<JSAMPLE>(*pixel++ & 0xFF); // blue + ++pixel; // skip alpha + } + output = rowBuffer.data(); + jpeg_write_scanlines(&compressData, &output, 1); + } + + jpeg_finish_compress(&compressData); + return true; +} + +} // namespace WebCore diff --git a/WebCore/platform/image-encoders/JPEGImageEncoder.h b/WebCore/platform/image-encoders/JPEGImageEncoder.h new file mode 100644 index 0000000..a373c4f --- /dev/null +++ b/WebCore/platform/image-encoders/JPEGImageEncoder.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2009 Torch Mobile, Inc. All rights reserved. + * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. + * + * 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 JPEGImageEncoder_h +#define JPEGImageEncoder_h + +#include <wtf/Vector.h> + +namespace WebCore { + +class IntSize; +bool compressRGBABigEndianToJPEG(unsigned char* rgbaBigEndianData, const IntSize& size, Vector<char>& jpegData); + +} + +#endif // JPEGImageEncoder_h diff --git a/WebCore/platform/image-encoders/PNGImageEncoder.cpp b/WebCore/platform/image-encoders/PNGImageEncoder.cpp new file mode 100644 index 0000000..358d351 --- /dev/null +++ b/WebCore/platform/image-encoders/PNGImageEncoder.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2006-2009, Google Inc. All rights reserved. + * Copyright (c) 2009 Torch Mobile, Inc. All rights reserved. + * Copyright (C) Research In Motion Limited 2009-2010. 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 "PNGImageEncoder.h" + +#include "IntSize.h" +#include "png.h" +#include <wtf/Vector.h> + +namespace WebCore { + +// Encoder -------------------------------------------------------------------- +// +// This section of the code is based on nsPNGEncoder.cpp in Mozilla +// (Copyright 2005 Google Inc.) + +// Passed around as the io_ptr in the png structs so our callbacks know where +// to write data. +struct PNGEncoderState { + PNGEncoderState(Vector<char>* o) : m_dump(o) {} + Vector<char>* m_dump; +}; + +// Called by libpng to flush its internal buffer to ours. +void encoderWriteCallback(png_structp png, png_bytep data, png_size_t size) +{ + PNGEncoderState* state = static_cast<PNGEncoderState*>(png_get_io_ptr(png)); + ASSERT(state->m_dump); + + size_t oldSize = state->m_dump->size(); + state->m_dump->resize(oldSize + size); + char* destination = state->m_dump->data() + oldSize; + memcpy(destination, data, size); +} + +// Automatically destroys the given write structs on destruction to make +// cleanup and error handling code cleaner. +class PNGWriteStructDestroyer { +public: + PNGWriteStructDestroyer(png_struct** ps, png_info** pi) + : m_pngStruct(ps) + , m_pngInfo(pi) + { + } + + ~PNGWriteStructDestroyer() + { + png_destroy_write_struct(m_pngStruct, m_pngInfo); + } + +private: + png_struct** m_pngStruct; + png_info** m_pngInfo; +}; + +bool compressRGBABigEndianToPNG(unsigned char* rgbaBigEndianData, const IntSize& size, Vector<char>& pngData) +{ + png_struct* pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL, png_error_ptr_NULL, png_error_ptr_NULL); + if (!pngPtr) + return false; + + png_info* infoPtr = png_create_info_struct(pngPtr); + if (!infoPtr) { + png_destroy_write_struct(&pngPtr, 0); + return false; + } + PNGWriteStructDestroyer destroyer(&pngPtr, &infoPtr); + + // The destroyer will ensure that the structures are cleaned up in this + // case, even though we may get here as a jump from random parts of the + // PNG library called below. + if (setjmp(png_jmpbuf(pngPtr))) + return false; + + // Set our callback for libpng to give us the data. + PNGEncoderState state(&pngData); + png_set_write_fn(pngPtr, &state, encoderWriteCallback, 0); + + int pngOutputColorType = PNG_COLOR_TYPE_RGB_ALPHA; + + png_set_IHDR(pngPtr, infoPtr, size.width(), size.height(), 8, pngOutputColorType, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + png_write_info(pngPtr, infoPtr); + + unsigned bytesPerRow = size.width() * 4; + for (unsigned y = 0; y < size.height(); ++y) { + png_write_row(pngPtr, rgbaBigEndianData); + rgbaBigEndianData += bytesPerRow; + } + + png_write_end(pngPtr, infoPtr); + return true; +} + +} // namespace WebCore diff --git a/WebCore/platform/image-encoders/PNGImageEncoder.h b/WebCore/platform/image-encoders/PNGImageEncoder.h new file mode 100644 index 0000000..0c09086 --- /dev/null +++ b/WebCore/platform/image-encoders/PNGImageEncoder.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2007-2009 Torch Mobile, Inc. + * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. + * + * 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 PNGImageEncoder_h +#define PNGImageEncoder_h + +#include <wtf/Vector.h> + +namespace WebCore { + +class IntSize; +bool compressRGBABigEndianToPNG(unsigned char* rgbaBigEndianData, const IntSize& size, Vector<char>& pngData); + +} + +#endif // PNGImageEncoder_h diff --git a/WebCore/platform/mac/ClipboardMac.mm b/WebCore/platform/mac/ClipboardMac.mm index 0cbb3f6..74a93b6 100644 --- a/WebCore/platform/mac/ClipboardMac.mm +++ b/WebCore/platform/mac/ClipboardMac.mm @@ -313,12 +313,11 @@ PassRefPtr<FileList> ClipboardMac::files() const NSArray *absoluteURLs = absoluteURLsFromPasteboardFilenames(m_pasteboard.get()); NSUInteger count = [absoluteURLs count]; - ScriptExecutionContext* scriptExecutionContext = m_frame->document()->scriptExecutionContext(); RefPtr<FileList> fileList = FileList::create(); for (NSUInteger x = 0; x < count; x++) { NSURL *absoluteURL = [NSURL URLWithString:[absoluteURLs objectAtIndex:x]]; ASSERT([absoluteURL isFileURL]); - fileList->append(File::create(scriptExecutionContext, [absoluteURL path])); + fileList->append(File::create([absoluteURL path])); } return fileList.release(); // We will always return a FileList, sometimes empty } @@ -373,7 +372,7 @@ void ClipboardMac::writeRange(Range* range, Frame* frame) { ASSERT(range); ASSERT(frame); - Pasteboard::writeSelection(m_pasteboard.get(), range, frame->editor()->smartInsertDeleteEnabled() && frame->selectionGranularity() == WordGranularity, frame); + Pasteboard::writeSelection(m_pasteboard.get(), range, frame->editor()->smartInsertDeleteEnabled() && frame->selection()->granularity() == WordGranularity, frame); } void ClipboardMac::writePlainText(const String& text) diff --git a/WebCore/platform/mac/PasteboardMac.mm b/WebCore/platform/mac/PasteboardMac.mm index bba7cac..0625287 100644 --- a/WebCore/platform/mac/PasteboardMac.mm +++ b/WebCore/platform/mac/PasteboardMac.mm @@ -31,16 +31,22 @@ #import "DOMRangeInternal.h" #import "Document.h" #import "DocumentFragment.h" +#import "DocumentLoader.h" #import "Editor.h" #import "EditorClient.h" #import "Frame.h" +#import "FrameLoaderClient.h" #import "HitTestResult.h" +#import "HTMLAnchorElement.h" +#import "HTMLNames.h" #import "Image.h" #import "KURL.h" #import "LegacyWebArchive.h" #import "LoaderNSURLExtras.h" #import "MIMETypeRegistry.h" +#import "Page.h" #import "RenderImage.h" +#import "Text.h" #import "WebCoreNSStringExtras.h" #import "markup.h" @@ -139,7 +145,8 @@ void Pasteboard::writeSelection(NSPasteboard* pasteboard, Range* selectedRange, Pasteboard::generalPasteboard(); // Initializes pasteboard types. ASSERT(selectedRange); - NSAttributedString *attributedString = [[[NSAttributedString alloc] _initWithDOMRange:kit(selectedRange)] autorelease]; + NSAttributedString *attributedString = [[[NSAttributedString alloc] initWithString:selectedRange->text()] autorelease]; + #ifdef BUILDING_ON_TIGER // 4930197: Mail overrides [WebHTMLView pasteboardTypesForSelection] in order to add another type to the pasteboard // after WebKit does. On Tiger we must call this function so that Mail code will be executed, meaning that @@ -362,12 +369,124 @@ String Pasteboard::plainText(Frame* frame) return String(); } + +PassRefPtr<DocumentFragment> Pasteboard::documentFragmentWithImageResource(Frame* frame, PassRefPtr<ArchiveResource> resource) +{ + if (DocumentLoader* loader = frame->loader()->documentLoader()) + loader->addArchiveResource(resource.get()); + + RefPtr<Element> imageElement = frame->document()->createElement(HTMLNames::imgTag, false); + if (!imageElement) + return 0; + + NSURL *URL = resource->url(); + imageElement->setAttribute(HTMLNames::srcAttr, [URL isFileURL] ? [URL absoluteString] : resource->url()); + RefPtr<DocumentFragment> fragment = frame->document()->createDocumentFragment(); + if (fragment) { + ExceptionCode ec; + fragment->appendChild(imageElement, ec); + return fragment.release(); + } + return 0; +} + +PassRefPtr<DocumentFragment> Pasteboard::documentFragmentWithRtf(Frame* frame, NSString* pboardType) +{ + if (!frame || !frame->document() || !frame->document()->isHTMLDocument()) + return 0; + + NSAttributedString *string = nil; + if (pboardType == NSRTFDPboardType) + string = [[NSAttributedString alloc] initWithRTFD:[m_pasteboard.get() dataForType:NSRTFDPboardType] documentAttributes:NULL]; + if (string == nil) + string = [[NSAttributedString alloc] initWithRTF:[m_pasteboard.get() dataForType:NSRTFPboardType] documentAttributes:NULL]; + if (string == nil) + return nil; + + bool wasDeferringCallbacks = frame->page()->defersLoading(); + if (!wasDeferringCallbacks) + frame->page()->setDefersLoading(true); + + Vector<RefPtr<ArchiveResource> > resources; + RefPtr<DocumentFragment> fragment = frame->editor()->client()->documentFragmentFromAttributedString(string, resources); + + size_t size = resources.size(); + if (size) { + DocumentLoader* loader = frame->loader()->documentLoader(); + for (size_t i = 0; i < size; ++i) + loader->addArchiveResource(resources[i]); + } + + if (!wasDeferringCallbacks) + frame->page()->setDefersLoading(false); + + [string release]; + return fragment.release(); +} + +#define WebDataProtocolScheme @"webkit-fake-url" + +static NSURL* uniqueURLWithRelativePart(NSString *relativePart) +{ + CFUUIDRef UUIDRef = CFUUIDCreate(kCFAllocatorDefault); + NSString *UUIDString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, UUIDRef); + CFRelease(UUIDRef); + NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@/%@", WebDataProtocolScheme, UUIDString, relativePart]]; + CFRelease(UUIDString); + return URL; +} + PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefPtr<Range> context, bool allowPlainText, bool& chosePlainText) { NSArray *types = [m_pasteboard.get() types]; + RefPtr<DocumentFragment> fragment; chosePlainText = false; + if ([types containsObject:WebArchivePboardType]) { + RefPtr<LegacyWebArchive> coreArchive = LegacyWebArchive::create(SharedBuffer::wrapNSData([m_pasteboard.get() dataForType:WebArchivePboardType]).get()); + if (coreArchive) { + RefPtr<ArchiveResource> mainResource = coreArchive->mainResource(); + if (mainResource) { + NSString *MIMEType = mainResource->mimeType(); + if (!frame || !frame->document()) + return 0; + if (frame->loader()->client()->canShowMIMETypeAsHTML(MIMEType)) { + NSString *markupString = [[NSString alloc] initWithData:[mainResource->data()->createNSData() autorelease] encoding:NSUTF8StringEncoding]; + // FIXME: seems poor form to do this as a side effect of getting a document fragment + if (DocumentLoader* loader = frame->loader()->documentLoader()) + loader->addAllArchiveResources(coreArchive.get()); + + fragment = createFragmentFromMarkup(frame->document(), markupString, mainResource->url(), FragmentScriptingNotAllowed); + [markupString release]; + } else if (MIMETypeRegistry::isSupportedImageMIMEType(MIMEType)) + fragment = documentFragmentWithImageResource(frame, mainResource); + } + } + if (fragment) + return fragment.release(); + } + + if ([types containsObject:NSFilenamesPboardType]) { + NSArray* paths = [m_pasteboard.get() propertyListForType:NSFilenamesPboardType]; + NSEnumerator* enumerator = [paths objectEnumerator]; + NSString* path; + Vector< RefPtr<Node> > refNodesVector; + Vector<Node*> nodesVector; + + while ((path = [enumerator nextObject]) != nil) { + // Non-image file types; _web_userVisibleString is appropriate here because this will + // be pasted as visible text. + NSString *url = frame->editor()->client()->userVisibleString([NSURL fileURLWithPath:path]); + RefPtr<Node> textNode = frame->document()->createTextNode(url); + refNodesVector.append(textNode.get()); + nodesVector.append(textNode.get()); + } + fragment = createFragmentFromNodes(frame->document(), nodesVector); + if (fragment && fragment->firstChild()) + return fragment.release(); + } + if ([types containsObject:NSHTMLPboardType]) { NSString *HTMLString = [m_pasteboard.get() stringForType:NSHTMLPboardType]; // This is a hack to make Microsoft's HTML pasteboard data work. See 3778785. @@ -377,24 +496,66 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP HTMLString = [HTMLString substringFromIndex:range.location]; } } - if ([HTMLString length] != 0) { - // FIXME: FragmentScriptingNotAllowed is a HACK and should - // be removed or replaced with an enum with a better name. - // FragmentScriptingNotAllowed causes the Parser to remove children - // of <script> tags (so javascript doesn't show up in pastes). - RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), HTMLString, "", FragmentScriptingNotAllowed); - if (fragment) - return fragment.release(); + if ([HTMLString length] != 0 && + (fragment = createFragmentFromMarkup(frame->document(), HTMLString, "", FragmentScriptingNotAllowed))) + return fragment.release(); + } + + if ([types containsObject:NSRTFDPboardType] && + (fragment = documentFragmentWithRtf(frame, NSRTFDPboardType))) + return fragment.release(); + + if ([types containsObject:NSRTFPboardType] && + (fragment = documentFragmentWithRtf(frame, NSRTFPboardType))) + return fragment.release(); + + if ([types containsObject:NSTIFFPboardType] && + (fragment = documentFragmentWithImageResource(frame, ArchiveResource::create(SharedBuffer::wrapNSData([[[m_pasteboard.get() dataForType:NSTIFFPboardType] copy] autorelease]), uniqueURLWithRelativePart(@"image.tiff"), "image/tiff", "", "")))) + return fragment.release(); + + if ([types containsObject:NSPDFPboardType] && + (fragment = documentFragmentWithImageResource(frame, ArchiveResource::create(SharedBuffer::wrapNSData([[[m_pasteboard.get() dataForType:NSPDFPboardType] copy] autorelease]), uniqueURLWithRelativePart(@"application.pdf"), "application/pdf", "", "")))) + return fragment.release(); + +#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) + if ([types containsObject:NSPICTPboardType] && + (fragment = documentFragmentWithImageResource(frame, ArchiveResource::create(SharedBuffer::wrapNSData([[[m_pasteboard.get() dataForType:NSPICTPboardType] copy] autorelease]), uniqueURLWithRelativePart(@"image.pict"), "image/pict", "", "")))) + return fragment.release(); +#endif + + // Only 10.5 and higher support setting and retrieving pasteboard types with UTIs, but we don't believe + // that any applications on Tiger put types for which we only have a UTI, like PNG, on the pasteboard. + if ([types containsObject:(NSString*)kUTTypePNG] && + (fragment = documentFragmentWithImageResource(frame, ArchiveResource::create(SharedBuffer::wrapNSData([[[m_pasteboard.get() dataForType:(NSString*)kUTTypePNG] copy] autorelease]), uniqueURLWithRelativePart(@"image.png"), "image/png", "", "")))) + return fragment.release(); + + if ([types containsObject:NSURLPboardType]) { + NSURL *URL = [NSURL URLFromPasteboard:m_pasteboard.get()]; + Document* document = frame->document(); + ASSERT(document); + if (!document) + return 0; + RefPtr<Element> anchor = document->createElement(HTMLNames::aTag, false); + NSString *URLString = [URL absoluteString]; // Original data is ASCII-only, so there is no need to precompose. + if ([URLString length] == 0) + return nil; + NSString *URLTitleString = [[m_pasteboard.get() stringForType:WebURLNamePboardType] precomposedStringWithCanonicalMapping]; + ExceptionCode ec; + anchor->setAttribute(HTMLNames::hrefAttr, URLString); + anchor->appendChild(document->createTextNode(URLTitleString), ec); + fragment = document->createDocumentFragment(); + if (fragment) { + fragment->appendChild(anchor, ec); + return fragment.release(); } } - + if (allowPlainText && [types containsObject:NSStringPboardType]) { chosePlainText = true; - RefPtr<DocumentFragment> fragment = createFragmentFromText(context.get(), [[m_pasteboard.get() stringForType:NSStringPboardType] precomposedStringWithCanonicalMapping]); - if (fragment) - return fragment.release(); + fragment = createFragmentFromText(context.get(), [[m_pasteboard.get() stringForType:NSStringPboardType] precomposedStringWithCanonicalMapping]); + return fragment.release(); } - + return 0; } diff --git a/WebCore/platform/network/BlobResourceHandle.cpp b/WebCore/platform/network/BlobResourceHandle.cpp index 8767b55..48ac2c0 100644 --- a/WebCore/platform/network/BlobResourceHandle.cpp +++ b/WebCore/platform/network/BlobResourceHandle.cpp @@ -80,7 +80,7 @@ public: virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); virtual void didReceiveData(ResourceHandle*, const char*, int, int /*lengthReceived*/); - virtual void didFinishLoading(ResourceHandle*); + virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/); virtual void didFail(ResourceHandle*, const ResourceError&); private: @@ -116,7 +116,7 @@ void BlobResourceSynchronousLoader::didReceiveData(ResourceHandle*, const char*, { } -void BlobResourceSynchronousLoader::didFinishLoading(ResourceHandle*) +void BlobResourceSynchronousLoader::didFinishLoading(ResourceHandle*, double) { } @@ -581,7 +581,7 @@ void BlobResourceHandle::notifyFail(int errorCode) void BlobResourceHandle::notifyFinish() { if (client()) - client()->didFinishLoading(this); + client()->didFinishLoading(this, 0); } } // namespace WebCore diff --git a/WebCore/platform/network/NetworkingContext.h b/WebCore/platform/network/NetworkingContext.h index 31f3025..a7d40dc 100644 --- a/WebCore/platform/network/NetworkingContext.h +++ b/WebCore/platform/network/NetworkingContext.h @@ -57,6 +57,7 @@ public: #if PLATFORM(WIN) virtual String userAgent() const = 0; virtual String referrer() const = 0; + virtual ResourceError blockedError(const ResourceRequest&) const = 0; #endif protected: diff --git a/WebCore/platform/network/ResourceHandle.cpp b/WebCore/platform/network/ResourceHandle.cpp index 2da1d77..9910ac1 100644 --- a/WebCore/platform/network/ResourceHandle.cpp +++ b/WebCore/platform/network/ResourceHandle.cpp @@ -52,8 +52,7 @@ ResourceHandle::ResourceHandle(const ResourceRequest& request, ResourceHandleCli } } -PassRefPtr<ResourceHandle> ResourceHandle::create(const ResourceRequest& request, ResourceHandleClient* client, - Frame* frame, bool defersLoading, bool shouldContentSniff) +PassRefPtr<ResourceHandle> ResourceHandle::create(NetworkingContext* context, const ResourceRequest& request, ResourceHandleClient* client, bool defersLoading, bool shouldContentSniff) { #if ENABLE(BLOB) if (request.url().protocolIs("blob")) { @@ -68,7 +67,7 @@ PassRefPtr<ResourceHandle> ResourceHandle::create(const ResourceRequest& request if (newHandle->d->m_scheduledFailureType != NoFailure) return newHandle.release(); - if (newHandle->start(frame)) + if (newHandle->start(context)) return newHandle.release(); return 0; diff --git a/WebCore/platform/network/ResourceHandle.h b/WebCore/platform/network/ResourceHandle.h index 1167715..1cb9ee0 100644 --- a/WebCore/platform/network/ResourceHandle.h +++ b/WebCore/platform/network/ResourceHandle.h @@ -29,6 +29,7 @@ #include "AuthenticationChallenge.h" #include "AuthenticationClient.h" #include "HTTPHeaderMap.h" +#include "NetworkingContext.h" #include "ThreadableLoader.h" #include <wtf/OwnPtr.h> @@ -109,9 +110,8 @@ private: }; public: - // FIXME: should not need the Frame - static PassRefPtr<ResourceHandle> create(const ResourceRequest&, ResourceHandleClient*, Frame*, bool defersLoading, bool shouldContentSniff); - static void loadResourceSynchronously(const ResourceRequest&, StoredCredentials, ResourceError&, ResourceResponse&, Vector<char>& data, Frame* frame); + static PassRefPtr<ResourceHandle> create(NetworkingContext*, const ResourceRequest&, ResourceHandleClient*, bool defersLoading, bool shouldContentSniff); + static void loadResourceSynchronously(NetworkingContext*, const ResourceRequest&, StoredCredentials, ResourceError&, ResourceResponse&, Vector<char>& data); static void prepareForURL(const KURL&); static bool willLoadFromCache(ResourceRequest&, Frame*); @@ -216,7 +216,7 @@ private: void scheduleFailure(FailureType); - bool start(Frame*); + bool start(NetworkingContext*); virtual void refAuthenticationClient() { ref(); } virtual void derefAuthenticationClient() { deref(); } diff --git a/WebCore/platform/network/ResourceHandleClient.h b/WebCore/platform/network/ResourceHandleClient.h index 97c0f54..d9350ee 100644 --- a/WebCore/platform/network/ResourceHandleClient.h +++ b/WebCore/platform/network/ResourceHandleClient.h @@ -26,6 +26,7 @@ #ifndef ResourceHandleClient_h #define ResourceHandleClient_h +#include <wtf/CurrentTime.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> @@ -72,7 +73,7 @@ namespace WebCore { virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&) { } virtual void didReceiveData(ResourceHandle*, const char*, int, int /*lengthReceived*/) { } virtual void didReceiveCachedMetadata(ResourceHandle*, const char*, int) { } - virtual void didFinishLoading(ResourceHandle*) { } + virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/) { } virtual void didFail(ResourceHandle*, const ResourceError&) { } virtual void wasBlocked(ResourceHandle*) { } virtual void cannotShowURL(ResourceHandle*) { } diff --git a/WebCore/platform/network/ResourceHandleInternal.h b/WebCore/platform/network/ResourceHandleInternal.h index 24b00bf..7b6db90 100644 --- a/WebCore/platform/network/ResourceHandleInternal.h +++ b/WebCore/platform/network/ResourceHandleInternal.h @@ -51,7 +51,6 @@ class Frame; #endif #if PLATFORM(QT) -class QWebFrame; class QWebNetworkJob; namespace WebCore { class QNetworkReplyHandler; @@ -121,11 +120,9 @@ namespace WebCore { , m_bufferSize(0) , m_total(0) , m_idleHandler(0) - , m_frame(0) #endif #if PLATFORM(QT) , m_job(0) - , m_frame(0) #endif #if PLATFORM(MAC) , m_startWhenScheduled(false) @@ -202,11 +199,11 @@ namespace WebCore { char* m_buffer; gsize m_bufferSize, m_total; guint m_idleHandler; - Frame* m_frame; + RefPtr<NetworkingContext> m_context; #endif #if PLATFORM(QT) QNetworkReplyHandler* m_job; - QWebFrame* m_frame; + RefPtr<NetworkingContext> m_context; #endif #if PLATFORM(MAC) diff --git a/WebCore/platform/network/cf/ResourceHandleCFNet.cpp b/WebCore/platform/network/cf/ResourceHandleCFNet.cpp index 209906e..13412c1 100644 --- a/WebCore/platform/network/cf/ResourceHandleCFNet.cpp +++ b/WebCore/platform/network/cf/ResourceHandleCFNet.cpp @@ -92,7 +92,7 @@ private: virtual void didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge&); virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); virtual void didReceiveData(ResourceHandle*, const char*, int, int /*lengthReceived*/); - virtual void didFinishLoading(ResourceHandle*); + virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/); virtual void didFail(ResourceHandle*, const ResourceError&); bool m_allowStoredCredentials; @@ -241,7 +241,7 @@ void didFinishLoading(CFURLConnectionRef conn, const void* clientInfo) LOG(Network, "CFNet - didFinishLoading(conn=%p, handle=%p) (%s)", conn, handle, handle->firstRequest().url().string().utf8().data()); if (handle->client()) - handle->client()->didFinishLoading(handle); + handle->client()->didFinishLoading(handle, 0); } void didFail(CFURLConnectionRef conn, CFErrorRef error, const void* clientInfo) @@ -432,11 +432,14 @@ void ResourceHandle::createCFURLConnection(bool shouldUseCredentialStorage, bool d->m_connection.adoptCF(CFURLConnectionCreateWithProperties(0, request.get(), reinterpret_cast<CFURLConnectionClient*>(&client), connectionProperties.get())); } -bool ResourceHandle::start(Frame* frame) +bool ResourceHandle::start(NetworkingContext* context) { - // If we are no longer attached to a Page, this must be an attempted load from an - // onUnload handler, so let's just block it. - if (!frame->page()) + if (!context) + return false; + + // If NetworkingContext is invalid then we are no longer attached to a Page, + // this must be an attempted load from an unload handler, so let's just block it. + if (!context->isValid()) return false; bool shouldUseCredentialStorage = !client() || client()->shouldUseCredentialStorage(this); @@ -615,7 +618,7 @@ CFURLConnectionRef ResourceHandle::releaseConnectionForDownload() return d->m_connection.releaseRef(); } -void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& vector, Frame* frame) +void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& vector) { LOG(Network, "ResourceHandle::loadResourceSynchronously:%s allowStoredCredentials:%u", request.url().string().utf8().data(), storedCredentials); @@ -629,8 +632,8 @@ void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, S RefPtr<ResourceHandle> handle = adoptRef(new ResourceHandle(request, client.get(), false /*defersLoading*/, true /*shouldContentSniff*/)); - if (handle->d->m_scheduledFailureType != NoFailure) { - error = frame->loader()->blockedError(request); + if (context && handle->d->m_scheduledFailureType != NoFailure) { + error = context->blockedError(request); return; } @@ -738,7 +741,7 @@ void WebCoreSynchronousLoaderClient::didReceiveData(ResourceHandle*, const char* CFDataAppendBytes(m_data.get(), reinterpret_cast<const UInt8*>(data), length); } -void WebCoreSynchronousLoaderClient::didFinishLoading(ResourceHandle*) +void WebCoreSynchronousLoaderClient::didFinishLoading(ResourceHandle*, double) { m_isDone = true; } diff --git a/WebCore/platform/network/curl/ResourceHandleCurl.cpp b/WebCore/platform/network/curl/ResourceHandleCurl.cpp index 096905d..052ac56 100644 --- a/WebCore/platform/network/curl/ResourceHandleCurl.cpp +++ b/WebCore/platform/network/curl/ResourceHandleCurl.cpp @@ -47,7 +47,7 @@ public: virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived); - virtual void didFinishLoading(ResourceHandle*); + virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/); virtual void didFail(ResourceHandle*, const ResourceError&); ResourceResponse resourceResponse() const { return m_response; } @@ -74,7 +74,7 @@ void WebCoreSynchronousLoader::didReceiveData(ResourceHandle*, const char* data, m_data.append(data, length); } -void WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*) +void WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*, double) { } @@ -103,13 +103,14 @@ ResourceHandle::~ResourceHandle() cancel(); } -bool ResourceHandle::start(Frame* frame) +bool ResourceHandle::start(NetworkingContext* context) { // The frame could be null if the ResourceHandle is not associated to any // Frame, e.g. if we are downloading a file. // If the frame is not null but the page is null this must be an attempted - // load from an onUnload handler, so let's just block it. - if (frame && !frame->page()) + // load from an unload handler, so let's just block it. + // If both the frame and the page are not null the context is valid. + if (context && !context->isValid()) return false; ResourceHandleManager::sharedInstance()->add(this); @@ -187,7 +188,7 @@ bool ResourceHandle::loadsBlocked() return false; } -void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& data, Frame*) +void ResourceHandle::loadResourceSynchronously(NetworkingContext*, const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& data) { WebCoreSynchronousLoader syncLoader; RefPtr<ResourceHandle> handle = adoptRef(new ResourceHandle(request, &syncLoader, true, false)); diff --git a/WebCore/platform/network/curl/ResourceHandleManager.cpp b/WebCore/platform/network/curl/ResourceHandleManager.cpp index 8d2a1bf..a4d71e0 100644 --- a/WebCore/platform/network/curl/ResourceHandleManager.cpp +++ b/WebCore/platform/network/curl/ResourceHandleManager.cpp @@ -397,7 +397,7 @@ void ResourceHandleManager::downloadTimerCallback(Timer<ResourceHandleManager>* } if (d->client()) - d->client()->didFinishLoading(job); + d->client()->didFinishLoading(job, 0); } else { char* url = 0; curl_easy_getinfo(d->m_handle, CURLINFO_EFFECTIVE_URL, &url); @@ -624,7 +624,7 @@ static void parseDataUrl(ResourceHandle* handle) client->didReceiveData(handle, reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), 0); } - client->didFinishLoading(handle); + client->didFinishLoading(handle, 0); } void ResourceHandleManager::dispatchSynchronousJob(ResourceHandle* job) diff --git a/WebCore/platform/network/mac/ResourceHandleMac.mm b/WebCore/platform/network/mac/ResourceHandleMac.mm index 0af86d0..daec366 100644 --- a/WebCore/platform/network/mac/ResourceHandleMac.mm +++ b/WebCore/platform/network/mac/ResourceHandleMac.mm @@ -115,7 +115,7 @@ private: virtual void didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge&); virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); virtual void didReceiveData(ResourceHandle*, const char*, int, int /*lengthReceived*/); - virtual void didFinishLoading(ResourceHandle*); + virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/); virtual void didFail(ResourceHandle*, const ResourceError&); #if USE(PROTECTION_SPACE_AUTH_CALLBACK) virtual bool canAuthenticateAgainstProtectionSpace(ResourceHandle*, const ProtectionSpace&); @@ -260,17 +260,16 @@ void ResourceHandle::createNSURLConnection(id delegate, bool shouldUseCredential #endif } -bool ResourceHandle::start(Frame* frame) +bool ResourceHandle::start(NetworkingContext* context) { - if (!frame) + if (!context) return false; BEGIN_BLOCK_OBJC_EXCEPTIONS; - // If we are no longer attached to a Page, this must be an attempted load from an - // onUnload handler, so let's just block it. - Page* page = frame->page(); - if (!page) + // If NetworkingContext is invalid then we are no longer attached to a Page, + // this must be an attempted load from an unload event handler, so let's just block it. + if (!context->isValid()) return false; #ifndef NDEBUG @@ -293,16 +292,16 @@ bool ResourceHandle::start(Frame* frame) firstRequest().setCachePolicy(ReloadIgnoringCacheData); #endif - d->m_needsSiteSpecificQuirks = frame->settings() && frame->settings()->needsSiteSpecificQuirks(); + d->m_needsSiteSpecificQuirks = context->needsSiteSpecificQuirks(); createNSURLConnection( d->m_proxy.get(), shouldUseCredentialStorage, - d->m_shouldContentSniff || frame->settings()->localFileContentSniffingEnabled()); + d->m_shouldContentSniff || context->localFileContentSniffingEnabled()); #ifndef BUILDING_ON_TIGER bool scheduled = false; - if (SchedulePairHashSet* scheduledPairs = page->scheduledRunLoopPairs()) { + if (SchedulePairHashSet* scheduledPairs = context->scheduledRunLoopPairs()) { SchedulePairHashSet::iterator end = scheduledPairs->end(); for (SchedulePairHashSet::iterator it = scheduledPairs->begin(); it != end; ++it) { if (NSRunLoop *runLoop = (*it)->nsRunLoop()) { @@ -461,7 +460,7 @@ bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame*) #endif } -void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& data, Frame* frame) +void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& data) { LOG(Network, "ResourceHandle::loadResourceSynchronously:%@ allowStoredCredentials:%u", request.nsURLRequest(), storedCredentials); @@ -483,15 +482,15 @@ void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, S RefPtr<ResourceHandle> handle = adoptRef(new ResourceHandle(request, client.get(), false /*defersLoading*/, true /*shouldContentSniff*/)); - if (handle->d->m_scheduledFailureType != NoFailure) { - error = frame->loader()->blockedError(request); + if (context && handle->d->m_scheduledFailureType != NoFailure) { + error = context->blockedError(request); return; } handle->createNSURLConnection( handle->delegate(), // A synchronous request cannot turn into a download, so there is no need to proxy the delegate. storedCredentials == AllowStoredCredentials, - handle->shouldContentSniff() || frame->settings()->localFileContentSniffingEnabled()); + handle->shouldContentSniff() || (context && context->localFileContentSniffingEnabled())); [handle->connection() scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:WebCoreSynchronousLoaderRunLoopMode]; [handle->connection() start]; @@ -507,7 +506,7 @@ void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, S #else UNUSED_PARAM(storedCredentials); - UNUSED_PARAM(frame); + UNUSED_PARAM(context); NSURLRequest *firstRequest = request.nsURLRequest(); // If a URL already has cookies, then we'll relax the 3rd party cookie policy and accept new cookies. @@ -918,7 +917,7 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen if (!ResourceHandle::didSendBodyDataDelegateExists()) disassociateStreamWithResourceHandle([m_handle->firstRequest().nsURLRequest() HTTPBodyStream]); - m_handle->client()->didFinishLoading(m_handle); + m_handle->client()->didFinishLoading(m_handle, 0); } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error @@ -1060,7 +1059,7 @@ void WebCoreSynchronousLoaderClient::didReceiveData(ResourceHandle*, const char* [m_data appendBytes:data length:length]; } -void WebCoreSynchronousLoaderClient::didFinishLoading(ResourceHandle*) +void WebCoreSynchronousLoaderClient::didFinishLoading(ResourceHandle*, double) { m_isDone = true; } diff --git a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp index 915dc9a..30f7011 100644 --- a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp +++ b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp @@ -34,6 +34,7 @@ #include <QNetworkCookie> #include <qwebframe.h> #include <qwebpage.h> + #include <wtf/text/CString.h> #include <QDebug> @@ -171,7 +172,11 @@ QNetworkReplyHandler::QNetworkReplyHandler(ResourceHandle* handle, LoadMode load else m_method = QNetworkAccessManager::UnknownOperation; - m_request = r.toNetworkRequest(m_resourceHandle->getInternal()->m_frame); + QObject* originatingObject = 0; + if (m_resourceHandle->getInternal()->m_context) + originatingObject = m_resourceHandle->getInternal()->m_context->originatingObject(); + + m_request = r.toNetworkRequest(originatingObject); if (m_loadMode == LoadNormal) start(); @@ -258,7 +263,7 @@ void QNetworkReplyHandler::finish() resetState(); start(); } else if (!m_reply->error() || ignoreHttpError(m_reply, m_responseDataSent)) { - client->didFinishLoading(m_resourceHandle); + client->didFinishLoading(m_resourceHandle, 0); } else { QUrl url = m_reply->url(); int httpStatusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); @@ -300,12 +305,7 @@ void QNetworkReplyHandler::sendResponseIfNeeded() if (mimeType.isEmpty()) { // let's try to guess from the extension - QString extension = m_reply->url().path(); - int index = extension.lastIndexOf(QLatin1Char('.')); - if (index > 0) { - extension = extension.mid(index + 1); - mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension); - } + mimeType = MIMETypeRegistry::getMIMETypeForPath(m_reply->url().path()); } KURL url(m_reply->url()); @@ -374,7 +374,11 @@ void QNetworkReplyHandler::sendResponseIfNeeded() if (!m_resourceHandle) // network error did cancel the request return; - m_request = newRequest.toNetworkRequest(m_resourceHandle->getInternal()->m_frame); + QObject* originatingObject = 0; + if (m_resourceHandle->getInternal()->m_context) + originatingObject = m_resourceHandle->getInternal()->m_context->originatingObject(); + + m_request = newRequest.toNetworkRequest(originatingObject); return; } @@ -426,7 +430,12 @@ void QNetworkReplyHandler::start() ResourceHandleInternal* d = m_resourceHandle->getInternal(); - QNetworkAccessManager* manager = d->m_frame->page()->networkAccessManager(); + QNetworkAccessManager* manager = 0; + if (d->m_context) + manager = d->m_context->networkAccessManager(); + + if (!manager) + return; const QUrl url = m_request.url(); const QString scheme = url.scheme(); diff --git a/WebCore/platform/network/qt/ResourceHandleQt.cpp b/WebCore/platform/network/qt/ResourceHandleQt.cpp index 3548467..a5ac4c3 100644 --- a/WebCore/platform/network/qt/ResourceHandleQt.cpp +++ b/WebCore/platform/network/qt/ResourceHandleQt.cpp @@ -33,6 +33,7 @@ #include "ChromeClientQt.h" #include "CachedResourceLoader.h" #include "Frame.h" +#include "FrameNetworkingContext.h" #include "FrameLoaderClientQt.h" #include "NotImplemented.h" #include "Page.h" @@ -61,7 +62,7 @@ public: virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived); - virtual void didFinishLoading(ResourceHandle*); + virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/); virtual void didFail(ResourceHandle*, const ResourceError&); ResourceResponse resourceResponse() const { return m_response; } @@ -89,7 +90,7 @@ void WebCoreSynchronousLoader::didReceiveData(ResourceHandle*, const char* data, m_data.append(data, length); } -void WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*) +void WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*, double) { m_eventLoop.exit(); } @@ -115,15 +116,11 @@ ResourceHandle::~ResourceHandle() cancel(); } -bool ResourceHandle::start(Frame* frame) +bool ResourceHandle::start(NetworkingContext* context) { - if (!frame) - return false; - - Page *page = frame->page(); - // If we are no longer attached to a Page, this must be an attempted load from an - // onUnload handler, so let's just block it. - if (!page) + // If NetworkingContext is invalid then we are no longer attached to a Page, + // this must be an attempted load from an unload event handler, so let's just block it. + if (context && !context->isValid()) return false; if (!(d->m_user.isEmpty() || d->m_pass.isEmpty())) { @@ -135,7 +132,7 @@ bool ResourceHandle::start(Frame* frame) d->m_firstRequest.setURL(urlWithCredentials); } - getInternal()->m_frame = static_cast<FrameLoaderClientQt*>(frame->loader()->client())->webFrame(); + getInternal()->m_context = context; ResourceHandleInternal *d = getInternal(); d->m_job = new QNetworkReplyHandler(this, QNetworkReplyHandler::LoadMode(d->m_defersLoading)); return true; @@ -159,8 +156,12 @@ bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame* frame) if (!frame) return false; - QNetworkAccessManager* manager = QWebFramePrivate::kit(frame)->page()->networkAccessManager(); - QAbstractNetworkCache* cache = manager->cache(); + QNetworkAccessManager* manager = 0; + QAbstractNetworkCache* cache = 0; + if (frame->loader()->networkingContext()) { + manager = frame->loader()->networkingContext()->networkAccessManager(); + cache = manager->cache(); + } if (!cache) return false; @@ -185,7 +186,7 @@ PassRefPtr<SharedBuffer> ResourceHandle::bufferedData() return 0; } -void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, StoredCredentials /*storedCredentials*/, ResourceError& error, ResourceResponse& response, Vector<char>& data, Frame* frame) +void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const ResourceRequest& request, StoredCredentials /*storedCredentials*/, ResourceError& error, ResourceResponse& response, Vector<char>& data) { WebCoreSynchronousLoader syncLoader; RefPtr<ResourceHandle> handle = adoptRef(new ResourceHandle(request, &syncLoader, true, false)); @@ -199,7 +200,7 @@ void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, S urlWithCredentials.setPass(d->m_pass); d->m_firstRequest.setURL(urlWithCredentials); } - d->m_frame = static_cast<FrameLoaderClientQt*>(frame->loader()->client())->webFrame(); + d->m_context = context; d->m_job = new QNetworkReplyHandler(handle.get(), QNetworkReplyHandler::LoadNormal); syncLoader.waitForCompletion(); @@ -208,7 +209,6 @@ void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, S response = syncLoader.resourceResponse(); } - void ResourceHandle::platformSetDefersLoading(bool defers) { if (d->m_job) diff --git a/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/WebCore/platform/network/soup/ResourceHandleSoup.cpp index dadbd22..0009e36 100644 --- a/WebCore/platform/network/soup/ResourceHandleSoup.cpp +++ b/WebCore/platform/network/soup/ResourceHandleSoup.cpp @@ -65,7 +65,7 @@ public: virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived); - virtual void didFinishLoading(ResourceHandle*); + virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/); virtual void didFail(ResourceHandle*, const ResourceError&); void run(); @@ -102,7 +102,7 @@ void WebCoreSynchronousLoader::didReceiveData(ResourceHandle*, const char* data, m_data.append(data, length); } -void WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*) +void WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*, double) { g_main_loop_quit(m_mainLoop); m_finished = true; @@ -111,7 +111,7 @@ void WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*) void WebCoreSynchronousLoader::didFail(ResourceHandle* handle, const ResourceError& error) { m_error = error; - didFinishLoading(handle); + didFinishLoading(handle, 0); } void WebCoreSynchronousLoader::run() @@ -336,7 +336,7 @@ static void finishedCallback(SoupSession *session, SoupMessage* msg, gpointer da client->didReceiveData(handle.get(), msg->response_body->data, msg->response_body->length, true); } - client->didFinishLoading(handle.get()); + client->didFinishLoading(handle.get(), 0); } // parseDataUrl() is taken from the CURL http backend. @@ -415,7 +415,7 @@ static gboolean parseDataUrl(gpointer callbackData) if (d->m_cancelled || !handle->client()) return false; - client->didFinishLoading(handle); + client->didFinishLoading(handle, 0); return false; } @@ -578,16 +578,16 @@ static bool startHttp(ResourceHandle* handle) return true; } -bool ResourceHandle::start(Frame* frame) +bool ResourceHandle::start(NetworkingContext* context) { ASSERT(!d->m_msg); - // The frame could be null if the ResourceHandle is not associated to any // Frame, e.g. if we are downloading a file. // If the frame is not null but the page is null this must be an attempted - // load from an onUnload handler, so let's just block it. - if (frame && !frame->page()) + // load from an unload handler, so let's just block it. + // If both the frame and the page are not null the context is valid. + if (context && !context->isValid()) return false; KURL url = firstRequest().url(); @@ -595,7 +595,7 @@ bool ResourceHandle::start(Frame* frame) String protocol = url.protocol(); // Used to set the authentication dialog toplevel; may be NULL - d->m_frame = frame; + d->m_context = context; if (equalIgnoringCase(protocol, "data")) return startData(this, urlString); @@ -655,14 +655,14 @@ bool ResourceHandle::willLoadFromCache(ResourceRequest&, Frame*) return false; } -void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, StoredCredentials /*storedCredentials*/, ResourceError& error, ResourceResponse& response, Vector<char>& data, Frame* frame) +void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const ResourceRequest& request, StoredCredentials /*storedCredentials*/, ResourceError& error, ResourceResponse& response, Vector<char>& data) { WebCoreSynchronousLoader syncLoader(error, response, data); // FIXME: we should use the ResourceHandle::create method here, // but it makes us timeout in a couple of tests. See // https://bugs.webkit.org/show_bug.cgi?id=41823 RefPtr<ResourceHandle> handle = adoptRef(new ResourceHandle(request, &syncLoader, true, false)); - handle->start(frame); + handle->start(context); syncLoader.run(); } @@ -717,7 +717,7 @@ static void closeCallback(GObject* source, GAsyncResult* res, gpointer) if (d->m_cancelled || !client) return; - client->didFinishLoading(handle.get()); + client->didFinishLoading(handle.get(), 0); } static void readCallback(GObject* source, GAsyncResult* res, gpointer) diff --git a/WebCore/platform/network/win/ResourceHandleWin.cpp b/WebCore/platform/network/win/ResourceHandleWin.cpp index 2af03c0..832a8e2 100644 --- a/WebCore/platform/network/win/ResourceHandleWin.cpp +++ b/WebCore/platform/network/win/ResourceHandleWin.cpp @@ -38,6 +38,7 @@ #include "ResourceHandleWin.h" #include "Timer.h" #include "WebCoreInstanceHandle.h" + #include <wtf/text/CString.h> #include <windows.h> #include <wininet.h> @@ -144,7 +145,7 @@ public: virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived); - virtual void didFinishLoading(ResourceHandle*); + virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/); virtual void didFail(ResourceHandle*, const ResourceError&); private: @@ -170,7 +171,7 @@ void WebCoreSynchronousLoader::didReceiveData(ResourceHandle*, const char* data, m_data.append(data, length); } -void WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*) +void WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*, double) { } @@ -349,7 +350,7 @@ void ResourceHandle::onRequestComplete(LPARAM lParam) InternetCloseHandle(d->m_secondaryHandle); InternetCloseHandle(d->m_resourceHandle); - client()->didFinishLoading(this); + client()->didFinishLoading(this, 0); delete this; } @@ -406,7 +407,7 @@ static void __stdcall transferJobStatusCallback(HINTERNET internetHandle, PostMessage(transferJobWindowHandle, msg, (WPARAM) jobId, lParam); } -bool ResourceHandle::start(Frame* frame) +bool ResourceHandle::start(NetworkingContext* context) { ref(); if (request().url().isLocalFile()) { @@ -415,7 +416,7 @@ bool ResourceHandle::start(Frame* frame) } else { static HINTERNET internetHandle = 0; if (!internetHandle) { - String userAgentStr = frame->loader()->userAgent(request().url()) + String("", 1); + String userAgentStr = context->userAgent() + String("", 1); LPCWSTR userAgent = reinterpret_cast<const WCHAR*>(userAgentStr.characters()); // leak the Internet for now internetHandle = InternetOpen(userAgent, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, INTERNET_FLAG_ASYNC); @@ -438,7 +439,7 @@ bool ResourceHandle::start(Frame* frame) // For form posting, we can't use InternetOpenURL. We have to use // InternetConnect followed by HttpSendRequest. HINTERNET urlHandle; - String referrer = frame->loader()->referrer(); + String referrer = context->referrer(); if (request().httpMethod() == "POST") { d->m_postReferrer = referrer; String host = request().url().host(); @@ -511,7 +512,7 @@ void ResourceHandle::fileLoadTimer(Timer<ResourceHandle>*) CloseHandle(fileHandle); - client()->didFinishLoading(this); + client()->didFinishLoading(this, 0); } void ResourceHandle::cancel() @@ -521,7 +522,7 @@ void ResourceHandle::cancel() else d->m_fileLoadTimer.stop(); - client()->didFinishLoading(this); + client()->didFinishLoading(this, 0); if (!d->m_resourceHandle) // Async load canceled before we have a handle -- mark ourselves as in error, to be deleted later. diff --git a/WebCore/platform/qt/CookieJarQt.cpp b/WebCore/platform/qt/CookieJarQt.cpp index 15053eb..4e1de23 100644 --- a/WebCore/platform/qt/CookieJarQt.cpp +++ b/WebCore/platform/qt/CookieJarQt.cpp @@ -31,6 +31,7 @@ #include "Cookie.h" #include "Document.h" #include "KURL.h" +#include "NetworkingContext.h" #include "PlatformString.h" #include "qwebpage.h" @@ -51,9 +52,7 @@ static QNetworkCookieJar *cookieJar(const Document *document) FrameLoader *loader = frame->loader(); if (!loader) return 0; - QWebFrame* webFrame = static_cast<FrameLoaderClientQt*>(loader->client())->webFrame(); - QWebPage* page = webFrame->page(); - QNetworkAccessManager* manager = page->networkAccessManager(); + QNetworkAccessManager* manager = loader->networkingContext()->networkAccessManager(); QNetworkCookieJar* jar = manager->cookieJar(); return jar; } diff --git a/WebCore/platform/qt/Language.cpp b/WebCore/platform/qt/Language.cpp new file mode 100644 index 0000000..0d2900b --- /dev/null +++ b/WebCore/platform/qt/Language.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2010 INdT - Instituto Nokia de Tecnologia + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * + * 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 "Language.h" + +#include "PlatformString.h" +#include <QLocale> + +namespace WebCore { + +String defaultLanguage() +{ + QLocale locale; + return locale.name().replace("_", "-"); +} + +} diff --git a/WebCore/platform/qt/Localizations.cpp b/WebCore/platform/qt/Localizations.cpp deleted file mode 100644 index 454872a..0000000 --- a/WebCore/platform/qt/Localizations.cpp +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Copyright (C) 2007 Staikos Computing Services Inc. <info@staikos.net> - * Copyright (C) 2007 Apple Inc. All rights reserved. - * - * 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 "LocalizedStrings.h" - -#include "IntSize.h" -#include "NotImplemented.h" -#include "PlatformString.h" -#include <QCoreApplication> -#include <QLocale> -#include <wtf/MathExtras.h> - - -namespace WebCore { - -String submitButtonDefaultLabel() -{ - return QCoreApplication::translate("QWebPage", "Submit", "default label for Submit buttons in forms on web pages"); -} - -String inputElementAltText() -{ - return QCoreApplication::translate("QWebPage", "Submit", "Submit (input element) alt text for <input> elements with no alt, title, or value"); -} - -String resetButtonDefaultLabel() -{ - return QCoreApplication::translate("QWebPage", "Reset", "default label for Reset buttons in forms on web pages"); -} - -String defaultLanguage() -{ - QLocale locale; - return locale.name().replace("_", "-"); -} - -String searchableIndexIntroduction() -{ - return QCoreApplication::translate("QWebPage", "This is a searchable index. Enter search keywords: ", "text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index'"); -} - -String fileButtonChooseFileLabel() -{ - return QCoreApplication::translate("QWebPage", "Choose File", "title for file button used in HTML forms"); -} - -String fileButtonNoFileSelectedLabel() -{ - return QCoreApplication::translate("QWebPage", "No file selected", "text to display in file button used in HTML forms when no file is selected"); -} - -String contextMenuItemTagOpenLinkInNewWindow() -{ - return QCoreApplication::translate("QWebPage", "Open in New Window", "Open in New Window context menu item"); -} - -String contextMenuItemTagDownloadLinkToDisk() -{ - return QCoreApplication::translate("QWebPage", "Save Link...", "Download Linked File context menu item"); -} - -String contextMenuItemTagCopyLinkToClipboard() -{ - return QCoreApplication::translate("QWebPage", "Copy Link", "Copy Link context menu item"); -} - -String contextMenuItemTagOpenImageInNewWindow() -{ - return QCoreApplication::translate("QWebPage", "Open Image", "Open Image in New Window context menu item"); -} - -String contextMenuItemTagDownloadImageToDisk() -{ - return QCoreApplication::translate("QWebPage", "Save Image", "Download Image context menu item"); -} - -String contextMenuItemTagCopyImageToClipboard() -{ - return QCoreApplication::translate("QWebPage", "Copy Image", "Copy Link context menu item"); -} - -String contextMenuItemTagOpenFrameInNewWindow() -{ - return QCoreApplication::translate("QWebPage", "Open Frame", "Open Frame in New Window context menu item"); -} - -String contextMenuItemTagCopy() -{ - return QCoreApplication::translate("QWebPage", "Copy", "Copy context menu item"); -} - -String contextMenuItemTagGoBack() -{ - return QCoreApplication::translate("QWebPage", "Go Back", "Back context menu item"); -} - -String contextMenuItemTagGoForward() -{ - return QCoreApplication::translate("QWebPage", "Go Forward", "Forward context menu item"); -} - -String contextMenuItemTagStop() -{ - return QCoreApplication::translate("QWebPage", "Stop", "Stop context menu item"); -} - -String contextMenuItemTagReload() -{ - return QCoreApplication::translate("QWebPage", "Reload", "Reload context menu item"); -} - -String contextMenuItemTagCut() -{ - return QCoreApplication::translate("QWebPage", "Cut", "Cut context menu item"); -} - -String contextMenuItemTagPaste() -{ - return QCoreApplication::translate("QWebPage", "Paste", "Paste context menu item"); -} - -String contextMenuItemTagNoGuessesFound() -{ - return QCoreApplication::translate("QWebPage", "No Guesses Found", "No Guesses Found context menu item"); -} - -String contextMenuItemTagIgnoreSpelling() -{ - return QCoreApplication::translate("QWebPage", "Ignore", "Ignore Spelling context menu item"); -} - -String contextMenuItemTagLearnSpelling() -{ - return QCoreApplication::translate("QWebPage", "Add To Dictionary", "Learn Spelling context menu item"); -} - -String contextMenuItemTagSearchWeb() -{ - return QCoreApplication::translate("QWebPage", "Search The Web", "Search The Web context menu item"); -} - -String contextMenuItemTagLookUpInDictionary() -{ - return QCoreApplication::translate("QWebPage", "Look Up In Dictionary", "Look Up in Dictionary context menu item"); -} - -String contextMenuItemTagOpenLink() -{ - return QCoreApplication::translate("QWebPage", "Open Link", "Open Link context menu item"); -} - -String contextMenuItemTagIgnoreGrammar() -{ - return QCoreApplication::translate("QWebPage", "Ignore", "Ignore Grammar context menu item"); -} - -String contextMenuItemTagSpellingMenu() -{ - return QCoreApplication::translate("QWebPage", "Spelling", "Spelling and Grammar context sub-menu item"); -} - -String contextMenuItemTagShowSpellingPanel(bool show) -{ - return show ? QCoreApplication::translate("QWebPage", "Show Spelling and Grammar", "menu item title") : - QCoreApplication::translate("QWebPage", "Hide Spelling and Grammar", "menu item title"); -} - -String contextMenuItemTagCheckSpelling() -{ - return QCoreApplication::translate("QWebPage", "Check Spelling", "Check spelling context menu item"); -} - -String contextMenuItemTagCheckSpellingWhileTyping() -{ - return QCoreApplication::translate("QWebPage", "Check Spelling While Typing", "Check spelling while typing context menu item"); -} - -String contextMenuItemTagCheckGrammarWithSpelling() -{ - return QCoreApplication::translate("QWebPage", "Check Grammar With Spelling", "Check grammar with spelling context menu item"); -} - -String contextMenuItemTagFontMenu() -{ - return QCoreApplication::translate("QWebPage", "Fonts", "Font context sub-menu item"); -} - -String contextMenuItemTagBold() -{ - return QCoreApplication::translate("QWebPage", "Bold", "Bold context menu item"); -} - -String contextMenuItemTagItalic() -{ - return QCoreApplication::translate("QWebPage", "Italic", "Italic context menu item"); -} - -String contextMenuItemTagUnderline() -{ - return QCoreApplication::translate("QWebPage", "Underline", "Underline context menu item"); -} - -String contextMenuItemTagOutline() -{ - return QCoreApplication::translate("QWebPage", "Outline", "Outline context menu item"); -} - -String contextMenuItemTagWritingDirectionMenu() -{ - return QCoreApplication::translate("QWebPage", "Direction", "Writing direction context sub-menu item"); -} - -String contextMenuItemTagTextDirectionMenu() -{ - return QCoreApplication::translate("QWebPage", "Text Direction", "Text direction context sub-menu item"); -} - -String contextMenuItemTagDefaultDirection() -{ - return QCoreApplication::translate("QWebPage", "Default", "Default writing direction context menu item"); -} - -String contextMenuItemTagLeftToRight() -{ - return QCoreApplication::translate("QWebPage", "Left to Right", "Left to Right context menu item"); -} - -String contextMenuItemTagRightToLeft() -{ - return QCoreApplication::translate("QWebPage", "Right to Left", "Right to Left context menu item"); -} - -String contextMenuItemTagInspectElement() -{ - return QCoreApplication::translate("QWebPage", "Inspect", "Inspect Element context menu item"); -} - -String searchMenuNoRecentSearchesText() -{ - return QCoreApplication::translate("QWebPage", "No recent searches", "Label for only item in menu that appears when clicking on the search field image, when no searches have been performed"); -} - -String searchMenuRecentSearchesText() -{ - return QCoreApplication::translate("QWebPage", "Recent searches", "label for first item in the menu that appears when clicking on the search field image, used as embedded menu title"); -} - -String searchMenuClearRecentSearchesText() -{ - return QCoreApplication::translate("QWebPage", "Clear recent searches", "menu item in Recent Searches menu that empties menu's contents"); -} - -String AXWebAreaText() -{ - return String(); -} - -String AXLinkText() -{ - return String(); -} - -String AXListMarkerText() -{ - return String(); -} - -String AXImageMapText() -{ - return String(); -} - -String AXHeadingText() -{ - return String(); -} - -String AXDefinitionListTermText() -{ - return String(); -} - -String AXDefinitionListDefinitionText() -{ - return String(); -} - -String AXButtonActionVerb() -{ - return String(); -} - -String AXRadioButtonActionVerb() -{ - return String(); -} - -String AXTextFieldActionVerb() -{ - return String(); -} - -String AXCheckedCheckBoxActionVerb() -{ - return String(); -} - -String AXUncheckedCheckBoxActionVerb() -{ - return String(); -} - -String AXLinkActionVerb() -{ - return String(); -} - -String AXMenuListPopupActionVerb() -{ - return String(); -} - -String AXMenuListActionVerb() -{ - return String(); -} - -String missingPluginText() -{ - return QCoreApplication::translate("QWebPage", "Missing Plug-in", "Label text to be used when a plug-in is missing"); -} - -String crashedPluginText() -{ - notImplemented(); - return String(); -} - -String multipleFileUploadText(unsigned) -{ - return String(); -} - -String unknownFileSizeText() -{ - return QCoreApplication::translate("QWebPage", "Unknown", "Unknown filesize FTP directory listing item"); -} - -String imageTitle(const String& filename, const IntSize& size) -{ - return QCoreApplication::translate("QWebPage", "%1 (%2x%3 pixels)", "Title string for images").arg(filename).arg(size.width()).arg(size.height()); -} - -String mediaElementLoadingStateText() -{ - return QCoreApplication::translate("QWebPage", "Loading...", "Media controller status message when the media is loading"); -} - -String mediaElementLiveBroadcastStateText() -{ - return QCoreApplication::translate("QWebPage", "Live Broadcast", "Media controller status message when watching a live broadcast"); -} - -#if ENABLE(VIDEO) - -String localizedMediaControlElementString(const String& name) -{ - if (name == "AudioElement") - return QCoreApplication::translate("QWebPage", "Audio Element", "Media controller element"); - if (name == "VideoElement") - return QCoreApplication::translate("QWebPage", "Video Element", "Media controller element"); - if (name == "MuteButton") - return QCoreApplication::translate("QWebPage", "Mute Button", "Media controller element"); - if (name == "UnMuteButton") - return QCoreApplication::translate("QWebPage", "Unmute Button", "Media controller element"); - if (name == "PlayButton") - return QCoreApplication::translate("QWebPage", "Play Button", "Media controller element"); - if (name == "PauseButton") - return QCoreApplication::translate("QWebPage", "Pause Button", "Media controller element"); - if (name == "Slider") - return QCoreApplication::translate("QWebPage", "Slider", "Media controller element"); - if (name == "SliderThumb") - return QCoreApplication::translate("QWebPage", "Slider Thumb", "Media controller element"); - if (name == "RewindButton") - return QCoreApplication::translate("QWebPage", "Rewind Button", "Media controller element"); - if (name == "ReturnToRealtimeButton") - return QCoreApplication::translate("QWebPage", "Return to Real-time Button", "Media controller element"); - if (name == "CurrentTimeDisplay") - return QCoreApplication::translate("QWebPage", "Elapsed Time", "Media controller element"); - if (name == "TimeRemainingDisplay") - return QCoreApplication::translate("QWebPage", "Remaining Time", "Media controller element"); - if (name == "StatusDisplay") - return QCoreApplication::translate("QWebPage", "Status Display", "Media controller element"); - if (name == "FullscreenButton") - return QCoreApplication::translate("QWebPage", "Fullscreen Button", "Media controller element"); - if (name == "SeekForwardButton") - return QCoreApplication::translate("QWebPage", "Seek Forward Button", "Media controller element"); - if (name == "SeekBackButton") - return QCoreApplication::translate("QWebPage", "Seek Back Button", "Media controller element"); - - return String(); -} - -String localizedMediaControlElementHelpText(const String& name) -{ - if (name == "AudioElement") - return QCoreApplication::translate("QWebPage", "Audio element playback controls and status display", "Media controller element"); - if (name == "VideoElement") - return QCoreApplication::translate("QWebPage", "Video element playback controls and status display", "Media controller element"); - if (name == "MuteButton") - return QCoreApplication::translate("QWebPage", "Mute audio tracks", "Media controller element"); - if (name == "UnMuteButton") - return QCoreApplication::translate("QWebPage", "Unmute audio tracks", "Media controller element"); - if (name == "PlayButton") - return QCoreApplication::translate("QWebPage", "Begin playback", "Media controller element"); - if (name == "PauseButton") - return QCoreApplication::translate("QWebPage", "Pause playback", "Media controller element"); - if (name == "Slider") - return QCoreApplication::translate("QWebPage", "Movie time scrubber", "Media controller element"); - if (name == "SliderThumb") - return QCoreApplication::translate("QWebPage", "Movie time scrubber thumb", "Media controller element"); - if (name == "RewindButton") - return QCoreApplication::translate("QWebPage", "Rewind movie", "Media controller element"); - if (name == "ReturnToRealtimeButton") - return QCoreApplication::translate("QWebPage", "Return streaming movie to real-time", "Media controller element"); - if (name == "CurrentTimeDisplay") - return QCoreApplication::translate("QWebPage", "Current movie time", "Media controller element"); - if (name == "TimeRemainingDisplay") - return QCoreApplication::translate("QWebPage", "Remaining movie time", "Media controller element"); - if (name == "StatusDisplay") - return QCoreApplication::translate("QWebPage", "Current movie status", "Media controller element"); - if (name == "FullscreenButton") - return QCoreApplication::translate("QWebPage", "Play movie in full-screen mode", "Media controller element"); - if (name == "SeekForwardButton") - return QCoreApplication::translate("QWebPage", "Seek quickly back", "Media controller element"); - if (name == "SeekBackButton") - return QCoreApplication::translate("QWebPage", "Seek quickly forward", "Media controller element"); - - ASSERT_NOT_REACHED(); - return String(); -} - -String localizedMediaTimeDescription(float time) -{ - if (!isfinite(time)) - return QCoreApplication::translate("QWebPage", "Indefinite time", "Media time description"); - - int seconds = (int)fabsf(time); - int days = seconds / (60 * 60 * 24); - int hours = seconds / (60 * 60); - int minutes = (seconds / 60) % 60; - seconds %= 60; - - if (days) - return QCoreApplication::translate("QWebPage", "%1 days %2 hours %3 minutes %4 seconds", "Media time description").arg(days).arg(hours).arg(minutes).arg(seconds); - - if (hours) - return QCoreApplication::translate("QWebPage", "%1 hours %2 minutes %3 seconds", "Media time description").arg(hours).arg(minutes).arg(seconds); - - if (minutes) - return QCoreApplication::translate("QWebPage", "%1 minutes %2 seconds", "Media time description").arg(minutes).arg(seconds); - - return QCoreApplication::translate("QWebPage", "%1 seconds", "Media time description").arg(seconds); -} -#endif // ENABLE(VIDEO) - -String validationMessageValueMissingText() -{ - notImplemented(); - return String(); -} - -String validationMessageTypeMismatchText() -{ - notImplemented(); - return String(); -} - -String validationMessagePatternMismatchText() -{ - notImplemented(); - return String(); -} - -String validationMessageTooLongText() -{ - notImplemented(); - return String(); -} - -String validationMessageRangeUnderflowText() -{ - notImplemented(); - return String(); -} - -String validationMessageRangeOverflowText() -{ - notImplemented(); - return String(); -} - -String validationMessageStepMismatchText() -{ - notImplemented(); - return String(); -} - -} -// vim: ts=4 sw=4 et diff --git a/WebCore/platform/qt/MIMETypeRegistryQt.cpp b/WebCore/platform/qt/MIMETypeRegistryQt.cpp index 4161f81..12db891 100644 --- a/WebCore/platform/qt/MIMETypeRegistryQt.cpp +++ b/WebCore/platform/qt/MIMETypeRegistryQt.cpp @@ -79,7 +79,7 @@ String MIMETypeRegistry::getMIMETypeForExtension(const String &ext) ++e; } - return "application/octet-stream"; + return String(); } bool MIMETypeRegistry::isApplicationPluginMIMEType(const String& mimeType) diff --git a/WebCore/platform/qt/PlatformBridge.h b/WebCore/platform/qt/PlatformBridge.h new file mode 100644 index 0000000..918e139 --- /dev/null +++ b/WebCore/platform/qt/PlatformBridge.h @@ -0,0 +1,98 @@ +/* + * Copyright 2009, 2010, The Android Open Source Project + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 PlatformBridge_h +#define PlatformBridge_h + +#include "KURL.h" +#include "npapi.h" +#include "PlatformString.h" + +#include <wtf/Vector.h> + +// V8 bindings use the ARRAYSIZE_UNSAFE macro. This macro was copied +// from http://src.chromium.org/viewvc/chrome/trunk/src/base/basictypes.h +// +// ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize, +// but can be used on anonymous types or types defined inside +// functions. It's less safe than arraysize as it accepts some +// (although not all) pointers. Therefore, you should use arraysize +// whenever possible. +// +// The expression ARRAYSIZE_UNSAFE(a) is a compile-time constant of type +// size_t. +// +// ARRAYSIZE_UNSAFE catches a few type errors. If you see a compiler error +// +// "warning: division by zero in ..." +// +// when using ARRAYSIZE_UNSAFE, you are (wrongfully) giving it a pointer. +// You should only use ARRAYSIZE_UNSAFE on statically allocated arrays. +// +// The following comments are on the implementation details, and can +// be ignored by the users. +// +// ARRAYSIZE_UNSAFE(arr) works by inspecting sizeof(arr) (the # of bytes in +// the array) and sizeof(*(arr)) (the # of bytes in one array +// element). If the former is divisible by the latter, perhaps arr is +// indeed an array, in which case the division result is the # of +// elements in the array. Otherwise, arr cannot possibly be an array, +// and we generate a compiler error to prevent the code from +// compiling. +// +// Since the size of bool is implementation-defined, we need to cast +// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final +// result has type size_t. +// +// This macro is not perfect as it wrongfully accepts certain +// pointers, namely where the pointer size is divisible by the pointee +// size. Since all our code has to go through a 32-bit compiler, +// where a pointer is 4 bytes, this means all pointers to a type whose +// size is 3 or greater than 4 will be (righteously) rejected. + +#define ARRAYSIZE_UNSAFE(a) \ + ((sizeof(a) / sizeof(*(a))) / \ + static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) + + +class NPObject; + +namespace WebCore { + +class Widget; + +// An interface to the embedding layer, which has the ability to answer +// questions about the system and so on... +// This is very similar to ChromiumBridge and the two are likely to converge +// in the future. +class PlatformBridge { +public: + static bool popupsAllowed(NPP npp); + // Plugin + static NPObject* pluginScriptableObject(Widget*); +}; + +} +#endif // PlatformBridge_h diff --git a/WebCore/platform/text/brew/TextBreakIteratorInternalICUBrew.cpp b/WebCore/platform/qt/PlatformBridgeQt.cpp index 4384411..62065d7 100644 --- a/WebCore/platform/text/brew/TextBreakIteratorInternalICUBrew.cpp +++ b/WebCore/platform/qt/PlatformBridgeQt.cpp @@ -1,5 +1,7 @@ /* - * Copyright (C) 2010 Company 100, Inc. + * This file is part of the WebKit project. + * + * Copyright (C) 2010 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 @@ -13,29 +15,37 @@ * * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. * */ - #include "config.h" -#include "TextBreakIteratorInternalICU.h" +#include "PlatformBridge.h" -#include "NotImplemented.h" +#include "Frame.h" +#include "PluginView.h" +#include "Widget.h" namespace WebCore { -const char* currentSearchLocaleID() +bool PlatformBridge::popupsAllowed(NPP npp) { - notImplemented(); - return ""; + if (npp && npp->ndata) + return static_cast<PluginView*>(npp->ndata)->arePopupsAllowed(); + + return false; } -const char* currentTextBreakLocaleID() +NPObject* PlatformBridge::pluginScriptableObject(Widget* widget) { - notImplemented(); - return "en_us"; -} + if (!widget) + return 0; -} // namespace WebCore + if (!widget->isPluginView()) + return 0; + PluginView* pluginView = static_cast<PluginView*>(widget); + return pluginView->npObject(); +} + +} diff --git a/WebCore/platform/qt/PlatformKeyboardEventQt.cpp b/WebCore/platform/qt/PlatformKeyboardEventQt.cpp index 6dde9c4..33e9552 100644 --- a/WebCore/platform/qt/PlatformKeyboardEventQt.cpp +++ b/WebCore/platform/qt/PlatformKeyboardEventQt.cpp @@ -188,6 +188,13 @@ int windowsKeyCodeForKeyEvent(unsigned int keycode, bool isKeypad) return VK_RIGHT; // (27) RIGHT ARROW key case Qt::Key_Down: return VK_DOWN; // (28) DOWN ARROW key + case Qt::Key_Enter: + case Qt::Key_Return: + return VK_RETURN; // (0D) Return key + case Qt::Key_Insert: + return VK_INSERT; // (2D) INS key + case Qt::Key_Delete: + return VK_DELETE; // (2E) DEL key default: return 0; } @@ -304,12 +311,9 @@ int windowsKeyCodeForKeyEvent(unsigned int keycode, bool isKeypad) case Qt::Key_Select: return VK_SELECT; // (29) SELECT key case Qt::Key_Print: - return VK_PRINT; // (2A) PRINT key + return VK_SNAPSHOT; // (2A) PRINT key case Qt::Key_Execute: return VK_EXECUTE; // (2B) EXECUTE key - // dunno on this - // case Qt::Key_PrintScreen: - // return VK_SNAPSHOT; // (2C) PRINT SCREEN key case Qt::Key_Insert: return VK_INSERT; // (2D) INS key case Qt::Key_Delete: diff --git a/WebCore/platform/qt/RenderThemeQt.cpp b/WebCore/platform/qt/RenderThemeQt.cpp index 870f0eb..4a461ac 100644 --- a/WebCore/platform/qt/RenderThemeQt.cpp +++ b/WebCore/platform/qt/RenderThemeQt.cpp @@ -380,6 +380,7 @@ void RenderThemeQt::computeSizeBasedOnStyle(RenderStyle* renderStyle) const QStyleOption styleOption; styleOption.state |= QStyle::State_Small; int checkBoxWidth = style->pixelMetric(QStyle::PM_IndicatorWidth, &styleOption); + checkBoxWidth *= renderStyle->effectiveZoom(); size = QSize(checkBoxWidth, checkBoxWidth); break; } @@ -387,6 +388,7 @@ void RenderThemeQt::computeSizeBasedOnStyle(RenderStyle* renderStyle) const QStyleOption styleOption; styleOption.state |= QStyle::State_Small; int radioWidth = style->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth, &styleOption); + radioWidth *= renderStyle->effectiveZoom(); size = QSize(radioWidth, radioWidth); break; } diff --git a/WebCore/platform/text/wince/TextBoundariesWince.cpp b/WebCore/platform/text/wince/TextBoundariesWinCE.cpp index df6f757..f3070a4 100644 --- a/WebCore/platform/text/wince/TextBoundariesWince.cpp +++ b/WebCore/platform/text/wince/TextBoundariesWinCE.cpp @@ -71,5 +71,4 @@ void findWordBoundary(const UChar * buffer, int len, int position, int* start, i *end = currentPosition; } - -} +} // namespace WebCore diff --git a/WebCore/platform/text/wince/TextBreakIteratorWince.cpp b/WebCore/platform/text/wince/TextBreakIteratorWinCE.cpp index 7f46e4f..7f46e4f 100644 --- a/WebCore/platform/text/wince/TextBreakIteratorWince.cpp +++ b/WebCore/platform/text/wince/TextBreakIteratorWinCE.cpp diff --git a/WebCore/platform/text/wince/TextCodecWinCE.cpp b/WebCore/platform/text/wince/TextCodecWinCE.cpp index 2789148..499035f 100644 --- a/WebCore/platform/text/wince/TextCodecWinCE.cpp +++ b/WebCore/platform/text/wince/TextCodecWinCE.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2007-2009 Torch Mobile, Inc. All rights reserved. + * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -132,11 +133,11 @@ static UINT getCodePage(const char* name) static PassOwnPtr<TextCodec> newTextCodecWinCE(const TextEncoding& encoding, const void*) { - return new TextCodecWinCE(encoding); + return new TextCodecWinCE(getCodePage(encoding.name())); } -TextCodecWinCE::TextCodecWinCE(const TextEncoding& encoding) - : m_encoding(encoding) +TextCodecWinCE::TextCodecWinCE(UINT codePage) + : m_codePage(codePage) { } @@ -211,22 +212,12 @@ static inline const char* findFirstNonAsciiCharacter(const char* bytes, size_t l return bytes; } -static void decode(Vector<UChar, 8192>& result, const char* encodingName, const char* bytes, size_t length, size_t* left, bool canBeFirstTime, bool& sawInvalidChar) +static void decode(Vector<UChar, 8192>& result, UINT codePage, const char* bytes, size_t length, size_t* left, bool canBeFirstTime, bool& sawInvalidChar) { *left = length; if (!bytes || !length) return; - UINT codePage; - - HashMap<String, CharsetInfo>::iterator i = knownCharsets().find(encodingName); - if (i == knownCharsets().end()) { - if (!strcmp(encodingName, "UTF-8")) - codePage = CP_UTF8; - else - codePage = CP_ACP; - } - DWORD flags = getCodePageFlags(codePage); if (codePage == CP_UTF8) { @@ -331,7 +322,7 @@ String TextCodecWinCE::decode(const char* bytes, size_t length, bool flush, bool Vector<UChar, 8192> result; for (;;) { bool sawInvalidChar = false; - WebCore::decode(result, m_encoding.name(), bytes, length, &left, m_decodeBuffer.isEmpty(), sawInvalidChar); + WebCore::decode(result, m_codePage, bytes, length, &left, m_decodeBuffer.isEmpty(), sawInvalidChar); if (!left) break; @@ -367,21 +358,21 @@ CString TextCodecWinCE::encode(const UChar* characters, size_t length, Unencodab if (!characters || !length) return CString(); - UINT codePage = getCodePage(m_encoding.name()); - DWORD flags = codePage == CP_UTF8 ? 0 : WC_COMPOSITECHECK; + DWORD flags = m_codePage == CP_UTF8 ? 0 : WC_COMPOSITECHECK; - int resultLength = WideCharToMultiByte(codePage, flags, characters, length, 0, 0, 0, 0); + int resultLength = WideCharToMultiByte(m_codePage, flags, characters, length, 0, 0, 0, 0); // FIXME: We need to implement UnencodableHandling: QuestionMarksForUnencodables, EntitiesForUnencodables, and URLEncodedEntitiesForUnencodables. if (resultLength <= 0) return "?"; - Vector<char> result(resultLength); + char* characterBuffer; + CString result = CString::newUninitialized(resultLength, characterBuffer); - WideCharToMultiByte(codePage, flags, characters, length, result.data(), resultLength, 0, 0); + WideCharToMultiByte(m_codePage, flags, characters, length, characterBuffer, resultLength, 0, 0); - return CString(result.data(), result.size()); + return result; } void TextCodecWinCE::enumerateSupportedEncodings(EncodingReceiver& receiver) diff --git a/WebCore/platform/text/wince/TextCodecWinCE.h b/WebCore/platform/text/wince/TextCodecWinCE.h index a870d3e..8d332a6 100644 --- a/WebCore/platform/text/wince/TextCodecWinCE.h +++ b/WebCore/platform/text/wince/TextCodecWinCE.h @@ -2,6 +2,7 @@ * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> * Copyright (C) 2007-2009 Torch Mobile, Inc. + * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,6 +33,7 @@ #include "TextCodec.h" #include "TextEncoding.h" #include <wtf/Vector.h> +#include <windows.h> namespace WebCore { @@ -43,7 +45,7 @@ public: static void registerExtendedEncodingNames(EncodingNameRegistrar); static void registerExtendedCodecs(TextCodecRegistrar); - TextCodecWinCE(const TextEncoding&); + TextCodecWinCE(UINT codePage); virtual ~TextCodecWinCE(); virtual String decode(const char*, size_t length, bool flush, bool stopOnError, bool& sawError); @@ -62,7 +64,7 @@ public: static void enumerateSupportedEncodings(EncodingReceiver& receiver); private: - TextEncoding m_encoding; + UINT m_codePage; Vector<char> m_decodeBuffer; }; diff --git a/WebCore/platform/win/ClipboardWin.cpp b/WebCore/platform/win/ClipboardWin.cpp index 6d9930c..b13473a 100644 --- a/WebCore/platform/win/ClipboardWin.cpp +++ b/WebCore/platform/win/ClipboardWin.cpp @@ -604,13 +604,12 @@ PassRefPtr<FileList> ClipboardWin::files() const if (!hdrop) return files.release(); - ScriptExecutionContext* scriptExecutionContext = m_frame->document()->scriptExecutionContext(); WCHAR filename[MAX_PATH]; UINT fileCount = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0); for (UINT i = 0; i < fileCount; i++) { if (!DragQueryFileW(hdrop, i, filename, ARRAYSIZE(filename))) continue; - files->append(File::create(scriptExecutionContext, reinterpret_cast<UChar*>(filename))); + files->append(File::create(reinterpret_cast<UChar*>(filename))); } GlobalUnlock(medium.hGlobal); diff --git a/WebCore/platform/wince/CursorWince.cpp b/WebCore/platform/wince/CursorWinCE.cpp index d7dcfb4..90ba879 100644 --- a/WebCore/platform/wince/CursorWince.cpp +++ b/WebCore/platform/wince/CursorWinCE.cpp @@ -106,4 +106,4 @@ const Cursor& westPanningCursor() { return crossCursor(); } const Cursor& grabbingCursor() { return moveCursor(); } const Cursor& grabCursor() { return moveCursor(); } -} +} // namespace WebCore diff --git a/WebCore/platform/wince/DragDataWince.cpp b/WebCore/platform/wince/DragDataWinCE.cpp index 73dd8a2..5535ea9 100644 --- a/WebCore/platform/wince/DragDataWince.cpp +++ b/WebCore/platform/wince/DragDataWinCE.cpp @@ -80,5 +80,4 @@ Color DragData::asColor() const return Color(); } -} - +} // namespace WebCore diff --git a/WebCore/platform/wince/DragImageWince.cpp b/WebCore/platform/wince/DragImageWinCE.cpp index 4d60f80..f639b41 100644 --- a/WebCore/platform/wince/DragImageWince.cpp +++ b/WebCore/platform/wince/DragImageWinCE.cpp @@ -60,4 +60,4 @@ DragImageRef createDragImageIconForCachedImage(CachedImage*) return 0; } -} +} // namespace WebCore diff --git a/WebCore/platform/wince/EditorWince.cpp b/WebCore/platform/wince/EditorWinCE.cpp index 71f4db9..eb0ecb4 100644 --- a/WebCore/platform/wince/EditorWince.cpp +++ b/WebCore/platform/wince/EditorWinCE.cpp @@ -22,7 +22,7 @@ #include "Editor.h" -#include "ClipboardWince.h" +#include "ClipboardWinCE.h" #include "Document.h" #include "EditorClient.h" #include "Element.h" @@ -37,7 +37,7 @@ namespace WebCore { PassRefPtr<Clipboard> Editor::newGeneralClipboard(ClipboardAccessPolicy policy, Frame*) { - return adoptRef(new ClipboardWince(policy, false)); + return adoptRef(new ClipboardWinCE(policy, false)); } } // namespace WebCore diff --git a/WebCore/platform/wince/FileChooserWince.cpp b/WebCore/platform/wince/FileChooserWinCE.cpp index 07c99b1..955e68a 100644 --- a/WebCore/platform/wince/FileChooserWince.cpp +++ b/WebCore/platform/wince/FileChooserWinCE.cpp @@ -57,4 +57,4 @@ String FileChooser::basenameForWidth(const Font& font, int width) const return StringTruncator::centerTruncate(string, width, font, false); } -} +} // namespace WebCore diff --git a/WebCore/platform/wince/FileSystemWince.cpp b/WebCore/platform/wince/FileSystemWinCE.cpp index cb165a6..2a27089 100644 --- a/WebCore/platform/wince/FileSystemWince.cpp +++ b/WebCore/platform/wince/FileSystemWinCE.cpp @@ -281,4 +281,4 @@ Vector<String> listDirectory(const String& path, const String& filter) return entries; } -} +} // namespace WebCore diff --git a/WebCore/platform/wince/KURLWince.cpp b/WebCore/platform/wince/KURLWinCE.cpp index 5ca1e4b..2bbdfe8 100644 --- a/WebCore/platform/wince/KURLWince.cpp +++ b/WebCore/platform/wince/KURLWinCE.cpp @@ -27,4 +27,4 @@ String KURL::fileSystemPath() const return path(); } -} +} // namespace WebCore diff --git a/WebCore/platform/wince/KeygenWince.cpp b/WebCore/platform/wince/KeygenWinCE.cpp index 0c1b3c6..0c1b3c6 100644 --- a/WebCore/platform/wince/KeygenWince.cpp +++ b/WebCore/platform/wince/KeygenWinCE.cpp diff --git a/WebCore/platform/wince/MIMETypeRegistryWince.cpp b/WebCore/platform/wince/MIMETypeRegistryWinCE.cpp index 9e1bece..7534b91 100644 --- a/WebCore/platform/wince/MIMETypeRegistryWince.cpp +++ b/WebCore/platform/wince/MIMETypeRegistryWinCE.cpp @@ -138,4 +138,4 @@ bool MIMETypeRegistry::isApplicationPluginMIMEType(const String&) return false; } -} +} // namespace WebCore diff --git a/WebCore/platform/wince/PasteboardWince.cpp b/WebCore/platform/wince/PasteboardWinCE.cpp index 70b4083..70b4083 100644 --- a/WebCore/platform/wince/PasteboardWince.cpp +++ b/WebCore/platform/wince/PasteboardWinCE.cpp diff --git a/WebCore/platform/wince/SearchPopupMenuWince.cpp b/WebCore/platform/wince/SearchPopupMenuWinCE.cpp index f9d65a6..b2a8442 100644 --- a/WebCore/platform/wince/SearchPopupMenuWince.cpp +++ b/WebCore/platform/wince/SearchPopupMenuWinCE.cpp @@ -51,4 +51,4 @@ void SearchPopupMenu::loadRecentSearches(const AtomicString& name, Vector<String notImplemented(); } -} +} // namespace WebCore diff --git a/WebCore/platform/wince/SharedTimerWince.cpp b/WebCore/platform/wince/SharedTimerWinCE.cpp index 2328017..81295e2 100644 --- a/WebCore/platform/wince/SharedTimerWince.cpp +++ b/WebCore/platform/wince/SharedTimerWinCE.cpp @@ -128,4 +128,4 @@ void stopSharedTimer() timerID = TimerIdNone; } -} +} // namespace WebCore diff --git a/WebCore/platform/wx/PasteboardWx.cpp b/WebCore/platform/wx/PasteboardWx.cpp index 207c63c..4677d14 100644 --- a/WebCore/platform/wx/PasteboardWx.cpp +++ b/WebCore/platform/wx/PasteboardWx.cpp @@ -53,7 +53,7 @@ Pasteboard* Pasteboard::generalPasteboard() void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame) { if (wxTheClipboard->Open()) { - wxTheClipboard->SetData( new wxTextDataObject(frame->selectedText()) ); + wxTheClipboard->SetData( new wxTextDataObject(frame->editor()->selectedText()) ); wxTheClipboard->Close(); } } |