mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 13:41:07 +00:00
Share the popcount() fallback for MSVC
We use __builtin_popcount() in a couple of places, so it makes sense to have it in one header.
This commit is contained in:
parent
c5dd34344f
commit
b8a651df47
@ -169,6 +169,7 @@ private_headers = [
|
||||
'gtkplacesviewprivate.h',
|
||||
'gtkplacesviewrowprivate.h',
|
||||
'gtkpointerfocusprivate.h',
|
||||
'gtkpopcountprivate.h',
|
||||
'gtkpopoverprivate.h',
|
||||
'gtkprinterprivate.h',
|
||||
'gtkprintoperation-private.h',
|
||||
|
@ -24,9 +24,7 @@
|
||||
#include "gtkstyleproviderprivate.h"
|
||||
#include "gtksettingsprivate.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
#include "gtkpopcountprivate.h"
|
||||
|
||||
/* repeated API */
|
||||
|
||||
@ -1453,39 +1451,6 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_EAST_ASIAN = {
|
||||
gtk_css_font_variant_east_asian_value_print
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* __builtin_popcount is a GCC-only function
|
||||
so we need to define it for ourselves somehow */
|
||||
|
||||
static inline guint
|
||||
__msvc_compat_popcnt (guint32 value)
|
||||
{
|
||||
static gssize popcnt_checked = 0;
|
||||
static gboolean have_popcnt = FALSE;
|
||||
|
||||
# if defined (_M_AMD64) || defined (_M_X64) || (_M_IX86)
|
||||
if (g_once_init_enter (&popcnt_checked))
|
||||
{
|
||||
int cpuinfo[4] = {-1};
|
||||
|
||||
__cpuid (cpuinfo, 1);
|
||||
have_popcnt = (cpuinfo[2] & 0x00800000) != 0;
|
||||
g_once_init_leave (&popcnt_checked, 1);
|
||||
}
|
||||
# endif
|
||||
|
||||
if (have_popcnt)
|
||||
return __popcnt (value);
|
||||
else
|
||||
/* http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel */
|
||||
return (((value & 0xfff) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f) +
|
||||
((((value & 0xfff000) >> 12) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f) +
|
||||
(((value >> 24) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f);
|
||||
}
|
||||
|
||||
# define __builtin_popcount(v) __msvc_compat_popcnt(v)
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
east_asian_value_is_valid (GtkCssFontVariantEastAsian east_asian)
|
||||
{
|
||||
@ -1493,7 +1458,7 @@ east_asian_value_is_valid (GtkCssFontVariantEastAsian east_asian)
|
||||
(east_asian != GTK_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL))
|
||||
return FALSE;
|
||||
|
||||
if (__builtin_popcount (east_asian & (GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS78 |
|
||||
if (gtk_popcount (east_asian & (GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS78 |
|
||||
GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS83 |
|
||||
GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS90 |
|
||||
GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS04 |
|
||||
@ -1501,7 +1466,7 @@ east_asian_value_is_valid (GtkCssFontVariantEastAsian east_asian)
|
||||
GTK_CSS_FONT_VARIANT_EAST_ASIAN_TRADITIONAL)) > 1)
|
||||
return FALSE;
|
||||
|
||||
if (__builtin_popcount (east_asian & (GTK_CSS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH |
|
||||
if (gtk_popcount (east_asian & (GTK_CSS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH |
|
||||
GTK_CSS_FONT_VARIANT_EAST_ASIAN_PROPORTIONAL)) > 1)
|
||||
return FALSE;
|
||||
|
||||
|
@ -132,6 +132,7 @@
|
||||
#include "gtkimmodule.h"
|
||||
#include "gtkroot.h"
|
||||
#include "gtknative.h"
|
||||
#include "gtkpopcountprivate.h"
|
||||
|
||||
#include "inspector/window.h"
|
||||
|
||||
@ -1484,9 +1485,11 @@ handle_pointing_event (GdkEvent *event)
|
||||
modifiers = gdk_event_get_modifier_state (event);
|
||||
|
||||
if (type == GDK_BUTTON_RELEASE &&
|
||||
__builtin_popcount (modifiers &
|
||||
(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK |
|
||||
GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)) == 1)
|
||||
gtk_popcount (modifiers & (GDK_BUTTON1_MASK |
|
||||
GDK_BUTTON2_MASK |
|
||||
GDK_BUTTON3_MASK |
|
||||
GDK_BUTTON4_MASK |
|
||||
GDK_BUTTON5_MASK)) == 1)
|
||||
{
|
||||
GtkWidget *new_target = gtk_widget_pick (native, x, y, GTK_PICK_DEFAULT);
|
||||
|
||||
|
42
gtk/gtkpopcountprivate.h
Normal file
42
gtk/gtkpopcountprivate.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* gtkpopcountprivate.h: Private implementation of popcount
|
||||
*
|
||||
* Copyright 2020 GNOME Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
|
||||
static inline guint
|
||||
gtk_popcount (guint32 value)
|
||||
{
|
||||
return __popcnt (value);
|
||||
}
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
# define gtk_popcount(v) __builtin_popcount(v)
|
||||
#else
|
||||
static inline guint
|
||||
gtk_popcount (guint32 value)
|
||||
{
|
||||
/* http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel */
|
||||
return (((value & 0xfff) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f) +
|
||||
((((value & 0xfff000) >> 12) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f) +
|
||||
(((value >> 24) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f);
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user