28#if SO3_WEB_NAVIGATOR_BUILD == 1
32 namespace EmbeddedWebNavigator
35 WebNavigatorRenderHandler::WebNavigatorRenderHandler(CefRefPtr<WebNavigatorClient>& parentWebNavigatorClientInstance,
const ScolWindowHandle& scolMainWindow,
bool offscreen) :
WebNavigatorHandler(parentWebNavigatorClientInstance, scolMainWindow),
36 isOffscreen(offscreen)
39 offscreenBufferMemorySize = 0;
40 offscreenBuffer_width = 512;
41 offscreenBuffer_height = 512;
42 offscreenPopupBuffer = 0;
43 offscreenPopupRect.Set(0, 0, 0, 0);
44 bufferContentChanged =
false;
57 free(offscreenBuffer);
59 offscreenBufferMemorySize = 0;
61 if (offscreenPopupBuffer)
63 free(offscreenPopupBuffer);
64 offscreenPopupBuffer = 0;
65 offscreenPopupRect.Set(0, 0, 0, 0);
71 bufferContentChanged =
false;
73 return offscreenBuffer;
80 bufferContentChanged =
false;
82 return offscreenPopupBuffer;
89 assert(CefCurrentlyOn(TID_UI));
94 rect.width = size.first;
95 rect.height = size.second;
104 assert(CefCurrentlyOn(TID_UI));
109 std::unique_lock< std::shared_mutex > lock(offscreenBufferCriticalSection);
114 offscreenPopupRect.Set(0, 0, 0, 0);
115 if (offscreenPopupBuffer != 0)
118 free(offscreenPopupBuffer);
119 offscreenPopupBuffer = 0;
122 bufferContentChanged =
true;
131 assert(CefCurrentlyOn(TID_UI));
136 std::unique_lock< std::shared_mutex > lock(offscreenBufferCriticalSection);
141 assert(((rect.x + rect.width) <
static_cast<int>(offscreenBuffer_width)) && ((rect.y + rect.height) <
static_cast<int>(offscreenBuffer_height)));
144 if ((offscreenPopupRect.width * offscreenPopupRect.height) != (rect.width * rect.height))
147 if (offscreenPopupBuffer != 0)
148 free(offscreenPopupBuffer);
151 size_t neededMemory = rect.width * rect.height * 4;
152 offscreenPopupBuffer = (
unsigned char*)malloc(neededMemory);
153 memset(offscreenPopupBuffer, 0xF, neededMemory);
157 offscreenPopupRect = rect;
162 void WebNavigatorRenderHandler::OnPaint(CefRefPtr<CefBrowser> browser, CefRenderHandler::PaintElementType type,
const CefRenderHandler::RectList& dirtyRects,
const void* buffer,
int width,
int height)
167 std::unique_lock< std::shared_mutex > lock(offscreenBufferCriticalSection);
168 if (!dirtyRects.empty())
170 assert(CefCurrentlyOn(TID_UI));
172 if (type == PET_VIEW)
175 SetRGB(browser, width, height, buffer, dirtyRects);
176 bufferContentChanged =
true;
179 if (type == PET_POPUP)
182 if (offscreenPopupBuffer != 0)
183 memcpy(offscreenPopupBuffer, (
unsigned char*)buffer, offscreenPopupRect.width * offscreenPopupRect.height * 4);
193 assert(CefCurrentlyOn(TID_UI));
201 void WebNavigatorRenderHandler::SetRGB(CefRefPtr<CefBrowser> browser,
int width,
int height,
const void* src,
const RectList& dirtyRects)
203 SetBufferSize(width, height);
204 ConvertToRGBA((
unsigned char*)src, offscreenBuffer, dirtyRects, width, height);
209 return offscreenBuffer_width;
214 return offscreenBuffer_height;
219 return bufferContentChanged;
224 return offscreenPopupRect;
227 void WebNavigatorRenderHandler::SetBufferSize(
int width,
int height)
229 size_t dst_size = width * height * 4 *
sizeof(
unsigned char);
232 offscreenBuffer_width = width;
233 offscreenBuffer_height = height;
235 if (dst_size != offscreenBufferMemorySize)
238 free(offscreenBuffer);
240 offscreenBufferMemorySize = dst_size;
241 offscreenBuffer = (
unsigned char*)malloc(offscreenBufferMemorySize);
242 memset(offscreenBuffer, 0xF, offscreenBufferMemorySize);
246 void WebNavigatorRenderHandler::ConvertToRGBA(
const unsigned char* src,
unsigned char* dst,
const RectList& dirtyRects,
int renderSizeWidth,
int renderSizeHeight)
249 RectList::const_iterator iDirtyRects = dirtyRects.begin();
250 while (iDirtyRects != dirtyRects.end())
253 size_t initialOffset = ((((*iDirtyRects).y * renderSizeWidth) + (*iDirtyRects).x)) * 4;
254 size_t offset = initialOffset;
257 for (
int i = 0; i < (*iDirtyRects).height; i++)
259 memcpy(dst + offset, src + offset, (*iDirtyRects).width * 4);
260 offset += (renderSizeWidth * 4);
276 std::shared_lock< std::shared_mutex > lock(offscreenBufferCriticalSection);
278 if ((offscreenBuffer_width == destWidth) && (offscreenBuffer_height == destHeight))
281 unsigned long srcByte = 0;
282 unsigned long destByte = 0;
288 for (
long y = 0; y < destHeight; y++)
290 for (
long x = 0; x < destWidth; x++)
292 srcByte = (x + (destWidth * y)) * 4;
293 destByte = (x * destBytesPerPixel) + (y * destBitsPerLine);
295 dest[destByte] = buffer[srcByte];
296 dest[destByte + 1] = buffer[srcByte + 1];
297 dest[destByte + 2] = buffer[srcByte + 2];
307 for (
long y = 0; y < offscreenPopupBufferRect.height; y++)
309 for (
long x = 0; x < offscreenPopupBufferRect.width; x++)
311 srcByte = (x + (y * offscreenPopupBufferRect.width)) * 4;
312 destByte = ((x + offscreenPopupBufferRect.x) * destBytesPerPixel) + ((offscreenPopupBufferRect.y + y) * destBitsPerLine);
314 dest[destByte] = buffer[srcByte];
315 dest[destByte + 1] = buffer[srcByte + 1];
316 dest[destByte + 2] = buffer[srcByte + 2];
330 std::shared_lock< std::shared_mutex > lock(offscreenBufferCriticalSection);
332 if ((offscreenBuffer_width == destWidth) && (offscreenBuffer_height == destHeight))
335 unsigned long srcByte = 0;
336 unsigned long destByte = 0;
337 unsigned long alphaLineOffset = 0;
343 for (
long y = 0; y < destHeight; y++)
345 alphaLineOffset = y * destWidth;
346 for (
long x = 0; x < destWidth; x++)
348 srcByte = (x + (y * destWidth)) * 4;
349 destByte = (x * destColorBytesPerPixel) + (y * destColorBitsPerLine);
351 destColor[destByte] = buffer[srcByte];
352 destColor[destByte + 1] = buffer[srcByte + 1];
353 destColor[destByte + 2] = buffer[srcByte + 2];
354 destAlpha[x + alphaLineOffset] = buffer[srcByte + 3];
364 for (
long y = 0; y < offscreenPopupBufferRect.height; y++)
366 alphaLineOffset = (y * offscreenPopupBufferRect.width);
367 for (
long x = 0; x < offscreenPopupBufferRect.width; x++)
369 srcByte = (x + (y * offscreenPopupBufferRect.width)) * 4;
370 destByte = ((x + offscreenPopupBufferRect.x) * destColorBytesPerPixel) + ((offscreenPopupBufferRect.y + y) * destColorBitsPerLine);
372 destColor[destByte] = buffer[srcByte];
373 destColor[destByte + 1] = buffer[srcByte + 1];
374 destColor[destByte + 2] = buffer[srcByte + 2];
375 destAlpha[x + alphaLineOffset] = buffer[srcByte + 3];
388 bool returnValue =
false;
389 if (forceUpdate || bufferContentChanged)
392 std::shared_lock< std::shared_mutex > lock(offscreenBufferCriticalSection);
396 Ogre::HardwarePixelBufferSharedPtr pixelBuffer = ogreTexture->getBuffer();
397 pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
398 const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock();
402 if (cefRenderBuffer != 0)
405 const Ogre::PixelBox scolPixelBox(offscreenBuffer_width, offscreenBuffer_height, 1, Ogre::PF_BYTE_BGRA, cefRenderBuffer);
408 Ogre::Image::scale(scolPixelBox, pixelBox);
414 if (cefRenderBuffer != 0)
416 float ratio =
static_cast<float>(pixelBox.getWidth()) /
static_cast<float>(offscreenBuffer_width);
417 Ogre::PixelBox targetPixelBox = pixelBox.getSubVolume(Ogre::Box(
static_cast<size_t>(offscreenPopupBufferRect.x * ratio),
418 static_cast<size_t>(offscreenPopupBufferRect.y * ratio),
419 static_cast<size_t>((offscreenPopupBufferRect.width + offscreenPopupBufferRect.x) * ratio),
420 static_cast<size_t>((offscreenPopupBufferRect.height + offscreenPopupBufferRect.y) * ratio)));
423 const Ogre::PixelBox scolPixelBox(offscreenPopupBufferRect.width, offscreenPopupBufferRect.height, 1, Ogre::PF_BYTE_BGRA, cefRenderBuffer);
426 Ogre::Image::scale(scolPixelBox, targetPixelBox);
430 pixelBuffer->unlock();
433 catch (
const Ogre::Exception&)
443 bool returnValue =
false;
445 if (
GetOffscreenBuffer() && (posX <
static_cast<int>(offscreenBuffer_width)) && (posY <
static_cast<int>(offscreenBuffer_height)))
447 std::shared_lock< std::shared_mutex > lock(offscreenBufferCriticalSection);
449 int color = buf[(((posX * 4) + (offscreenBuffer_width * 4) * posY) + 3) *
sizeof(
unsigned char)];
450 if (color > transparentTresholdColor * 255)
WebNavigator * parentWebNavigator
CefRefPtr< WebNavigatorClient > parentWebNavigatorClient
unsigned long GetUniqueId()
std::pair< int, int > GetSize()
boost::asio::io_service mainThreadWebMessageQueue
static WebNavigatorManager * GetSingletonPtr()
void InvokeCursorChange(unsigned long uniqueId, HCURSOR newCursor)
unsigned char * GetOffscreenPopupBuffer()
virtual void OnPopupShow(CefRefPtr< CefBrowser > browser, bool show) OVERRIDE
~WebNavigatorRenderHandler()
virtual bool GetViewRect(CefRefPtr< CefBrowser > browser, CefRect &rect)
virtual void OnCursorChange(CefRefPtr< CefBrowser > browser, CefCursorHandle cursor, CursorType type, const CefCursorInfo &custom_cursor_info) OVERRIDE
unsigned int GetOffscreenBufferHeight()
virtual void OnPaint(CefRefPtr< CefBrowser > browser, CefRenderHandler::PaintElementType type, const CefRenderHandler::RectList &dirtyRects, const void *buffer, int width, int height) OVERRIDE
bool GetOffscreenBufferContentChanged()
bool BlitOffscreenTexture(Ogre::TexturePtr &ogreTexture, bool forceUpdate)
unsigned char * GetOffscreenBuffer()
bool BlitOffscreenBitmap(unsigned char *dest, int destWidth, int destHeight, int destBytesPerPixel, int destBitsPerLine)
virtual void OnPopupSize(CefRefPtr< CefBrowser > browser, const CefRect &rect) OVERRIDE
CefRect GetOffscreenPopupBufferRect()
unsigned int GetOffscreenBufferWidth()
bool CheckPixelAlpha(int posX, int posY, float transparentTresholdColor)
bool BlitOffscreenAlphaBitmap(unsigned char *destColor, unsigned char *destAlpha, int destWidth, int destHeight, int destColorBytesPerPixel, int destColorBitsPerLine)