From da4e047c7bcf6dc966dcb862033ce8c09bd561d9 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Fri, 18 Sep 2009 18:18:38 +0100 Subject: Experimenting to make video visible. Removed the hack to set translucent window background in the mediaplayer. Then tried the following: 1. Direct write to backing store: does not work (backing bitmap is 16MU) 2. Set window background color: does not work (is over-written by control's Draw function) 3. Brush using CWindowGc from widget's paint event: does not work (is over-written by control's Draw function) 4. Hack QSymbianControl to blit a transparent bitmap from the Draw function: does work 5. Hack QSymbianControl to brush using CWindowGc from the Draw function: does work Configuration 5 is the one being committed. Other things we could try: 6. Trigger switch to 16MA backing store if child widgets have been created. This could be tested by calling RWindowTreeNode::Child on the TLW's window. - Maybe we could test whether the child window's display mode is 16MA? 7. Somehow tell QSymbianControl not to draw anything at all - Based on setting Qt::WA_PaintOnScreen? - Then we either: - (Ideally) do nothing, and rely on video stack to paint the necessary transparency - Brush using CWindowGc from widget's paint event --- demos/mediaplayer/mediaplayer.cpp | 2 ++ src/3rdparty/phonon/mmf/defs.h | 2 +- src/3rdparty/phonon/mmf/videooutput.cpp | 36 +++++++++++++++++++++++++++++--- src/3rdparty/phonon/mmf/videoplayer.cpp | 20 ++++++++++++++++++ src/gui/gui.pro | 2 +- src/gui/kernel/qapplication_s60.cpp | 17 ++++++++++++++- src/gui/kernel/qt_s60_p.h | 33 +++++++++++++++++++++++++++++ src/plugins/phonon/mmf/plugin/plugin.pro | 4 ++++ 8 files changed, 110 insertions(+), 6 deletions(-) diff --git a/demos/mediaplayer/mediaplayer.cpp b/demos/mediaplayer/mediaplayer.cpp index 9504236..f3f4128 100644 --- a/demos/mediaplayer/mediaplayer.cpp +++ b/demos/mediaplayer/mediaplayer.cpp @@ -156,9 +156,11 @@ MediaPlayer::MediaPlayer(const QString &filePath) : m_videoWidget->setObjectName("videoWidget"); #ifdef Q_OS_SYMBIAN +/* // setWindowTitle triggers creation of the window surface, so we set // transparency here setAttribute(Qt::WA_TranslucentBackground, true); +*/ #endif setWindowTitle(tr("Media Player")); diff --git a/src/3rdparty/phonon/mmf/defs.h b/src/3rdparty/phonon/mmf/defs.h index 348a40f..e4e06e4 100644 --- a/src/3rdparty/phonon/mmf/defs.h +++ b/src/3rdparty/phonon/mmf/defs.h @@ -26,7 +26,7 @@ along with this library. If not, see . // Defining this macro causes VideoOutput::paintEvent to write transparent // alpha values directly into the backing store, rather than using QPainter -//#define PHONON_MMF_DIRECT_WRITE_ALPHA +#define PHONON_MMF_DIRECT_WRITE_ALPHA QT_BEGIN_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/videooutput.cpp b/src/3rdparty/phonon/mmf/videooutput.cpp index d0f8707..58fa25d 100644 --- a/src/3rdparty/phonon/mmf/videooutput.cpp +++ b/src/3rdparty/phonon/mmf/videooutput.cpp @@ -29,12 +29,17 @@ along with this library. If not, see . #include #include -// Required for implementation of transparentFill +// Required for implementation of transparentFill (direct write to backing store) #include #include #include #include +// Required for implementation of transparentFill (GC brush) +#include +#include +#include + QT_BEGIN_NAMESPACE @@ -140,11 +145,35 @@ void MMF::VideoOutput::transparentFill(const QVector& rects) { TRACE_CONTEXT(VideoOutput::transparentFill, EVideoInternal); TRACE_ENTRY_0(); + +/* + // Graphics context brushing approach + RWindow *const window = static_cast(winId()->DrawableWindow()); + const TDisplayMode displayMode = static_cast(window->SetRequiredDisplayMode(EColor16MA)); + CWindowGc& gc = CEikonEnv::Static()->SystemGc(); + gc.Activate(*window); + gc.SetBrushColor(TRgb(255, 255, 255, 0)); + gc.SetBrushStyle(CGraphicsContext::ESolidBrush); + gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); + window->Invalidate(); + window->BeginRedraw(); + gc.Clear(); + window->EndRedraw(); + gc.Deactivate(); +*/ +/* + // Direct draw into backing store approach (entire TLW) QImage *image = window()->windowSurface()->buffer(window()); QRgb *data = reinterpret_cast(image->bits()); const int row_stride = image->bytesPerLine() / 4; + const QRgb color = + //0xff0000ff // opaque blue + 0x000000ff // transparent blue + //0x00000000 // transparent black + ; + // Paint the entire surface const int imageWidth = image->size().width(); const int imageHeight = image->size().height(); @@ -153,12 +182,13 @@ void MMF::VideoOutput::transparentFill(const QVector& rects) QRgb *ptr = row; for(int x=0; x::const_iterator it = rects.begin(); it != rects.end(); ++it) { const QRect& rect = *it; diff --git a/src/3rdparty/phonon/mmf/videoplayer.cpp b/src/3rdparty/phonon/mmf/videoplayer.cpp index e2c0b7d..cc56671 100644 --- a/src/3rdparty/phonon/mmf/videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/videoplayer.cpp @@ -30,6 +30,8 @@ along with this library. If not, see . #include "objectdump.h" #endif +#include // for QSymbianControl + QT_BEGIN_NAMESPACE using namespace Phonon; @@ -125,7 +127,9 @@ void MMF::VideoPlayer::doPlay() updateMmfOutput(); } + TRAP_IGNORE(m_player->SetVolumeL(0)); // *** HACK *** m_player->Play(); + TRAP_IGNORE(m_player->SetVolumeL(0)); // *** HACK *** } void MMF::VideoPlayer::doPause() @@ -402,11 +406,27 @@ void MMF::VideoPlayer::getNativeWindowSystemHandles() VideoOutput& output = videoOutput(); CCoeControl* const control = output.winId(); + // Inform control that it needs to brush rather than blit the backing store + QSymbianControl* const symbianControl = static_cast(control); + //symbianControl->setBlit(0xff00ff00); // opaque green + //symbianControl->setBlit(0x0000ff00); // transparent green + symbianControl->setBlit(0x00000000); // transparent black + CCoeEnv* const coeEnv = control->ControlEnv(); m_wsSession = &(coeEnv->WsSession()); m_screenDevice = coeEnv->ScreenDevice(); m_window = control->DrawableWindow(); +/* + // Set background window color + RWindow *const window = static_cast(m_window); + const TDisplayMode displayMode = static_cast(window->SetRequiredDisplayMode(EColor16MA)); + //const TInt err = window->SetTransparencyAlphaChannel(); + //if (err == KErrNone) + window->SetBackgroundColor(TRgb(255, 0, 255, 255)); + window->Invalidate(); // force a redraw +*/ + #ifdef _DEBUG QScopedPointer dumper(new ObjectDump::QDumper); dumper->setPrefix("Phonon::MMF"); // to aid searchability of logs diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 9fe09c8..f95be59 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -5,7 +5,7 @@ DEFINES += QT_BUILD_GUI_LIB QT_NO_USING_NAMESPACE win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x65000000 # These enable debugging of window management for Symbian. -#DEFINES += DEBUG_QSYMBIANCONTROL DEBUG_QWIDGET +DEFINES += DEBUG_QSYMBIANCONTROL DEBUG_QWIDGET !win32:!embedded:!mac:!symbian:CONFIG += x11 diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 3cb7ada..e3f3376 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -652,6 +652,7 @@ void QSymbianControl::Draw(const TRect& r) const const int coord = i*10; const TUint32 *ptr = address + (coord * bitmapWidth) + coord; const TUint32 pixel = *ptr; + qDebug() << " " << i*10 << " : " << ptr << pixel; } for(int i=0; i<10 and i*10d_func()->isOpaque) gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); - gc.BitBlt(r.iTl, bitmap, r); + + if(m_bitmap.data()) { + //gc.BitBlt(r.iTl, m_bitmap.data(), TRect(TPoint(), r.Size())); + + gc.SetBrushColor(TRgb(0, 0, 0, 0)); + gc.SetBrushStyle(CGraphicsContext::ESolidBrush); + gc.Clear(r); + } + else + gc.BitBlt(r.iTl, bitmap, r); } else { surface->flush(qwidget, QRegion(qt_TRect2QRect(r)), QPoint()); } @@ -699,6 +709,11 @@ void QSymbianControl::SizeChanged() if (!slowResize && tlwExtra) tlwExtra->inTopLevelResize = false; } + + if(m_bitmap.data()) { + m_bitmap->Resize(Size()); + fillBitmap(); + } } } diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index 1ac6a8e..5331504 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -74,6 +74,8 @@ #include // CEikStatusPane #endif +#include // for CFbsBitmap + QT_BEGIN_NAMESPACE // Application internal HandleResourceChangeL events, @@ -120,6 +122,8 @@ public: }; class QLongTapTimer; +class CFbsBitmap; + class QSymbianControl : public CCoeControl, public QAbstractLongTapObserver { public: @@ -142,6 +146,8 @@ public: void sendInputEvent(QWidget *widget, QInputEvent *inputEvent); void setIgnoreFocusChanged(bool enabled) { m_ignoreFocusChanged = enabled; } void CancelLongTapTimer(); + + void setBlit(TUint32 color); protected: void Draw(const TRect& aRect) const; @@ -156,13 +162,40 @@ private: void sendMouseEvent(QWidget *widget, QMouseEvent *mEvent); void HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation ); + void fillBitmap(); + private: QWidget *qwidget; bool m_ignoreFocusChanged; QLongTapTimer* m_longTapDetector; bool m_previousEventLongTap; + + QScopedPointer m_bitmap; + TUint32 m_color; }; + + +inline void QSymbianControl::setBlit(TUint32 color) +{ + m_bitmap.reset( q_check_ptr(new CFbsBitmap) ); // CBase derived object needs check on new + qt_symbian_throwIfError( m_bitmap->Create(Size(), EColor16MA) ); + + // Not sure if bitmap pixel data is zero-initialized, so do it here to make sure + m_color = color; + fillBitmap(); +} + +inline void QSymbianControl::fillBitmap() +{ + TUint32* ptr = m_bitmap->DataAddress(); + for(int y=0; y