Offscreen rendering example

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

Offscreen rendering example

Postby aflopes » Thu Oct 12, 2017 10:41 am

Hi all,

I'm using the Cef off-screen rendering example in https://github.com/qwertzui11/cef_osr as guide to add CEF into a custom DirectX application, and I'm running into problems :D

My application starts as expected, but the RenderHandler OnPaint method is only called once. I've runned the cefClient with the example with the argument --off-screen-rendering-enabled, and the OnPaint method on ClientHandlerOsr class is called several times as expected, so it seems to be an issue in my application.

Since this example is a little bit old, is it still up to date? As something changed in CEF that needs to be integrated into this example?

Bellow is the CEF related code that I'm using in my application.

Controller Class that initializes CEF
The Update() is called always before rendering a new frame of the application
Code: Select all
//Header File
namespace Generic
{
   class EmbeddedBrowserController : public ControllerBase
   {
   public:
      EmbeddedBrowserController (const std::string& name);
      ~EmbeddedBrowserController ();
   protected:
      virtual void OnLoad (const std::string& config);
   private:
      virtual void Update();
      EmbeddedBrowser::BrowserClient* m_Browser;
      EmbeddedBrowser::RenderHandler* m_RenderHandler;
      DynamicTexturePanel* m_texturePanel;
   };
}

//CPP file
namespace Generic
{
   EmbeddedBrowserController::EmbeddedBrowserController( const std::string& name )
      : ControllerBase (name)
   {
      
      m_texturePanel = new DynamicTexturePanel (this, GetName()+"::texture", SCREENPOS(0,0), XYSIZEF32(500,500));
      m_RenderHandler = new EmbeddedBrowser::RenderHandler(m_texturePanel);
   }

   EmbeddedBrowserController::~EmbeddedBrowserController()
   {
      CefShutdown();
   }

   void EmbeddedBrowserController::OnLoad( const std::string& config )
   {
      //Initialize DyanmicTexturePanel
      m_texturePanel->InitialiseTexture(false, DynamicTexturePanel::TX_FMT_32BBP, 500, 500);
      m_texturePanel->SetSize(XYSIZEF32(500, 500));

      CefMainArgs mainArgs;
      CefSettings appSettings;
      CefBrowserSettings browserSettings;
      CefRefPtr<CefApp> cefApplication;

      //Initialize CEF
      appSettings.windowless_rendering_enabled = true;
      if (CefInitialize(mainArgs, appSettings, cefApplication, NULL))
      {
         throw new std::exception("Error initializing CEF based embedded browser");
      }

      CefRefPtr<CefBrowser> browser;
      CefRefPtr<EmbeddedBrowser::BrowserClient> browserClient;
      {
         CefWindowInfo window_info;
         CefBrowserSettings browserSettings;
         window_info.SetAsWindowless(GetWindowHandle());
         browserClient = new EmbeddedBrowser::BrowserClient(m_RenderHandler);
         browser = CefBrowserHost::CreateBrowserSync(window_info, browserClient.get(), "http://www.google.com", browserSettings, nullptr);
      }
   }

   void EmbeddedBrowserController::Update()
   {
      CefDoMessageLoopWork();
   }
}


BrowserClient class
Code: Select all
//Header File
#include "include/cef_client.h"
#include "RenderHandler.h"

namespace Generic{

   namespace EmbeddedBrowser{

      class BrowserClient : public CefClient
      {
      public:
         BrowserClient(RenderHandler *renderHandler);

         virtual CefRefPtr<CefRenderHandler> GetRenderHandler();

      private:
         CefRefPtr<CefRenderHandler> m_renderHandler;

         IMPLEMENT_REFCOUNTING(BrowserClient);
      };
   }
}

//CPP File
#include "BrowserClient.h"

namespace Generic{

   namespace EmbeddedBrowser{

      BrowserClient::BrowserClient(RenderHandler *renderHandler)
         : m_renderHandler(renderHandler)
      {}

      CefRefPtr<CefRenderHandler> BrowserClient::GetRenderHandler() {
         return m_renderHandler;
      }
   }
}


RenderHandler class
Code: Select all
//Header File
#include "include/cef_render_handler.h"

namespace Generic{

   namespace EmbeddedBrowser{

      class RenderHandler : public CefRenderHandler
      {
      public:
         RenderHandler(DynamicTexturePanel* renderTexture);
         bool GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect);
         void OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList &dirtyRects, const void *buffer, int width, int height);

      private:
         DynamicTexturePanel* m_renderTexture;

         IMPLEMENT_REFCOUNTING(RenderHandler);
      };
   }
}

//CPP File
#include "RenderHandler.h"

namespace Generic{

   namespace EmbeddedBrowser{

      RenderHandler::RenderHandler(DynamicTexturePanel* renderTexture)
         : m_renderTexture(renderTexture)
      {}

      bool RenderHandler::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect)
      {
         rect = CefRect(0, 0, m_renderTexture->GetTextureSize().mXValue,  m_renderTexture->GetTextureSize().mYValue);
         return true;
      }

      void RenderHandler::OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList &dirtyRects, const void *buffer, int width, int height)
      {
         DynamicTexturePanel::LockedTextureInfo textureInfo = m_renderTexture->LockTexture();
         memcpy(textureInfo.buffer, buffer, width*height*4);
         m_renderTexture->UnlockTexture();
         m_renderTexture->Show();
      }
   }
}
aflopes
Newbie
 
Posts: 6
Joined: Thu Oct 12, 2017 10:00 am

Re: Offscreen rendering example

Postby magreenblatt » Thu Oct 12, 2017 11:04 am

Is this on Windows? If so, use CefSettings.multi_threaded_message_loop instead of CefDoMessageLoopWork. Also check that the size returned from GetViewRect is valid.
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: Offscreen rendering example

Postby aflopes » Thu Oct 12, 2017 11:44 am

Yes it's on windows.

With the multi threaded message loop I have the error
Code: Select all
Check failed: false. called on invalid thread

on the call to
Code: Select all
CefBrowserHost::CreateBrowserSync(window_info, browserClient.get(), "http://www.google.com", browserSettings, nullptr);


Without the multi thread message loop, the GetViewRect has the correct size, 500x500 that is the size of the target texture.

I've also fixed an issue that I had,. I've changed
Code: Select all
if (CefInitialize(mainArgs, appSettings, cefApplication, NULL))
{
    throw new std::exception("Error initializing CEF based embedded browser");
}

to
Code: Select all
if (!CefInitialize(mainArgs, appSettings, cefApplication, NULL))
{
     throw new std::exception("Error initializing CEF based embedded browser");
}
Last edited by aflopes on Thu Oct 12, 2017 3:34 pm, edited 1 time in total.
aflopes
Newbie
 
Posts: 6
Joined: Thu Oct 12, 2017 10:00 am

Re: Offscreen rendering example

Postby aflopes » Thu Oct 12, 2017 11:48 am

Well, after that fix on the CefInitialize the OnPaint started working, but I had a previous version without that problem that wasn't working... this is akward, I don't know What I've done in order to fix it, but it is fixed.

Thanks for all the help!
aflopes
Newbie
 
Posts: 6
Joined: Thu Oct 12, 2017 10:00 am

Re: Offscreen rendering example

Postby magreenblatt » Thu Oct 12, 2017 12:44 pm

Use CreateBrowser instead of CreateBrowserSync to fix the check failed.
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: Offscreen rendering example

Postby aflopes » Fri Oct 13, 2017 9:57 am

That fixed it!

Thanks for the help
aflopes
Newbie
 
Posts: 6
Joined: Thu Oct 12, 2017 10:00 am


Return to Support Forum

Who is online

Users browsing this forum: Google [Bot] and 33 guests