GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/render/graphics.cpp Lines: 105 254 41.3 %
Date: 2017-11-29 Branches: 35 154 22.7 %

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

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