GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/render/graphics.cpp Lines: 106 258 41.1 %
Date: 2021-03-17 Branches: 35 152 23.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2004-2009  The Mana World Development Team
4
 *  Copyright (C) 2009-2010  The Mana Developers
5
 *  Copyright (C) 2011-2019  The ManaPlus Developers
6
 *  Copyright (C) 2019-2021  Andrei Karas
7
 *
8
 *  This file is part of The ManaPlus Client.
9
 *
10
 *  This program is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  any later version.
14
 *
15
 *  This program is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License
21
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 */
23
24
/*      _______   __   __   __   ______   __   __   _______   __   __
25
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
26
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
27
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
28
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
29
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
30
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
31
 *
32
 * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
33
 *
34
 *
35
 * Per Larsson a.k.a finalman
36
 * Olof Naessén a.k.a jansem/yakslem
37
 *
38
 * Visit: http://guichan.sourceforge.net
39
 *
40
 * License: (BSD)
41
 * Redistribution and use in source and binary forms, with or without
42
 * modification, are permitted provided that the following conditions
43
 * are met:
44
 * 1. Redistributions of source code must retain the above copyright
45
 *    notice, this list of conditions and the following disclaimer.
46
 * 2. Redistributions in binary form must reproduce the above copyright
47
 *    notice, this list of conditions and the following disclaimer in
48
 *    the documentation and/or other materials provided with the
49
 *    distribution.
50
 * 3. Neither the name of Guichan nor the names of its contributors may
51
 *    be used to endorse or promote products derived from this software
52
 *    without specific prior written permission.
53
 *
54
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
55
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
56
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
57
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
58
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
59
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
60
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
61
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
62
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
63
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65
 */
66
67
#include "render/graphics.h"
68
69
#ifdef USE_OPENGL
70
#include "configuration.h"
71
#include "graphicsmanager.h"
72
#endif  // USE_OPENGL
73
74
#if defined(USE_OPENGL) && defined(USE_X11)
75
#include "render/openglx/mglxinit.h"
76
#endif  // defined(USE_OPENGL) && defined(USE_X11)
77
78
#ifdef USE_OPENGL
79
#include "resources/openglimagehelper.h"
80
#ifndef ANDROID
81
#include "resources/safeopenglimagehelper.h"
82
#endif  // ANDROID
83
#ifdef __native_client__
84
#include "render/nacl/naclfunctions.h"
85
#include "render/nacl/naclgles.h"
86
#endif  // __native_client__
87
#else  // USE_OPENGL
88
#ifndef USE_SDL2
89
#include "resources/imagehelper.h"
90
#endif  // USE_SDL2
91
#endif  // USE_OPENGL
92
93
#ifdef USE_OPENGL
94
#ifdef __APPLE__
95
#include <OpenGL/OpenGL.h>
96
#endif  // __APPLE__
97
#include "render/opengl/mgldefines.h"
98
RENDER_OPENGL_MGLDEFINES_H
99
#endif  // USE_OPENGL
100
101
#include "debug.h"
102
103
#ifdef USE_OPENGL
104
#ifndef GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
105
#define GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
106
#endif  // GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
107
#endif  // USE_OPENGL
108
109
Graphics *mainGraphics A_NONNULLPOINTER = nullptr;
110
111
#ifdef USE_SDL2
112
SDL_Renderer *restrict Graphics::mRenderer = nullptr;
113
#endif  // USE_SDL2
114
#ifdef USE_OPENGL
115
#ifdef USE_SDL2
116
SDL_GLContext Graphics::mGLContext = nullptr;
117
#else  // USE_SDL2
118
119
void *restrict Graphics::mGLContext = nullptr;
120
#endif  // USE_SDL2
121
#endif  // USE_OPENGL
122
123
201
Graphics::Graphics() :
124
    mWidth(0),
125
    mHeight(0),
126
    mActualWidth(0),
127
    mActualHeight(0),
128
    mClipStack(1000),
129
    mWindow(nullptr),
130
    mBpp(0),
131
    mAlpha(false),
132
    mFullscreen(false),
133
    mHWAccel(false),
134
    mRedraw(false),
135
    mDoubleBuffer(false),
136
    mRect(),
137
    mSecure(false),
138
    mOpenGL(RENDER_SOFTWARE),
139
    mEnableResize(false),
140
    mNoFrame(false),
141
    mAllowHighDPI(false),
142
    mName("Unknown"),
143
    mStartFreeMem(0),
144
    mSync(false),
145
    mScale(1),
146
804
    mColor()
147
{
148
201
    mRect.x = 0;
149
201
    mRect.y = 0;
150
201
    mRect.w = 0;
151
201
    mRect.h = 0;
152
201
}
153
154
603
Graphics::~Graphics()
155
{
156
201
    endDraw();
157
201
}
158
159
215
void Graphics::cleanUp()
160
{
161
#ifdef USE_SDL2
162
    if (mRenderer)
163
    {
164
        SDL_DestroyRenderer(mRenderer);
165
        mRenderer = nullptr;
166
    }
167
#ifdef USE_OPENGL
168
    if (mGLContext)
169
    {
170
        SDL_GL_DeleteContext(mGLContext);
171
        mGLContext = nullptr;
172
    }
173
#endif  // USE_OPENGL
174
#endif  // USE_SDL2
175
215
}
176
177
void Graphics::setSync(const bool sync) restrict2
178
{
179
    mSync = sync;
180
}
181
182
77
void Graphics::setMainFlags(const int w, const int h,
183
                            const int scale,
184
                            const int bpp,
185
                            const bool fs,
186
                            const bool hwaccel,
187
                            const bool resize,
188
                            const bool noFrame,
189
                            const bool allowHighDPI) restrict2
190
{
191
77
    logger->log("graphics backend: %s", getName().c_str());
192
77
    logger->log("Setting video mode %dx%d %s",
193
77
            w, h, fs ? "fullscreen" : "windowed");
194
195
77
    mBpp = bpp;
196
77
    mFullscreen = fs;
197
77
    mHWAccel = hwaccel;
198
77
    mEnableResize = resize;
199
77
    mNoFrame = noFrame;
200
77
    mAllowHighDPI = allowHighDPI;
201
77
    mActualWidth = w;
202
77
    mActualHeight = h;
203
77
    setScale(scale);
204
77
}
205
206
77
void Graphics::setScale(int scale) restrict2
207
{
208
77
    if (isAllowScale())
209
    {
210
        if (scale == 0)
211
            scale = 1;
212
        int scaleW = mActualWidth / scale;
213
        int scaleH = mActualHeight / scale;
214
        if (scaleW < 470)
215
        {
216
            scale = mActualWidth / 470;
217
            if (scale < 1)
218
                scale = 1;
219
            scaleH = mActualHeight / scale;
220
        }
221
        if (scaleH < 320)
222
        {
223
            scale = mActualHeight / 320;
224
            if (scale < 1)
225
                scale = 1;
226
        }
227
        logger->log("set scale: %d", scale);
228
        mScale = scale;
229
        mWidth = mActualWidth / mScale;
230
        mHeight = mActualHeight / mScale;
231
    }
232
    else
233
    {
234
77
        mScale = 1;
235
77
        mWidth = mActualWidth;
236
77
        mHeight = mActualHeight;
237
    }
238
77
    mRect.w = static_cast<RectSize>(mWidth);
239
77
    mRect.h = static_cast<RectSize>(mHeight);
240
77
}
241
242
int Graphics::getOpenGLFlags() const restrict2
243
{
244
#ifdef USE_OPENGL
245
246
#ifdef USE_SDL2
247
    int displayFlags = SDL_WINDOW_OPENGL;
248
    if (mFullscreen)
249
        displayFlags |= SDL_WINDOW_FULLSCREEN;
250
#if SDL_VERSION_ATLEAST(2, 0, 1)
251
    if (mAllowHighDPI)
252
        displayFlags |= SDL_WINDOW_ALLOW_HIGHDPI;
253
#endif  // SDL_VERSION_ATLEAST(2, 0, 1)
254
#else  // USE_SDL2
255
256
    int displayFlags = SDL_ANYFORMAT | SDL_OPENGL;
257
#endif  // USE_SDL2
258
259
    if (mFullscreen)
260
    {
261
        displayFlags |= SDL_FULLSCREEN;
262
    }
263
    else
264
    {
265
        // Resizing currently not supported on Windows, where it would require
266
        // reuploading all textures.
267
#if !defined(_WIN32)
268
        if (mEnableResize)
269
            displayFlags |= SDL_RESIZABLE;
270
#endif  // !defined(_WIN32)
271
    }
272
273
    if (mNoFrame)
274
        displayFlags |= SDL_NOFRAME;
275
276
    return displayFlags;
277
#else  // USE_OPENGL
278
279
    return 0;
280
#endif  // USE_OPENGL
281
}
282
283
bool Graphics::setOpenGLMode() restrict2
284
{
285
#ifdef USE_OPENGL
286
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
287
    if ((mWindow = GraphicsManager::createWindow(
288
        mActualWidth, mActualHeight,
289
        mBpp, getOpenGLFlags())) == nullptr)
290
    {
291
        logger->log("Window/context creation failed");
292
        mRect.w = 0;
293
        mRect.h = 0;
294
        return false;
295
    }
296
297
#if defined(USE_X11)
298
    Glx::initFunctions();
299
#endif  // defined(USE_X11)
300
#ifdef __native_client__
301
    NaclGles::initGles();
302
#endif   // __native_client__
303
304
#ifdef USE_SDL2
305
    int w1 = 0;
306
    int h1 = 0;
307
    SDL_GetWindowSize(mWindow, &w1, &h1);
308
    mRect.w = CAST_S32(w1 / mScale);
309
    mRect.h = CAST_S32(h1 / mScale);
310
311
    createGLContext(config.getBoolValue("openglContext"));
312
#else  // USE_SDL2
313
314
    createGLContext(config.getBoolValue("openglContext"));
315
    mRect.w = CAST_U16(mWindow->w / mScale);
316
    mRect.h = CAST_U16(mWindow->h / mScale);
317
318
#endif  // USE_SDL2
319
320
#ifdef __APPLE__
321
    if (mSync)
322
    {
323
        const GLint VBL = 1;
324
        CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &VBL);
325
    }
326
#endif  // __APPLE__
327
328
    graphicsManager.setGLVersion();
329
    graphicsManager.logVersion();
330
331
    // Setup OpenGL
332
    glViewport(0, 0, mActualWidth, mActualHeight);
333
    int gotDoubleBuffer = 0;
334
    SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &gotDoubleBuffer);
335
    logger->log("Using OpenGL %s double buffering.",
336
                (gotDoubleBuffer != 0 ? "with" : "without"));
337
338
    graphicsManager.initOpenGL();
339
    initArrays(graphicsManager.getMaxVertices());
340
    graphicsManager.updateTextureCompressionFormat();
341
    graphicsManager.updateTextureFormat();
342
    updateMemoryInfo();
343
344
    GLint texSize;
345
    bool rectTex = graphicsManager.supportExtension(
346
        "GL_ARB_texture_rectangle") ||
347
        graphicsManager.supportExtension("GL_EXT_texture_rectangle");
348
349
    if (rectTex
350
        && OpenGLImageHelper::getInternalTextureType() == 4
351
        && getOpenGL() != RENDER_GLES_OPENGL
352
        && getOpenGL() != RENDER_GLES2_OPENGL
353
        && getOpenGL() != RENDER_MODERN_OPENGL
354
        && config.getBoolValue("rectangulartextures")
355
        && !graphicsManager.isUseTextureSampler())
356
    {
357
        logger->log1("using GL_ARB_texture_rectangle");
358
        OpenGLImageHelper::mTextureType = GL_TEXTURE_RECTANGLE_ARB;
359
        glEnable(GL_TEXTURE_RECTANGLE_ARB);
360
        glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &texSize);
361
        OpenGLImageHelper::mTextureSize = texSize;
362
        logger->log("OpenGL texture size: %d pixels (rectangle textures)",
363
            OpenGLImageHelper::mTextureSize);
364
#if !defined(ANDROID) && !defined(__SWITCH__)
365
        SafeOpenGLImageHelper::mTextureType = GL_TEXTURE_RECTANGLE_ARB;
366
        SafeOpenGLImageHelper::mTextureSize = texSize;
367
#endif  // ANDROID
368
    }
369
    else
370
    {
371
        glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);
372
        OpenGLImageHelper::mTextureType = GL_TEXTURE_2D;
373
        OpenGLImageHelper::mTextureSize = texSize;
374
#if !defined(ANDROID) && !defined(__SWITCH__)
375
        SafeOpenGLImageHelper::mTextureType = GL_TEXTURE_2D;
376
        SafeOpenGLImageHelper::mTextureSize = texSize;
377
#endif  // ANDROID
378
379
        logger->log("OpenGL texture size: %d pixels",
380
            OpenGLImageHelper::mTextureSize);
381
    }
382
    return videoInfo();
383
#else  // USE_OPENGL
384
385
    return false;
386
#endif  // USE_OPENGL
387
}
388
389
77
int Graphics::getSoftwareFlags() const restrict2
390
{
391
#ifdef USE_SDL2
392
    int displayFlags = SDL_WINDOW_SHOWN;
393
#if SDL_VERSION_ATLEAST(2, 0, 1)
394
    if (mAllowHighDPI)
395
        displayFlags |= SDL_WINDOW_ALLOW_HIGHDPI;
396
#endif  // SDL_VERSION_ATLEAST(2, 0, 1)
397
#else  // USE_SDL2
398
399
77
    int displayFlags = SDL_ANYFORMAT;
400
401
77
    if (mHWAccel)
402
        displayFlags |= SDL_HWSURFACE | SDL_DOUBLEBUF;
403
    else
404
77
        displayFlags |= SDL_SWSURFACE;
405
#endif  // USE_SDL2
406
407
77
    if (mFullscreen)
408
        displayFlags |= SDL_FULLSCREEN;
409
77
    else if (mEnableResize)
410
        displayFlags |= SDL_RESIZABLE;
411
412
77
    if (mNoFrame)
413
        displayFlags |= SDL_NOFRAME;
414
77
    return displayFlags;
415
}
416
417
#ifdef USE_OPENGL
418
void Graphics::createGLContext(const bool custom A_UNUSED) restrict2
419
{
420
#ifdef USE_SDL2
421
    mGLContext = SDL_GL_CreateContext(mWindow);
422
#endif  // USE_SDL2
423
}
424
#endif  // USE_OPENGL
425
426
void Graphics::updateMemoryInfo() restrict2
427
{
428
#ifdef USE_OPENGL
429
    if (mStartFreeMem != 0)
430
        return;
431
432
    if (graphicsManager.supportExtension("GL_NVX_gpu_memory_info"))
433
    {
434
        glGetIntegerv(GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX,
435
            &mStartFreeMem);
436
        logger->log("free video memory: %d", mStartFreeMem);
437
    }
438
#endif  // USE_OPENGL
439
}
440
441
int Graphics::getMemoryUsage() const restrict2
442
{
443
#ifdef USE_OPENGL
444
    if (mStartFreeMem == 0)
445
        return 0;
446
447
    if (graphicsManager.supportExtension("GL_NVX_gpu_memory_info"))
448
    {
449
        GLint val;
450
        glGetIntegerv(GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX,
451
            &val);
452
        return mStartFreeMem - val;
453
    }
454
#endif  // USE_OPENGL
455
    return 0;
456
}
457
458
#ifdef USE_SDL2
459
void Graphics::dumpRendererInfo(const char *restrict const str,
460
                                const SDL_RendererInfo &restrict info)
461
                                restrict2
462
{
463
    logger->log(str, info.name);
464
    logger->log("flags:");
465
    if (info.flags & SDL_RENDERER_SOFTWARE)
466
        logger->log(" software");
467
    if (info.flags & SDL_RENDERER_ACCELERATED)
468
        logger->log(" accelerated");
469
    if (info.flags & SDL_RENDERER_PRESENTVSYNC)
470
        logger->log(" vsync");
471
    if (info.flags & SDL_RENDERER_TARGETTEXTURE)
472
        logger->log(" texture target");
473
    logger->log("max texture size: %d,%d",
474
        info.max_texture_width,
475
        info.max_texture_height);
476
    const size_t sz = CAST_SIZE(info.num_texture_formats);
477
    logger->log("texture formats:");
478
    for (size_t f = 0; f < sz; f ++)
479
        logger->log(" %u", info.texture_formats[f]);
480
}
481
#endif  // USE_SDL2
482
483
77
bool Graphics::videoInfo() restrict2
484
{
485
77
    logger->log("SDL video info");
486
#ifdef USE_SDL2
487
    logger->log("Using video driver: %s", SDL_GetCurrentVideoDriver());
488
489
    if (mRenderer)
490
    {
491
        SDL_RendererInfo info;
492
        SDL_GetRendererInfo(mRenderer, &info);
493
        dumpRendererInfo("Current SDL renderer name: %s", info);
494
495
        const int num = SDL_GetNumRenderDrivers();
496
        logger->log("Known renderers");
497
        for (int f = 0; f < num; f ++)
498
        {
499
            if (!SDL_GetRenderDriverInfo(f, &info))
500
                dumpRendererInfo("renderer name: %s", info);
501
        }
502
    }
503
#else  // USE_SDL2
504
505
    char videoDriverName[65];
506
77
    if (SDL_VideoDriverName(videoDriverName, 64) != nullptr)
507
77
        logger->log("Using video driver: %s", videoDriverName);
508
    else
509
        logger->log1("Using video driver: unknown");
510
77
    mDoubleBuffer = ((mWindow->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF);
511
77
    logger->log("Double buffer mode: %s", mDoubleBuffer ? "yes" : "no");
512
513
77
    ImageHelper::dumpSurfaceFormat(mWindow);
514
515
77
    const SDL_VideoInfo *restrict const vi = SDL_GetVideoInfo();
516
77
    if (vi == nullptr)
517
        return false;
518
519
77
    logger->log("Possible to create hardware surfaces: %s",
520
154
            ((vi->hw_available) != 0U ? "yes" : "no"));
521
77
    logger->log("Window manager available: %s",
522
154
            ((vi->wm_available) != 0U ? "yes" : "no"));
523
77
    logger->log("Accelerated hardware to hardware blits: %s",
524
154
            ((vi->blit_hw) != 0U ? "yes" : "no"));
525
77
    logger->log("Accelerated hardware to hardware colorkey blits: %s",
526
154
            ((vi->blit_hw_CC) != 0U ? "yes" : "no"));
527
77
    logger->log("Accelerated hardware to hardware alpha blits: %s",
528
154
            ((vi->blit_hw_A) != 0U ? "yes" : "no"));
529
77
    logger->log("Accelerated software to hardware blits: %s",
530
154
            ((vi->blit_sw) != 0U ? "yes" : "no"));
531
77
    logger->log("Accelerated software to hardware colorkey blits: %s",
532
154
            ((vi->blit_sw_CC) != 0U ? "yes" : "no"));
533
77
    logger->log("Accelerated software to hardware alpha blits: %s",
534
154
            ((vi->blit_sw_A) != 0U ? "yes" : "no"));
535
77
    logger->log("Accelerated color fills: %s",
536
154
            ((vi->blit_fill) != 0U ? "yes" : "no"));
537
#endif  // USE_SDL2
538
539
    return true;
540
}
541
542
bool Graphics::setFullscreen(const bool fs) restrict2
543
{
544
    if (mFullscreen == fs)
545
        return true;
546
547
    return setVideoMode(mActualWidth,
548
        mActualHeight,
549
        mScale,
550
        mBpp,
551
        fs,
552
        mHWAccel,
553
        mEnableResize,
554
        mNoFrame,
555
        mAllowHighDPI);
556
}
557
558
bool Graphics::resizeScreen(const int width,
559
                            const int height) restrict2
560
{
561
#ifdef USE_SDL2
562
    endDraw();
563
564
    mRect.w = CAST_S32(width / mScale);
565
    mRect.h = CAST_S32(height / mScale);
566
    mWidth = width / mScale;
567
    mHeight = height / mScale;
568
    mActualWidth = width;
569
    mActualHeight = height;
570
571
#ifdef USE_OPENGL
572
    // +++ probably this way will not work in windows/mac
573
    // Setup OpenGL
574
    glViewport(0, 0, mActualWidth, mActualHeight);
575
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
576
#else  // USE_OPENGL
577
    // +++ need impliment resize in soft mode
578
#endif  // USE_OPENGL
579
580
    screenResized();
581
    beginDraw();
582
    return true;
583
584
#else  // USE_SDL2
585
586
    const int prevWidth = mWidth;
587
    const int prevHeight = mHeight;
588
589
    endDraw();
590
591
    bool success = true;
592
#ifdef __native_client__
593
    if (mOpenGL != RENDER_SOFTWARE)
594
    {
595
        mRect.w = CAST_S32(width / mScale);
596
        mRect.h = CAST_S32(height / mScale);
597
        mWidth = width / mScale;
598
        mHeight = height / mScale;
599
        mActualWidth = width;
600
        mActualHeight = height;
601
#ifdef USE_OPENGL
602
        naclResizeBuffers(mActualWidth, mActualHeight);
603
        glViewport(0, 0, mActualWidth, mActualHeight);
604
#endif  // USE_OPENGL
605
    }
606
    else
607
#endif  // __native_client__
608
    {
609
        success = setVideoMode(width, height,
610
            mScale,
611
            mBpp,
612
            mFullscreen,
613
            mHWAccel,
614
            mEnableResize,
615
            mNoFrame,
616
            mAllowHighDPI);
617
618
        // If it didn't work, try to restore the previous size. If that didn't
619
        // work either, bail out (but then we're in deep trouble).
620
        if (!success)
621
        {
622
            if (!setVideoMode(prevWidth, prevHeight,
623
                mScale,
624
                mBpp,
625
                mFullscreen,
626
                mHWAccel,
627
                mEnableResize,
628
                mNoFrame,
629
                mAllowHighDPI))
630
            {
631
                return false;
632
            }
633
        }
634
    }
635
636
    screenResized();
637
    beginDraw();
638
639
    return success;
640
#endif  // USE_SDL2
641
}
642
643
13
int Graphics::getWidth() const restrict2
644
{
645
13
    return mWidth;
646
}
647
648
128
int Graphics::getHeight() const restrict2
649
{
650
128
    return mHeight;
651
}
652
653
void Graphics::drawNet(const int x1, const int y1,
654
                       const int x2, const int y2,
655
                       const int width, const int height) restrict2
656
{
657
    for (int y = y1; y < y2; y += height)
658
        drawLine(x1, y, x2, y);
659
660
    for (int x = x1; x < x2; x += width)
661
        drawLine(x, y1, x, y2);
662
}
663
664
#ifdef USE_SDL2
665
void Graphics::setWindowSize(const int width,
666
                             const int height) restrict2
667
{
668
    SDL_SetWindowSize(mWindow, width, height);
669
}
670
#else  // USE_SDL2
671
void Graphics::setWindowSize(const int width A_UNUSED,
672
                             const int height A_UNUSED) restrict2
673
{
674
}
675
#endif  // USE_SDL2
676
677
571
void Graphics::pushClipArea(const Rect &restrict area) restrict2
678
{
679
    // Ignore area with a negate width or height
680
    // by simple pushing an empty clip area
681
    // to the stack.
682

571
    if (area.width < 0 || area.height < 0)
683
    {
684
        ClipRect &carea = mClipStack.push();
685
        carea.x = 0;
686
        carea.y = 0;
687
        carea.width = 0;
688
        carea.height = 0;
689
        carea.xOffset = 0;
690
        carea.yOffset = 0;
691
        return;
692
    }
693
694
571
    if (mClipStack.empty())
695
    {
696
134
        ClipRect &carea = mClipStack.push();
697
67
        carea.x = area.x;
698
67
        carea.y = area.y;
699
67
        carea.width = area.width;
700
67
        carea.height = area.height;
701
67
        carea.xOffset = area.x;
702
67
        carea.yOffset = area.y;
703
67
        return;
704
    }
705
706
504
    const ClipRect &top = mClipStack.top();
707
1008
    ClipRect &carea = mClipStack.push();
708
504
    carea.x = area.x + top.xOffset;
709
504
    carea.y = area.y + top.yOffset;
710
504
    carea.width = area.width;
711
504
    carea.height = area.height;
712
504
    carea.xOffset = top.xOffset + area.x;
713
504
    carea.yOffset = top.yOffset + area.y;
714
715
    // Clamp the pushed clip rectangle.
716
504
    if (carea.x < top.x)
717
2
        carea.x = top.x;
718
719
504
    if (carea.y < top.y)
720
        carea.y = top.y;
721
722
504
    if (carea.x + carea.width > top.x + top.width)
723
    {
724
433
        carea.width = top.x + top.width - carea.x;
725
726
433
        if (carea.width < 0)
727
369
            carea.width = 0;
728
    }
729
730
504
    if (carea.y + carea.height > top.y + top.height)
731
    {
732
432
        carea.height = top.y + top.height - carea.y;
733
734
432
        if (carea.height < 0)
735
366
            carea.height = 0;
736
    }
737
}
738
739
571
void Graphics::popClipArea() restrict2
740
{
741
571
    if (mClipStack.empty())
742
        return;
743
744
571
    mClipStack.pop();
745
}
746
747
#ifdef USE_OPENGL
748
void Graphics::setOpenGLFlags() restrict2
749
{
750
    // here disable/enable probably need convert to mgl
751
752
    glEnable(GL_SCISSOR_TEST);
753
754
    glDisable(GL_MULTISAMPLE);
755
    glDisable(GL_DITHER);
756
    glDisable(GL_DEPTH_TEST);
757
    glDisable(GL_LINE_SMOOTH);
758
    glDisable(GL_POLYGON_SMOOTH);
759
    glDisable(GL_STENCIL_TEST);
760
    glDisable(GL_COLOR_LOGIC_OP);
761
    glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
762
    glDisable(GL_DEPTH_CLAMP);
763
    glDisable(GL_RASTERIZER_DISCARD);
764
    glDisable(GL_SAMPLE_MASK);
765
766
#ifndef ANDROID
767
#ifndef __MINGW32__
768
    glHint(GL_TEXTURE_COMPRESSION_HINT, GL_FASTEST);
769
#endif  // __MINGW32__
770
#endif  // ANDROID
771
772
    glHint(GL_TEXTURE_COMPRESSION_HINT_ARB, GL_FASTEST);
773
774
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
775
}
776
#endif  // USE_OPENGL