<commit_before>#include "../base/mutex.hpp"
#include "../base/timer.hpp"
#include "../base/logging.hpp"

#include "../std/bind.hpp"

#include "../yg/internal/opengl.hpp"
#include "../yg/render_state.hpp"
#include "../yg/rendercontext.hpp"
#include "../yg/framebuffer.hpp"
#include "../yg/renderbuffer.hpp"
#include "../yg/resource_manager.hpp"
#include "../yg/screen.hpp"
#include "../yg/pen_info.hpp"
#include "../yg/skin.hpp"
#include "../yg/base_texture.hpp"
#include "../yg/info_layer.hpp"
#include "../yg/tile.hpp"

#include "../indexer/scales.hpp"

#include "events.hpp"
#include "drawer_yg.hpp"
#include "window_handle.hpp"
#include "render_queue_routine.hpp"
#include "render_queue.hpp"

RenderQueueRoutine::Command::Command(yg::Tiler::RectInfo const & rectInfo,
                                     render_fn_t renderFn,
                                     size_t seqNum)
  : m_rectInfo(rectInfo),
    m_renderFn(renderFn),
    m_seqNum(seqNum)
{}

RenderQueueRoutine::RenderQueueRoutine(string const & skinName,
                                       bool isBenchmarking,
                                       unsigned scaleEtalonSize,
                                       yg::Color const & bgColor,
                                       size_t threadNum,
                                       RenderQueue * renderQueue)
  : m_threadNum(threadNum),
    m_renderQueue(renderQueue)
{
  m_skinName = skinName;
  m_visualScale = 0;
  m_isBenchmarking = isBenchmarking;
  m_scaleEtalonSize = scaleEtalonSize;
  m_bgColor = bgColor;
}

void RenderQueueRoutine::Cancel()
{
  IRoutine::Cancel();
  /// ...Or cancelling the current rendering command in progress.
  if (m_currentCommand != 0)
    m_currentCommand->m_paintEvent->setIsCancelled(true);
}

void RenderQueueRoutine::setVisualScale(double visualScale)
{
  m_visualScale = visualScale;
}

void RenderQueueRoutine::Do()
{
  m_renderContext->makeCurrent();

  m_frameBuffer = make_shared_ptr(new yg::gl::FrameBuffer());

  unsigned tileWidth = m_resourceManager->tileTextureWidth();
  unsigned tileHeight = m_resourceManager->tileTextureHeight();

  shared_ptr<yg::gl::RenderBuffer> depthBuffer(new yg::gl::RenderBuffer(tileWidth, tileHeight, true));
  m_frameBuffer->setDepthBuffer(depthBuffer);

  DrawerYG::params_t params;

  shared_ptr<yg::InfoLayer> infoLayer(new yg::InfoLayer());

  params.m_resourceManager = m_resourceManager;
  params.m_frameBuffer = m_frameBuffer;
  params.m_infoLayer = infoLayer;
  params.m_glyphCacheID = m_resourceManager->renderThreadGlyphCacheID(m_threadNum);
  params.m_useOverlay = true;
  params.m_threadID = m_threadNum;
/*  params.m_isDebugging = true;
  params.m_drawPathes = false;
  params.m_drawAreas = false;
  params.m_drawTexts = false; */

  m_threadDrawer = make_shared_ptr(new DrawerYG(m_skinName, params));
  m_threadDrawer->onSize(tileWidth, tileHeight);

  CHECK(m_visualScale != 0, ("VisualScale is not set"));
  m_threadDrawer->SetVisualScale(m_visualScale);

  ScreenBase frameScreen;
  m2::RectI renderRect(1, 1, tileWidth - 1, tileWidth - 1);

  frameScreen.OnSize(renderRect);

  while (!IsCancelled())
  {
    {
      threads::MutexGuard guard(m_mutex);

      m_currentCommand = m_renderQueue->RenderCommands().Front(true);

      if (m_renderQueue->RenderCommands().IsCancelled())
      {
        LOG(LINFO, (m_threadNum, " cancelled on renderCommands"));
        break;
      }

      m_currentCommand->m_paintEvent = make_shared_ptr(new PaintEvent(m_threadDrawer));

      /// commands from the previous sequence are ignored
      if (m_currentCommand->m_seqNum < m_renderQueue->CurrentSequence())
        continue;

      bool hasTile = false;

      m_renderQueue->TileCache().lock();
      hasTile = m_renderQueue->TileCache().hasTile(m_currentCommand->m_rectInfo);
      m_renderQueue->TileCache().unlock();

      if (hasTile)
        continue;
    }

    if (IsCancelled())
      break;

    my::Timer timer;

    shared_ptr<yg::gl::BaseTexture> tileTarget;

    tileTarget = m_resourceManager->renderTargets().Front(true);

    if (m_resourceManager->renderTargets().IsCancelled())
    {
      LOG(LINFO, (m_threadNum, " cancelled on renderTargets"));
      break;
    }

    m_threadDrawer->screen()->setRenderTarget(tileTarget);

    m_threadDrawer->beginFrame();

    m_threadDrawer->clear(yg::Color(m_bgColor.r, m_bgColor.g, m_bgColor.b, 0));
    m_threadDrawer->screen()->setClipRect(renderRect);
    m_threadDrawer->clear(m_bgColor);

//    frameScreen.OnSize(renderRect);
    frameScreen.SetFromRect(m_currentCommand->m_rectInfo.m_rect);

/*    m2::RectI r0(renderRect);
    m2::RectD r1;

    r0.Inflate(40.0, 40.0);

    frameScreen.PtoG(m2::RectD(r0), r1);

    frameScreen.OnSize(r0);
    frameScreen.SetFromRect(r1);*/

    m_currentCommand->m_renderFn(
        m_currentCommand->m_paintEvent,
        frameScreen,
        m_currentCommand->m_rectInfo.m_rect,
        m_currentCommand->m_rectInfo.m_drawScale);

    /// rendering all collected texts
//      m_infoLayer->draw(m_threadDrawer->screen().get(), math::Identity<double, 3>());

    m_threadDrawer->endFrame();

    double duration = timer.ElapsedSeconds();

    if (!IsCancelled())
    {
      /// We shouldn't update the actual target as it's already happened (through callback function)
      /// in the endFrame function
      /// updateActualTarget();

      {
        threads::MutexGuard guard(m_mutex);

        if (!m_currentCommand->m_paintEvent->isCancelled())
        {
          yg::Tile tile(tileTarget, frameScreen, m_currentCommand->m_rectInfo, duration);
          m_renderQueue->TileCache().lock();
          m_renderQueue->TileCache().addTile(m_currentCommand->m_rectInfo, yg::TileCache::Entry(tile, m_resourceManager));
          m_renderQueue->TileCache().unlock();
        }

        m_currentCommand.reset();<commit_msg>fixed geometry clipping artefacts on tile borders.<commit_after>#include "../base/mutex.hpp"
#include "../base/timer.hpp"
#include "../base/logging.hpp"

#include "../std/bind.hpp"

#include "../yg/internal/opengl.hpp"
#include "../yg/render_state.hpp"
#include "../yg/rendercontext.hpp"
#include "../yg/framebuffer.hpp"
#include "../yg/renderbuffer.hpp"
#include "../yg/resource_manager.hpp"
#include "../yg/screen.hpp"
#include "../yg/pen_info.hpp"
#include "../yg/skin.hpp"
#include "../yg/base_texture.hpp"
#include "../yg/info_layer.hpp"
#include "../yg/tile.hpp"

#include "../indexer/scales.hpp"

#include "events.hpp"
#include "drawer_yg.hpp"
#include "window_handle.hpp"
#include "render_queue_routine.hpp"
#include "render_queue.hpp"

RenderQueueRoutine::Command::Command(yg::Tiler::RectInfo const & rectInfo,
                                     render_fn_t renderFn,
                                     size_t seqNum)
  : m_rectInfo(rectInfo),
    m_renderFn(renderFn),
    m_seqNum(seqNum)
{}

RenderQueueRoutine::RenderQueueRoutine(string const & skinName,
                                       bool isBenchmarking,
                                       unsigned scaleEtalonSize,
                                       yg::Color const & bgColor,
                                       size_t threadNum,
                                       RenderQueue * renderQueue)
  : m_threadNum(threadNum),
    m_renderQueue(renderQueue)
{
  m_skinName = skinName;
  m_visualScale = 0;
  m_isBenchmarking = isBenchmarking;
  m_scaleEtalonSize = scaleEtalonSize;
  m_bgColor = bgColor;
}

void RenderQueueRoutine::Cancel()
{
  IRoutine::Cancel();
  /// ...Or cancelling the current rendering command in progress.
  if (m_currentCommand != 0)
    m_currentCommand->m_paintEvent->setIsCancelled(true);
}

void RenderQueueRoutine::setVisualScale(double visualScale)
{
  m_visualScale = visualScale;
}

void RenderQueueRoutine::Do()
{
  m_renderContext->makeCurrent();

  m_frameBuffer = make_shared_ptr(new yg::gl::FrameBuffer());

  unsigned tileWidth = m_resourceManager->tileTextureWidth();
  unsigned tileHeight = m_resourceManager->tileTextureHeight();

  shared_ptr<yg::gl::RenderBuffer> depthBuffer(new yg::gl::RenderBuffer(tileWidth, tileHeight, true));
  m_frameBuffer->setDepthBuffer(depthBuffer);

  DrawerYG::params_t params;

  shared_ptr<yg::InfoLayer> infoLayer(new yg::InfoLayer());

  params.m_resourceManager = m_resourceManager;
  params.m_frameBuffer = m_frameBuffer;
  params.m_infoLayer = infoLayer;
  params.m_glyphCacheID = m_resourceManager->renderThreadGlyphCacheID(m_threadNum);
  params.m_useOverlay = true;
  params.m_threadID = m_threadNum;
/*  params.m_isDebugging = true;
  params.m_drawPathes = false;
  params.m_drawAreas = false;
  params.m_drawTexts = false; */

  m_threadDrawer = make_shared_ptr(new DrawerYG(m_skinName, params));
  m_threadDrawer->onSize(tileWidth, tileHeight);

  CHECK(m_visualScale != 0, ("VisualScale is not set"));
  m_threadDrawer->SetVisualScale(m_visualScale);

  ScreenBase frameScreen;
  m2::RectI renderRect(1, 1, tileWidth - 1, tileWidth - 1);

  frameScreen.OnSize(renderRect);

  while (!IsCancelled())
  {
    {
      threads::MutexGuard guard(m_mutex);

      m_currentCommand = m_renderQueue->RenderCommands().Front(true);

      if (m_renderQueue->RenderCommands().IsCancelled())
      {
        LOG(LINFO, (m_threadNum, " cancelled on renderCommands"));
        break;
      }

      m_currentCommand->m_paintEvent = make_shared_ptr(new PaintEvent(m_threadDrawer));

      /// commands from the previous sequence are ignored
      if (m_currentCommand->m_seqNum < m_renderQueue->CurrentSequence())
        continue;

      bool hasTile = false;

      m_renderQueue->TileCache().lock();
      hasTile = m_renderQueue->TileCache().hasTile(m_currentCommand->m_rectInfo);
      m_renderQueue->TileCache().unlock();

      if (hasTile)
        continue;
    }

    if (IsCancelled())
      break;

    my::Timer timer;

    shared_ptr<yg::gl::BaseTexture> tileTarget;

    tileTarget = m_resourceManager->renderTargets().Front(true);

    if (m_resourceManager->renderTargets().IsCancelled())
    {
      LOG(LINFO, (m_threadNum, " cancelled on renderTargets"));
      break;
    }

    m_threadDrawer->screen()->setRenderTarget(tileTarget);

    m_threadDrawer->beginFrame();

    m_threadDrawer->clear(yg::Color(m_bgColor.r, m_bgColor.g, m_bgColor.b, 0));
    m_threadDrawer->screen()->setClipRect(renderRect);
    m_threadDrawer->clear(m_bgColor);

    frameScreen.SetFromRect(m_currentCommand->m_rectInfo.m_rect);

    m2::RectD selectionRect; // = m_currentCommand->m_rectInfo.m_rect;

    double inflationSize = 24 * m_visualScale;

    frameScreen.PtoG(m2::Inflate(m2::RectD(renderRect), inflationSize, inflationSize), selectionRect);

    m_currentCommand->m_renderFn(
        m_currentCommand->m_paintEvent,
        frameScreen,
        selectionRect,
        m_currentCommand->m_rectInfo.m_drawScale);

    /// rendering all collected texts
//      m_infoLayer->draw(m_threadDrawer->screen().get(), math::Identity<double, 3>());

    m_threadDrawer->endFrame();

    double duration = timer.ElapsedSeconds();

    if (!IsCancelled())
    {
      /// We shouldn't update the actual target as it's already happened (through callback function)
      /// in the endFrame function
      /// updateActualTarget();

      {
        threads::MutexGuard guard(m_mutex);

        if (!m_currentCommand->m_paintEvent->isCancelled())
        {
          yg::Tile tile(tileTarget, frameScreen, m_currentCommand->m_rectInfo, duration);
          m_renderQueue->TileCache().lock();
          m_renderQueue->TileCache().addTile(m_currentCommand->m_rectInfo, yg::TileCache::Entry(tile, m_resourceManager));
          m_renderQueue->TileCache().unlock();
        }

        m_currentCommand.reset();
{'fraction_non_alphanumeric': 0.13060179257362356, 'fraction_numerical': 0.0034997865983781478, 'mean_word_length': 3.3602530703386675, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 95, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3684946', 'n_tokens_mistral': 3809, 'n_tokens_neox': 3692, 'n_words': 589}