src/video/SDL_blit_slow.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 08 Dec 2019 11:36:40 -0800
changeset 13321 37350f1e7902
parent 13200 057a3fe53d5a
permissions -rw-r--r--
Fixed bug 4883 - Add approximation for display DPI on iOS

Aaron Barany

There appears to be no way to directly access the display DPI on iOS, so as an approximation the DPI for the iPhone 1 is used as a base value and is multiplied by the screen's scale. This should at least give a ballpark number for the various screen scales. (based on https://stackoverflow.com/questions/25756087/detecting-iphone-6-6-screen-sizes-in-point-values it appears that both 2x and 3x are used)

I have updated the patch to use a table of current devices and use a computation as a fallback. I have also updated the fallback computation to be more accurate.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "../SDL_internal.h"
    22 
    23 #include "SDL_video.h"
    24 #include "SDL_blit.h"
    25 #include "SDL_blit_slow.h"
    26 
    27 /* The ONE TRUE BLITTER
    28  * This puppy has to handle all the unoptimized cases - yes, it's slow.
    29  */
    30 void
    31 SDL_Blit_Slow(SDL_BlitInfo * info)
    32 {
    33     const int flags = info->flags;
    34     const Uint32 modulateR = info->r;
    35     const Uint32 modulateG = info->g;
    36     const Uint32 modulateB = info->b;
    37     const Uint32 modulateA = info->a;
    38     Uint32 srcpixel;
    39     Uint32 srcR, srcG, srcB, srcA;
    40     Uint32 dstpixel;
    41     Uint32 dstR, dstG, dstB, dstA;
    42     int srcy, srcx;
    43     int posy, posx;
    44     int incy, incx;
    45     SDL_PixelFormat *src_fmt = info->src_fmt;
    46     SDL_PixelFormat *dst_fmt = info->dst_fmt;
    47     int srcbpp = src_fmt->BytesPerPixel;
    48     int dstbpp = dst_fmt->BytesPerPixel;
    49     Uint32 rgbmask = ~src_fmt->Amask;
    50     Uint32 ckey = info->colorkey & rgbmask;
    51 
    52     srcy = 0;
    53     posy = 0;
    54     incy = (info->src_h << 16) / info->dst_h;
    55     incx = (info->src_w << 16) / info->dst_w;
    56 
    57     while (info->dst_h--) {
    58         Uint8 *src = 0;
    59         Uint8 *dst = info->dst;
    60         int n = info->dst_w;
    61         srcx = -1;
    62         posx = 0x10000L;
    63         while (posy >= 0x10000L) {
    64             ++srcy;
    65             posy -= 0x10000L;
    66         }
    67         while (n--) {
    68             if (posx >= 0x10000L) {
    69                 while (posx >= 0x10000L) {
    70                     ++srcx;
    71                     posx -= 0x10000L;
    72                 }
    73                 src =
    74                     (info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
    75             }
    76             if (src_fmt->Amask) {
    77                 DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
    78                               srcB, srcA);
    79             } else {
    80                 DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
    81                              srcB);
    82                 srcA = 0xFF;
    83             }
    84             if (flags & SDL_COPY_COLORKEY) {
    85                 /* srcpixel isn't set for 24 bpp */
    86                 if (srcbpp == 3) {
    87                     srcpixel = (srcR << src_fmt->Rshift) |
    88                         (srcG << src_fmt->Gshift) | (srcB << src_fmt->Bshift);
    89                 }
    90                 if ((srcpixel & rgbmask) == ckey) {
    91                     posx += incx;
    92                     dst += dstbpp;
    93                     continue;
    94                 }
    95             }
    96             if (dst_fmt->Amask) {
    97                 DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
    98                               dstB, dstA);
    99             } else {
   100                 DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
   101                              dstB);
   102                 dstA = 0xFF;
   103             }
   104 
   105             if (flags & SDL_COPY_MODULATE_COLOR) {
   106                 srcR = (srcR * modulateR) / 255;
   107                 srcG = (srcG * modulateG) / 255;
   108                 srcB = (srcB * modulateB) / 255;
   109             }
   110             if (flags & SDL_COPY_MODULATE_ALPHA) {
   111                 srcA = (srcA * modulateA) / 255;
   112             }
   113             if (flags & (SDL_COPY_BLEND | SDL_COPY_ADD)) {
   114                 /* This goes away if we ever use premultiplied alpha */
   115                 if (srcA < 255) {
   116                     srcR = (srcR * srcA) / 255;
   117                     srcG = (srcG * srcA) / 255;
   118                     srcB = (srcB * srcA) / 255;
   119                 }
   120             }
   121             switch (flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD)) {
   122             case 0:
   123                 dstR = srcR;
   124                 dstG = srcG;
   125                 dstB = srcB;
   126                 dstA = srcA;
   127                 break;
   128             case SDL_COPY_BLEND:
   129                 dstR = srcR + ((255 - srcA) * dstR) / 255;
   130                 dstG = srcG + ((255 - srcA) * dstG) / 255;
   131                 dstB = srcB + ((255 - srcA) * dstB) / 255;
   132                 dstA = srcA + ((255 - srcA) * dstA) / 255;
   133                 break;
   134             case SDL_COPY_ADD:
   135                 dstR = srcR + dstR;
   136                 if (dstR > 255)
   137                     dstR = 255;
   138                 dstG = srcG + dstG;
   139                 if (dstG > 255)
   140                     dstG = 255;
   141                 dstB = srcB + dstB;
   142                 if (dstB > 255)
   143                     dstB = 255;
   144                 break;
   145             case SDL_COPY_MOD:
   146                 dstR = (srcR * dstR) / 255;
   147                 dstG = (srcG * dstG) / 255;
   148                 dstB = (srcB * dstB) / 255;
   149                 break;
   150             }
   151             if (dst_fmt->Amask) {
   152                 ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA);
   153             } else {
   154                 ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
   155             }
   156             posx += incx;
   157             dst += dstbpp;
   158         }
   159         posy += incy;
   160         info->dst += info->dst_pitch;
   161     }
   162 }
   163 
   164 /* vi: set ts=4 sw=4 expandtab: */