PluginViewPrivateBlackBerry.cpp [plain text]
#include "config.h"
#include "PluginViewPrivateBlackBerry.h"
#include "FrameView.h"
#include "HostWindow.h"
#if USE(ACCELERATED_COMPOSITING)
#include "PluginLayerWebKitThread.h"
#endif
#include "NPCallbacksBlackBerry.h"
#include <BlackBerryPlatformExecutableMessage.h>
#include <BlackBerryPlatformMessageClient.h>
#include <wtf/MainThread.h>
static unsigned s_counter = 0;
namespace WebCore {
PluginViewPrivate::PluginViewPrivate(PluginView* view)
: m_view(view)
, m_pluginBufferType(BlackBerry::Platform::Graphics::PluginBufferWithAlpha)
, m_pluginFrontBuffer(0)
, m_idlePrevented(false)
, m_hasPendingGeometryChange(true)
, m_sentOnLoad(false)
, m_isFullScreen(false)
, m_isFocused(false)
, m_orientationLocked(false)
, m_isBackgroundPlaying(false)
{
m_pluginBuffers[0] = 0;
m_pluginBuffers[1] = 0;
pthread_mutexattr_t mutexAttributes;
pthread_mutexattr_init(&mutexAttributes);
pthread_mutexattr_settype(&mutexAttributes, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&m_backBufferMutex, &mutexAttributes);
pthread_rwlock_init(&m_frontBufferRwLock, 0);
pthread_mutexattr_destroy(&mutexAttributes);
char uniqueId[50];
snprintf(uniqueId, sizeof(uniqueId), "PluginViewBB-%08x%08x-", s_counter++, (int)this);
m_pluginUniquePrefix = uniqueId;
}
PluginViewPrivate::~PluginViewPrivate()
{
#if USE(ACCELERATED_COMPOSITING)
if (m_platformLayer)
static_cast<PluginLayerWebKitThread*>(m_platformLayer.get())->setPluginView(0);
#endif
destroyBuffers();
pthread_mutex_destroy(&m_backBufferMutex);
pthread_rwlock_destroy(&m_frontBufferRwLock);
}
BlackBerry::Platform::Graphics::BufferType PluginViewPrivate::toBufferType(NPSurfaceFormat format)
{
switch (format) {
case FORMAT_RGB_565:
return BlackBerry::Platform::Graphics::PluginBuffer;
case FORMAT_RGBA_8888:
default:
return BlackBerry::Platform::Graphics::PluginBufferWithAlpha;
}
}
void PluginViewPrivate::setZoomFactor(float zoomFactor)
{
if (((NPSetWindowCallbackStruct*)m_view->m_npWindow.ws_info)->zoomFactor != zoomFactor)
m_hasPendingGeometryChange = true;
((NPSetWindowCallbackStruct*)m_view->m_npWindow.ws_info)->zoomFactor = zoomFactor;
}
void PluginViewPrivate::setVisibleRects(const NPRect rects[], int32_t count)
{
m_keepVisibleRect = IntRect();
if (!m_view->parent() || !count)
return;
for (int i = 0; i < count; i++) {
IntRect addRect = IntRect(rects[i].left, rects[i].top, rects[i].right - rects[i].left, rects[i].bottom - rects[i].top);
m_keepVisibleRect.unite(addRect);
}
if (m_keepVisibleRect.isEmpty())
return;
m_keepVisibleRect = m_view->convertToContainingWindow(m_keepVisibleRect);
FrameView* frameView = toFrameView(m_view->parent());
m_keepVisibleRect.move(frameView->scrollPosition().x(), frameView->scrollPosition().y());
frameView->hostWindow()->platformPageClient()->ensureContentVisible();
}
void PluginViewPrivate::clearVisibleRects()
{
if (!m_keepVisibleRect.isEmpty())
setVisibleRects(0, 0);
}
void PluginViewPrivate::showKeyboard(bool value)
{
FrameView* frameView = toFrameView(m_view->parent());
frameView->hostWindow()->platformPageClient()->showVirtualKeyboard(value);
}
void PluginViewPrivate::requestFullScreen()
{
if (FrameView* frameView = toFrameView(m_view->parent()))
if (frameView->hostWindow()->platformPageClient()->shouldPluginEnterFullScreen(m_view, m_pluginUniquePrefix.c_str()))
m_view->handleFullScreenAllowedEvent();
}
void PluginViewPrivate::exitFullScreen()
{
m_view->handleFullScreenExitEvent();
}
void PluginViewPrivate::requestCenterFitZoom()
{
FrameView* frameView = toFrameView(m_view->parent());
if (!frameView)
return;
frameView->hostWindow()->platformPageClient()->zoomToContentRect(m_view->m_windowRect);
}
void PluginViewPrivate::lockOrientation(bool landscape)
{
FrameView* frameView = toFrameView(m_view->parent());
if (!frameView)
return;
frameView->hostWindow()->platformPageClient()->lockOrientation(landscape);
m_orientationLocked = true;
}
void PluginViewPrivate::unlockOrientation()
{
if (!m_orientationLocked)
return;
FrameView* frameView = toFrameView(m_view->parent());
if (!frameView)
return;
frameView->hostWindow()->platformPageClient()->unlockOrientation();
m_orientationLocked = false;
}
void PluginViewPrivate::preventIdle(bool preventIdle)
{
if (preventIdle == m_idlePrevented)
return;
FrameView* frameView = toFrameView(m_view->parent());
if (!frameView)
return;
frameView->hostWindow()->platformPageClient()->setPreventsScreenDimming(preventIdle);
m_idlePrevented = preventIdle;
}
void PluginViewPrivate::setHolePunch(int x, int y, int width, int height)
{
if (width > 0 && height > 0)
m_holePunchRect = IntRect(x, y, width, height);
else
m_holePunchRect = IntRect();
m_holePunchRect.intersect(IntRect(IntPoint(0, 0), m_view->frameRect().size()));
#if USE(ACCELERATED_COMPOSITING)
if (m_platformLayer) {
IntRect rect = m_holePunchRect;
if (!m_holePunchRect.isEmpty())
rect.move(m_view->frameRect().x(), m_view->frameRect().y());
OwnPtr<HolePunchData> hp = adoptPtr(new HolePunchData);
hp->x = m_holePunchRect.x();
hp->y = m_holePunchRect.y();
hp->w = m_holePunchRect.width();
hp->h = m_holePunchRect.height();
hp->layer = m_platformLayer;
callOnMainThread(npSetHolePunchHandler, hp.leakPtr()); }
#endif
}
NPSurface PluginViewPrivate::lockBackBuffer()
{
pthread_mutex_lock(&m_backBufferMutex);
BlackBerry::Platform::Graphics::Buffer* buffer = m_pluginBuffers[(m_pluginFrontBuffer + 1) % PLUGIN_BUFFERS];
if (!buffer || !BlackBerry::Platform::Graphics::platformBufferHandle(buffer)) {
unlockBackBuffer();
return 0;
}
return BlackBerry::Platform::Graphics::platformBufferHandle(buffer);
}
void PluginViewPrivate::unlockBackBuffer()
{
pthread_mutex_unlock(&m_backBufferMutex);
}
BlackBerry::Platform::Graphics::Buffer* PluginViewPrivate::lockReadFrontBufferInternal()
{
pthread_rwlock_rdlock(&m_frontBufferRwLock);
return m_pluginBuffers[m_pluginFrontBuffer];
}
NPSurface PluginViewPrivate::lockReadFrontBuffer()
{
BlackBerry::Platform::Graphics::Buffer* buffer = lockReadFrontBufferInternal();
if (!buffer || !BlackBerry::Platform::Graphics::platformBufferHandle(buffer)) {
unlockReadFrontBuffer();
return 0;
}
return BlackBerry::Platform::Graphics::platformBufferHandle(buffer);
}
void PluginViewPrivate::unlockReadFrontBuffer()
{
pthread_rwlock_unlock(&m_frontBufferRwLock);
}
void PluginViewPrivate::swapBuffers()
{
PthreadMutexLocker backLock(&m_backBufferMutex);
PthreadWriteLocker frontLock(&m_frontBufferRwLock);
m_pluginFrontBuffer = (m_pluginFrontBuffer + 1) % 2;
}
bool PluginViewPrivate::createBuffers(NPSurfaceFormat format, int width, int height)
{
bool success = true;
PthreadMutexLocker backLock(&m_backBufferMutex);
PthreadWriteLocker frontLock(&m_frontBufferRwLock);
bool didDestroyBuffers = false;
for (int i = 0; i < PLUGIN_BUFFERS; i++) {
if (m_pluginBuffers[i]) {
didDestroyBuffers = true;
BlackBerry::Platform::Graphics::destroyBuffer(m_pluginBuffers[i]);
m_pluginBuffers[i] = 0;
}
if (width <= 0 || height <= 0)
success = true;
else {
m_pluginBuffers[i] = BlackBerry::Platform::Graphics::createBuffer(
BlackBerry::Platform::IntSize(width, height),
toBufferType(format));
if (!m_pluginBuffers[i])
success = false;
}
}
if (success) {
m_pluginBufferSize = IntSize(width, height);
m_pluginBufferType = toBufferType(format);
if (didDestroyBuffers) {
BlackBerry::Platform::userInterfaceThreadMessageClient()->dispatchSyncMessage(
BlackBerry::Platform::createFunctionCallMessage(&BlackBerry::Platform::Graphics::collectThreadSpecificGarbage));
}
} else {
m_pluginBufferSize = IntSize();
m_pluginBufferType = BlackBerry::Platform::Graphics::PluginBufferWithAlpha;
destroyBuffers();
}
return success;
}
bool PluginViewPrivate::resizeBuffers(NPSurfaceFormat format, int width, int height)
{
bool success = true;
if (!m_pluginBufferSize.width() || !m_pluginBufferSize.height())
return createBuffers(format, width, height);
if (!width || !height)
return destroyBuffers();
PthreadMutexLocker backLock(&m_backBufferMutex);
PthreadWriteLocker frontLock(&m_frontBufferRwLock);
for (int i = 0; i < PLUGIN_BUFFERS && success; i++) {
success &= BlackBerry::Platform::Graphics::reallocBuffer(m_pluginBuffers[i],
BlackBerry::Platform::IntSize(width, height),
toBufferType(format));
}
if (success) {
m_pluginBufferSize = IntSize(width, height);
m_pluginBufferType = toBufferType(format);
return true;
}
if (!m_pluginBufferSize.width() || !m_pluginBufferSize.height()) {
destroyBuffers();
return false;
}
bool undone = true;
for (int i = 0; i < PLUGIN_BUFFERS; i++) {
undone &= BlackBerry::Platform::Graphics::reallocBuffer(m_pluginBuffers[i],
m_pluginBufferSize, m_pluginBufferType);
}
if (!undone)
destroyBuffers();
return false;
}
bool PluginViewPrivate::destroyBuffers()
{
bool didDestroyBuffers = false;
{
PthreadMutexLocker backLock(&m_backBufferMutex);
PthreadWriteLocker frontLock(&m_frontBufferRwLock);
for (int i = 0; i < PLUGIN_BUFFERS; i++) {
if (m_pluginBuffers[i]) {
didDestroyBuffers = true;
BlackBerry::Platform::Graphics::destroyBuffer(m_pluginBuffers[i]);
m_pluginBuffers[i] = 0;
}
}
m_pluginBufferSize = IntSize();
}
if (didDestroyBuffers) {
BlackBerry::Platform::userInterfaceThreadMessageClient()->dispatchSyncMessage(
BlackBerry::Platform::createFunctionCallMessage(&BlackBerry::Platform::Graphics::collectThreadSpecificGarbage));
}
return true;
}
}