//------------------------------------------------------------------------------
// emViewRenderer.h
//
// Copyright (C) 2016-2017 Oliver Hamann.
//
// Homepage: http://eaglemode.sourceforge.net/
//
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License version 3 as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
// more details.
//
// You should have received a copy of the GNU General Public License version 3
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------

#ifndef emViewRenderer_h
#define emViewRenderer_h

#ifndef emClipRects_h
#include <emCore/emClipRects.h>
#endif

#ifndef emRenderThreadPool_h
#include <emCore/emRenderThreadPool.h>
#endif

#ifndef emView_h
#include <emCore/emView.h>
#endif


//==============================================================================
//=============================== emViewRenderer ===============================
//==============================================================================

class emViewRenderer : public emUncopyable {

public:

        // Helper class for rendering views by multiple threads concurrently.
        // This uses emRenderThreadPool.

        emViewRenderer(emRootContext & rootContext);
        virtual ~emViewRenderer();

        void RenderView(
                const emViewPort & viewPort,
                const emClipRects<int> & invalidRects
        );
                // Render a view.
                // Arguments:
                //   viewPort     - The view port of the view.
                //   invalidRects - Which parts of the view are to be rendered, in
                //                  screen coordinates.

protected:

        virtual void PrepareBuffers(
                int bufCount, int maxWidth, int maxHeight
        ) = 0;
                // Prepare image buffers for rendering. Called rarely.
                // Arguments:
                //   bufCount  - Number of buffers.
                //   maxWidth  - Maximum used width of the buffer, in pixels.
                //   maxHeight - Maximum used height of the buffer, in pixels.

        virtual emPainter GetBufferPainter(
                int bufIndex, int x, int y, int w, int h
        ) = 0;
                // Get a painter for painting to a buffer.
                // Arguments:
                //   bufIndex  - Buffer index.
                //   x,y,w,h   - Rectangle on the screen to be updated.
                //               w and h are never larger than said with
                //               PrepareBuffers(...).

        virtual void AsyncFlushBuffer(
                int bufIndex, int x, int y, int w, int h
        ) = 0;
                // Flush a buffer to the screen. This has to be thread-safe.
                // The Arguments:
                //   bufIndex  - Buffer index.
                //   x,y,w,h   - Rectangle on the screen to be updated (same
                //               as in call to GetBufferPainter(...) before).

private:

        struct TodoRect {
                int x,y,w,h;
        };

        static void ThreadFunc(void * data, int bufIndex);
        void ThreadRun(int bufIndex);

        emRef<emRenderThreadPool> ThreadPool;
        int BufCount;
        int BufWidth;
        int BufHeight;
        const emViewPort * CurrentViewPort;
        emThreadMiniMutex UserSpaceMutex;
        emArray<TodoRect> TodoRects;
        int TrIndex;
};


#endif