linux-kernel-gpufreq-mali_kbase_config_XXXX.c

本文详细介绍了如何配置Mali GPU的性能参数,包括频率、调度时间、软硬停止及重置时间等,以实现最佳性能与安全性平衡。

/*
 *
 * (C) COPYRIGHT ARM Limited. All rights reserved.
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * A copy of the licence is included with the program, and can also be obtained
 * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 *
 */

 

 

#include <linux/ioport.h>
#include <mali_kbase.h>
#include <mali_kbase_defs.h>
#include <mali_kbase_config.h>

#include <linux/opp.h>
#include <linux/pm_runtime.h>
#include <linux/clk.h>
#include <linux/regulator/consumer.h>
#ifdef CONFIG_REPORT_VSYNC
#include <linux/export.h>
#endif
#include <linux/delay.h>

/* Versatile Express (VE) configuration defaults shared between config_attributes[]
 * and config_attributes_hw_issue_8408[]. Settings are not shared for
 * JS_HARD_STOP_TICKS_SS and JS_RESET_TICKS_SS.
 */
#define KBASE_VE_GPU_FREQ_KHZ_MAX               5000
#define KBASE_VE_GPU_FREQ_KHZ_MIN               5000

#define KBASE_VE_JS_SCHEDULING_TICK_NS_DEBUG    15000000u      /* 15ms, an agressive tick for testing purposes. This will reduce performance significantly */
#define KBASE_VE_JS_SOFT_STOP_TICKS_DEBUG       1 /* between 15ms and 30ms before soft-stop a job */
#define KBASE_VE_JS_SOFT_STOP_TICKS_CL_DEBUG    1 /* between 15ms and 30ms before soft-stop a CL job */
#define KBASE_VE_JS_HARD_STOP_TICKS_SS_DEBUG    333 /* 5s before hard-stop */
#define KBASE_VE_JS_HARD_STOP_TICKS_SS_8401_DEBUG 2000 /* 30s before hard-stop, for a certain GLES2 test at 128x128 (bound by combined vertex+tiler job) - for issue 8401 */
#define KBASE_VE_JS_HARD_STOP_TICKS_CL_DEBUG    166 /* 2.5s before hard-stop */
#define KBASE_VE_JS_HARD_STOP_TICKS_NSS_DEBUG   100000 /* 1500s (25mins) before NSS hard-stop */
#define KBASE_VE_JS_RESET_TICKS_SS_DEBUG        500 /* 45s before resetting GPU, for a certain GLES2 test at 128x128 (bound by combined vertex+tiler job) */
#define KBASE_VE_JS_RESET_TICKS_SS_8401_DEBUG   3000 /* 7.5s before resetting GPU - for issue 8401 */
#define KBASE_VE_JS_RESET_TICKS_CL_DEBUG        500 /* 45s before resetting GPU */
#define KBASE_VE_JS_RESET_TICKS_NSS_DEBUG       100166 /* 1502s before resetting GPU */

#define KBASE_VE_JS_SCHEDULING_TICK_NS          1250000000u /* 1.25s */
#define KBASE_VE_JS_SOFT_STOP_TICKS             2 /* 2.5s before soft-stop a job */
#define KBASE_VE_JS_SOFT_STOP_TICKS_CL          1 /* 1.25s before soft-stop a CL job */
#define KBASE_VE_JS_HARD_STOP_TICKS_SS          4 /* 5s before hard-stop */
#define KBASE_VE_JS_HARD_STOP_TICKS_SS_8401     24 /* 30s before hard-stop, for a certain GLES2 test at 128x128 (bound by combined vertex+tiler job) - for issue 8401 */
#define KBASE_VE_JS_HARD_STOP_TICKS_CL          2 /* 2.5s before hard-stop */
#define KBASE_VE_JS_HARD_STOP_TICKS_NSS         1200 /* 1500s before NSS hard-stop */
#define KBASE_VE_JS_RESET_TICKS_SS              6 /* 7.5s before resetting GPU */
#define KBASE_VE_JS_RESET_TICKS_SS_8401         36 /* 45s before resetting GPU, for a certain GLES2 test at 128x128 (bound by combined vertex+tiler job) - for issue 8401 */
#define KBASE_VE_JS_RESET_TICKS_CL              3 /* 7.5s before resetting GPU */
#define KBASE_VE_JS_RESET_TICKS_NSS             1201 /* 1502s before resetting GPU */

#define KBASE_VE_JS_RESET_TIMEOUT_MS            3000 /* 3s before cancelling stuck jobs */
#define KBASE_VE_JS_CTX_TIMESLICE_NS            1000000 /* 1ms - an agressive timeslice for testing purposes (causes lots of scheduling out for >4 ctxs) */
#define KBASE_VE_SECURE_BUT_LOSS_OF_PERFORMANCE ((uintptr_t)MALI_FALSE) /* By default we prefer performance over security on r0p0-15dev0 and KBASE_CONFIG_ATTR_ earlier */
#define KBASE_VE_POWER_MANAGEMENT_CALLBACKS     ((uintptr_t)&pm_callbacks)
#define KBASE_PLATFORM_CALLBACKS                ((uintptr_t)&platform_funcs)

#define HARD_RESET_AT_POWER_OFF 0

#ifndef CONFIG_OF
static kbase_io_resources io_resources = {
 .job_irq_number = 68,
 .mmu_irq_number = 69,
 .gpu_irq_number = 70,
 .io_memory_region = {
        .start = 0xFC010000,
        .end = 0xFC010000 + (4096 * 4) - 1}
};
#endif

#define KBASE_XXXX_PLATFORM_GPU_REGULATOR_NAME      "g3d"
#define RUNTIME_PM_DELAY_TIME 100
#define DEFAULT_POLLING_MS 20
#define STOP_POLLING  0

#ifdef CONFIG_REPORT_VSYNC
static kbase_device *kbase_dev;
#endif

static inline void kbase_platform_on(struct kbase_device *kbdev)
{
 if (kbdev->regulator) {
  if (unlikely(regulator_enable(kbdev->regulator)))
   printk("MALI-MIDGARD:  Failed to enable regulator\n");
 }
}

static inline void kbase_platform_off(struct kbase_device *kbdev)
{
 if (kbdev->regulator)
  regulator_disable(kbdev->regulator);

}

#ifdef CONFIG_PM_DEVFREQ
static int mali_kbase_devfreq_target(struct device *dev, unsigned long *_freq,
         u32 flags)
{
 struct kbase_device *kbdev = (struct kbase_device *)dev->platform_data;
 unsigned long old_freq = kbdev->devfreq->previous_freq;
 struct opp *opp = NULL;
 unsigned long freq;

 rcu_read_lock();
 opp = devfreq_recommended_opp(dev, _freq, flags);
 if (IS_ERR(opp)) {
  printk("[mali-midgard]  Failed to get Operating Performance Point\n");
  rcu_read_unlock();
  return PTR_ERR(opp);
 }
 freq = opp_get_freq(opp);
 rcu_read_unlock();

 if (old_freq == freq)
  return 0;

 if (clk_set_rate((kbdev->clk), freq)) {
  printk("[mali-midgard]  Failed to set gpu freqency, [%lu->%lu]\n", old_freq, freq);
  return -ENODEV;
 }


 return 0;
}

static int mali_kbase_get_dev_status(struct device *dev,
          struct devfreq_dev_status *stat)
{
 struct kbase_device *kbdev = (struct kbase_device *)dev->platform_data;

 (void)kbase_pm_get_dvfs_action(kbdev);
 stat->busy_time = kbdev->pm.metrics.utilisation;
 stat->total_time = 100;
 stat->private_data = (void *)kbdev->pm.metrics.vsync_hit;
 stat->current_frequency = kbdev->devfreq->previous_freq;

 return 0;
}

static struct devfreq_dev_profile mali_kbase_devfreq_profile = {
 /* it would be abnormal to enable devfreq monitor during initialization. */
 .polling_ms = STOP_POLLING,
 .target  = mali_kbase_devfreq_target,
 .get_dev_status = mali_kbase_get_dev_status,
};
#endif

#ifdef CONFIG_REPORT_VSYNC
void mali_kbase_pm_report_vsync(int buffer_updated)
{
 if (kbase_dev)
  kbase_pm_report_vsync(kbase_dev, buffer_updated);
}
EXPORT_SYMBOL(mali_kbase_pm_report_vsync);
#endif

#ifdef CONFIG_MALI_MIDGARD_DVFS
int kbase_platform_dvfs_event(struct kbase_device *kbdev, u32 utilisation)
{
 return 1;
}

int kbase_platform_dvfs_enable(kbase_device *kbdev, bool enable, int freq)
{
 unsigned long flags;

 KBASE_DEBUG_ASSERT(kbdev != NULL);

 if (enable != kbdev->pm.metrics.timer_active) {
  if (enable) {
   spin_lock_irqsave(&kbdev->pm.metrics.lock, flags);
   kbdev->pm.metrics.timer_active = MALI_TRUE;
   spin_unlock_irqrestore(&kbdev->pm.metrics.lock, flags);
   hrtimer_start(&kbdev->pm.metrics.timer,
     HR_TIMER_DELAY_MSEC(kbdev->pm.platform_dvfs_frequency),
     HRTIMER_MODE_REL);
  } else {
   spin_lock_irqsave(&kbdev->pm.metrics.lock, flags);
   kbdev->pm.metrics.timer_active = MALI_FALSE;
   spin_unlock_irqrestore(&kbdev->pm.metrics.lock, flags);
   hrtimer_cancel(&kbdev->pm.metrics.timer);
  }
 }

 return 1;
}
#endif

static mali_bool kbase_platform_init(struct kbase_device *kbdev)
{
 struct device *dev = kbdev->dev;
 dev->platform_data = kbdev;

#ifdef CONFIG_REPORT_VSYNC
 kbase_dev = kbdev;
#endif

 kbdev->clk = devm_clk_get(dev, NULL);
 if (IS_ERR(kbdev->clk)) {
  printk("[mali-midgard]  Failed to get clk\n");
  return MALI_FALSE;
 }

 kbdev->regulator = devm_regulator_get(dev, KBASE_XXXX_PLATFORM_GPU_REGULATOR_NAME);
 if (IS_ERR(kbdev->regulator)) {
  printk("[mali-midgard]  Failed to get regulator\n");
  return MALI_FALSE;
 }

#ifdef CONFIG_PM_DEVFREQ
 if (of_init_opp_table(dev) ||
  opp_init_devfreq_table(dev,
   &mali_kbase_devfreq_profile.freq_table)) {
  printk("[mali-midgard]  Failed to init devfreq_table\n");
  kbdev->devfreq = NULL;
 } else {
  mali_kbase_devfreq_profile.initial_freq = clk_get_rate(kbdev->clk);
  rcu_read_lock();
  mali_kbase_devfreq_profile.max_state = opp_get_opp_count(dev);
  rcu_read_unlock();
  kbdev->devfreq = devfreq_add_device(dev,
      &mali_kbase_devfreq_profile,
      "mali_ondemand",
      NULL);
 }

 if (IS_ERR(kbdev->devfreq)) {
  printk("[mali-midgard]  NULL pointer [kbdev->devFreq]\n");
  return MALI_FALSE;
 }

 /* make devfreq function */
 mali_kbase_devfreq_profile.polling_ms = DEFAULT_POLLING_MS;
#endif
 return MALI_TRUE;
}

static void kbase_platform_term(struct kbase_device *kbdev)
{
#ifdef CONFIG_PM_DEVFREQ
 devfreq_remove_device(kbdev->devfreq);
#endif
}

kbase_platform_funcs_conf platform_funcs = {
 .platform_init_func = &kbase_platform_init,
 .platform_term_func = &kbase_platform_term,
};

#ifdef CONFIG_MALI_MIDGARD_RT_PM
static int pm_callback_power_on(kbase_device *kbdev)
{
 int result;
 int ret_val;
 struct device *dev = kbdev->dev;

#if (HARD_RESET_AT_POWER_OFF != 1)
 if (!pm_runtime_status_suspended(dev))
  ret_val = 0;
 else
#endif
  ret_val = 1;

 if (unlikely(dev->power.disable_depth > 0)) {
  kbase_platform_on(kbdev);
 } else {
  result = pm_runtime_resume(dev);
  if (result < 0 && result == -EAGAIN)
   kbase_platform_on(kbdev);
  else if (result < 0)
   printk("[mali-midgard]  pm_runtime_resume failed (%d)\n", result);
 }

 return ret_val;
}

static void pm_callback_power_off(kbase_device *kbdev)
{
 struct device *dev = kbdev->dev;
 int ret = 0, retry = 0;

#if HARD_RESET_AT_POWER_OFF
 /* Cause a GPU hard reset to test whether we have actually idled the GPU
  * and that we properly reconfigure the GPU on power up.
  * Usually this would be dangerous, but if the GPU is working correctly it should
  * be completely safe as the GPU should not be active at this point.
  * However this is disabled normally because it will most likely interfere with
  * bus logging etc.
  */
 KBASE_TRACE_ADD(kbdev, CORE_GPU_HARD_RESET, NULL, NULL, 0u, 0);
 kbase_os_reg_write(kbdev, GPU_CONTROL_REG(GPU_COMMAND), GPU_COMMAND_HARD_RESET);
#endif

 if (unlikely(dev->power.disable_depth > 0)) {
  kbase_platform_off(kbdev);
 } else {
  do {
   ret = pm_schedule_suspend(dev, RUNTIME_PM_DELAY_TIME);
   if (ret != -EAGAIN) {
    if (unlikely(ret < 0)) {
     pr_err("[mali-midgard]  pm_schedule_suspend failed (%d)\n\n", ret);
     WARN_ON(1);
    }

    /* correct status */
    break;
   }

   /* -EAGAIN, repeated attempts for 1s totally */
   msleep(50);
  } while (++retry < 20);
 }
}

static mali_error pm_callback_runtime_init(kbase_device *kbdev)
{
 pm_suspend_ignore_children(kbdev->dev, true);
 pm_runtime_enable(kbdev->dev);
 return MALI_ERROR_NONE;
}

static void pm_callback_runtime_term(kbase_device *kbdev)
{
 pm_runtime_disable(kbdev->dev);
}

static void pm_callback_runtime_off(kbase_device *kbdev)
{
#ifdef CONFIG_PM_DEVFREQ
 devfreq_suspend_device(kbdev->devfreq);
#elif defined(CONFIG_MALI_MIDGARD_DVFS)
 kbase_platform_dvfs_enable(kbdev, false, 0);
#endif

 kbase_platform_off(kbdev);
}

static int pm_callback_runtime_on(kbase_device *kbdev)
{
 kbase_platform_on(kbdev);

#ifdef CONFIG_PM_DEVFREQ
 devfreq_resume_device(kbdev->devfreq);
#elif defined(CONFIG_MALI_MIDGARD_DVFS)
 if (kbase_platform_dvfs_enable(kbdev, true, 0) != MALI_TRUE)
  return -EPERM;
#endif

 return 0;
}

static inline void pm_callback_suspend(struct kbase_device *kbdev)
{
 if (!pm_runtime_status_suspended(kbdev->dev))
  pm_callback_runtime_off(kbdev);
}

static inline void pm_callback_resume(struct kbase_device *kbdev)
{
 if (!pm_runtime_status_suspended(kbdev->dev))
  pm_callback_runtime_on(kbdev);
 else
  pm_callback_power_on(kbdev);
}

static kbase_pm_callback_conf pm_callbacks = {
 .power_on_callback = pm_callback_power_on,
 .power_off_callback = pm_callback_power_off,
 .power_suspend_callback = pm_callback_suspend,
 .power_resume_callback = pm_callback_resume,
#ifdef CONFIG_PM_RUNTIME
 .power_runtime_init_callback = pm_callback_runtime_init,
 .power_runtime_term_callback = pm_callback_runtime_term,
 .power_runtime_off_callback = pm_callback_runtime_off,
 .power_runtime_on_callback = pm_callback_runtime_on
#else
 .power_runtime_init_callback = NULL,
 .power_runtime_term_callback = NULL,
 .power_runtime_off_callback = NULL,
 .power_runtime_on_callback = NULL
#endif
};
#endif

/* Please keep table config_attributes in sync with config_attributes_hw_issue_8408 */
static kbase_attribute config_attributes[] = {
 {
  KBASE_CONFIG_ATTR_GPU_FREQ_KHZ_MAX,
  KBASE_VE_GPU_FREQ_KHZ_MAX},

 {
  KBASE_CONFIG_ATTR_GPU_FREQ_KHZ_MIN,
  KBASE_VE_GPU_FREQ_KHZ_MIN},

#ifdef CONFIG_MALI_DEBUG
/* Use more aggressive scheduling timeouts in debug builds for testing purposes */
 {
  KBASE_CONFIG_ATTR_JS_SCHEDULING_TICK_NS,
  KBASE_VE_JS_SCHEDULING_TICK_NS_DEBUG},

 {
  KBASE_CONFIG_ATTR_JS_SOFT_STOP_TICKS,
  KBASE_VE_JS_SOFT_STOP_TICKS_DEBUG},

 {
  KBASE_CONFIG_ATTR_JS_SOFT_STOP_TICKS_CL,
  KBASE_VE_JS_SOFT_STOP_TICKS_CL_DEBUG},

 {
  KBASE_CONFIG_ATTR_JS_HARD_STOP_TICKS_SS,
  KBASE_VE_JS_HARD_STOP_TICKS_SS_DEBUG},

 {
  KBASE_CONFIG_ATTR_JS_HARD_STOP_TICKS_CL,
  KBASE_VE_JS_HARD_STOP_TICKS_CL_DEBUG},

 {
  KBASE_CONFIG_ATTR_JS_HARD_STOP_TICKS_NSS,
  KBASE_VE_JS_HARD_STOP_TICKS_NSS_DEBUG},

 {
  KBASE_CONFIG_ATTR_JS_RESET_TICKS_SS,
  KBASE_VE_JS_RESET_TICKS_SS_DEBUG},

 {
  KBASE_CONFIG_ATTR_JS_RESET_TICKS_CL,
  KBASE_VE_JS_RESET_TICKS_CL_DEBUG},

 {
  KBASE_CONFIG_ATTR_JS_RESET_TICKS_NSS,
  KBASE_VE_JS_RESET_TICKS_NSS_DEBUG},
#else    /* CONFIG_MALI_DEBUG */
/* In release builds same as the defaults but scaled for 5MHz FPGA */
 {
  KBASE_CONFIG_ATTR_JS_SCHEDULING_TICK_NS,
  KBASE_VE_JS_SCHEDULING_TICK_NS},

 {
  KBASE_CONFIG_ATTR_JS_SOFT_STOP_TICKS,
  KBASE_VE_JS_SOFT_STOP_TICKS},

 {
  KBASE_CONFIG_ATTR_JS_SOFT_STOP_TICKS_CL,
  KBASE_VE_JS_SOFT_STOP_TICKS_CL},

 {
  KBASE_CONFIG_ATTR_JS_HARD_STOP_TICKS_SS,
  KBASE_VE_JS_HARD_STOP_TICKS_SS},

 {
  KBASE_CONFIG_ATTR_JS_HARD_STOP_TICKS_CL,
  KBASE_VE_JS_HARD_STOP_TICKS_CL},

 {
  KBASE_CONFIG_ATTR_JS_HARD_STOP_TICKS_NSS,
  KBASE_VE_JS_HARD_STOP_TICKS_NSS},

 {
  KBASE_CONFIG_ATTR_JS_RESET_TICKS_SS,
  KBASE_VE_JS_RESET_TICKS_SS},

 {
  KBASE_CONFIG_ATTR_JS_RESET_TICKS_CL,
  KBASE_VE_JS_RESET_TICKS_CL},

 {
  KBASE_CONFIG_ATTR_JS_RESET_TICKS_NSS,
  KBASE_VE_JS_RESET_TICKS_NSS},
#endif    /* CONFIG_MALI_DEBUG */
 {
  KBASE_CONFIG_ATTR_JS_RESET_TIMEOUT_MS,
  KBASE_VE_JS_RESET_TIMEOUT_MS},

 {
  KBASE_CONFIG_ATTR_JS_CTX_TIMESLICE_NS,
  KBASE_VE_JS_CTX_TIMESLICE_NS},
#ifdef CONFIG_MALI_MIDGARD_RT_PM
 {
  KBASE_CONFIG_ATTR_POWER_MANAGEMENT_CALLBACKS,
  KBASE_VE_POWER_MANAGEMENT_CALLBACKS},
#endif
 {
  KBASE_CONFIG_ATTR_PLATFORM_FUNCS,
  KBASE_PLATFORM_CALLBACKS},

 {
  KBASE_CONFIG_ATTR_SECURE_BUT_LOSS_OF_PERFORMANCE,
  KBASE_VE_SECURE_BUT_LOSS_OF_PERFORMANCE},

 {
  KBASE_CONFIG_ATTR_GPU_IRQ_THROTTLE_TIME_US,
  20},

 {
  KBASE_CONFIG_ATTR_END,
  0}
};

static kbase_platform_config XXXX_platform_config = {
 .attributes = config_attributes,
#ifndef CONFIG_OF
 .io_resources = &io_resources
#endif
};

kbase_platform_config *kbase_get_platform_config(void)
{
 return &XXXX_platform_config;
}

int kbase_platform_early_init(void)
{
 /* Nothing needed at this stage */
 return 0;
}

2025-12-10 20:01:03.720 4246-4246 cr_LibraryLoader com.skycomx.projectframes I Successfully loaded native library 2025-12-10 20:01:03.722 4246-4246 cr_CachingUmaRecorder com.skycomx.projectframes I Flushed 7 samples from 7 histograms, 0 samples were dropped. 2025-12-10 20:01:03.724 4246-4246 cr_VariationsUtils com.skycomx.projectframes I Loaded seed with age 17883s 2025-12-10 20:01:03.756 4246-4246 Compatibil...geReporter com.skycomx.projectframes D Compat change id reported: 183155436; UID 10111; state: ENABLED 2025-12-10 20:01:03.794 4246-4352 chromium com.skycomx.projectframes W [WARNING:dns_config_service_android.cc(115)] Failed to read DnsConfig. 2025-12-10 20:01:04.006 4246-4246 Compatibil...geReporter com.skycomx.projectframes D Compat change id reported: 214741472; UID 10111; state: ENABLED 2025-12-10 20:01:04.081 4246-4246 System.out com.skycomx.projectframes I --ppp-----path:/storage/emulated/0/Download/car_manual.pdf 2025-12-10 20:01:04.087 4246-4365 AudioManager com.skycomx.projectframes E enter AudioManager(), allow_adjust_volume=false 2025-12-10 20:01:04.089 4246-4382 libEGL com.skycomx.projectframes D loaded /vendor/lib64/egl/libGLES_mali.so 2025-12-10 20:01:04.096 4246-4365 Compatibil...geReporter com.skycomx.projectframes D Compat change id reported: 263076149; UID 10111; state: ENABLED 2025-12-10 20:01:04.099 4246-4246 System.out com.skycomx.projectframes I --ppp-----path:/storage/emulated/0/Download/car_manual.pdf 2025-12-10 20:01:04.156 4246-4382 mali_so com.skycomx.projectframes I [File] : hardware/arm/mali_so/driver/product/base/src/mali_base_kbase.c; [Line] : 1403; [Func] : base_context_deal_with_version_affairs_rk_ext; arm_release_ver of this mali_so is 'g15p0-01eac0', rk_so_ver is '4'. 2025-12-10 20:01:04.156 4246-4382 mali_so com.skycomx.projectframes I [File] : hardware/arm/mali_so/driver/product/base/src/mali_base_kbase.c; [Line] : 1419; [Func] : base_context_deal_with_version_affairs_rk_ext; arm_release_vers are match. to set the full mali_ver 'g15p0-01eac0-x-4' as value of 'sys.gmali.version'. 2025-12-10 20:01:04.162 4246-4382 libEGL com.skycomx.projectframes E eglCreateContextImpl:931 error 3004 (EGL_BAD_ATTRIBUTE) 2025-12-10 20:01:04.165 4246-4246 Compatibil...geReporter com.skycomx.projectframes D Compat change id reported: 237531167; UID 10111; state: DISABLED 2025-12-10 20:01:04.168 4246-4246 OpenGLRenderer com.skycomx.projectframes W Unknown dataspace 0 2025-12-10 20:01:04.197 4246-4382 mali_so com.skycomx.projectframes I [File] : hardware/arm/mali_so/driver/product/base/src/mali_base_kbase.c; [Line] : 1403; [Func] : base_context_deal_with_version_affairs_rk_ext; arm_release_ver of this mali_so is 'g15p0-01eac0', rk_so_ver is '4'. 2025-12-10 20:01:04.197 4246-4382 mali_so com.skycomx.projectframes I [File] : hardware/arm/mali_so/driver/product/base/src/mali_base_kbase.c; [Line] : 1419; [Func] : base_context_deal_with_version_affairs_rk_ext; arm_release_vers are match. to set the full mali_ver 'g15p0-01eac0-x-4' as value of 'sys.gmali.version'. 2025-12-10 20:01:04.211 4246-4354 Compatibil...geReporter com.skycomx.projectframes D Compat change id reported: 247079863; UID 10111; state: ENABLED 2025-12-10 20:01:04.232 4246-4382 mali_so com.skycomx.projectframes I [File] : hardware/arm/mali_so/driver/product/base/src/mali_base_kbase.c; [Line] : 1403; [Func] : base_context_deal_with_version_affairs_rk_ext; arm_release_ver of this mali_so is 'g15p0-01eac0', rk_so_ver is '4'. 2025-12-10 20:01:04.233 4246-4382 mali_so com.skycomx.projectframes I [File] : hardware/arm/mali_so/driver/product/base/src/mali_base_kbase.c; [Line] : 1419; [Func] : base_context_deal_with_version_affairs_rk_ext; arm_release_vers are match. to set the full mali_ver 'g15p0-01eac0-x-4' as value of 'sys.gmali.version'. 2025-12-10 20:01:04.238 4246-4382 mali_so com.skycomx.projectframes I [File] : hardware/arm/mali_so/driver/product/base/src/mali_base_kbase.c; [Line] : 1403; [Func] : base_context_deal_with_version_affairs_rk_ext; arm_release_ver of this mali_so is 'g15p0-01eac0', rk_so_ver is '4'. 2025-12-10 20:01:04.238 4246-4382 mali_so com.skycomx.projectframes I [File] : hardware/arm/mali_so/driver/product/base/src/mali_base_kbase.c; [Line] : 1419; [Func] : base_context_deal_with_version_affairs_rk_ext; arm_release_vers are match. to set the full mali_ver 'g15p0-01eac0-x-4' as value of 'sys.gmali.version'. 2025-12-10 20:01:04.240 4246-4246 Compatibil...geReporter com.skycomx.projectframes D Compat change id reported: 193247900; UID 10111; state: ENABLED 2025-12-10 20:01:04.341 4246-4246 DecorView com.skycomx.projectframes I splitscreenFocusView windowingMode: 1 hasFoucs: true 2025-12-10 20:01:04.539 4246-4246 chromium com.skycomx.projectframes I [INFO:CONSOLE(1)] "Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')", source: (1) 2025-12-10 20:01:04.770 4246-4279 libEGL com.skycomx.projectframes E eglCreateContextImpl:931 error 3004 (EGL_BAD_ATTRIBUTE) 2025-12-10 20:01:04.802 4246-4279 mali_so com.skycomx.projectframes I [File] : hardware/arm/mali_so/driver/product/base/src/mali_base_kbase.c; [Line] : 1403; [Func] : base_context_deal_with_version_affairs_rk_ext; arm_release_ver of this mali_so is 'g15p0-01eac0', rk_so_ver is '4'. 2025-12-10 20:01:04.803 4246-4279 mali_so com.skycomx.projectframes I [File] : hardware/arm/mali_so/driver/product/base/src/mali_base_kbase.c; [Line] : 1419; [Func] : base_context_deal_with_version_affairs_rk_ext; arm_release_vers are match. to set the full mali_ver 'g15p0-01eac0-x-4' as value of 'sys.gmali.version'. 2025-12-10 20:01:04.813 4246-4380 chromium com.skycomx.projectframes W [WARNING:display_webview.cc(32)] WebView overlays are enabled! 2025-12-10 20:01:04.939 4246-4246 chromium com.skycomx.projectframes I [INFO:CONSOLE(16168)] "Uncaught TypeError: Promise.withResolvers is not a function", source: file:///android_asset/pdf_js/web/viewer.mjs (16168) 2025-12-10 20:01:23.033 4246-4258 x.projectframes com.skycomx.projectframes I Background concurrent mark compact GC freed 113154(6152KB) AllocSpace objects, 6(120KB) LOS objects, 49% free, 3984KB/7968KB, paused 387us,9.232ms total 64.658ms 2025-12-10 20:01:23.040 4246-4261 x.projectframes com.skycomx.projectframes W ApkAssets: Deleting an ApkAssets object '<empty> and /product/app/webview/webview.apk' with 1 weak references
最新发布
12-11
从你提供的 **Logcat 日志**来看,你的 Android 应用(`com.skycomx.projectframes`)正在尝试加载一个 PDF 文件: ``` --ppp-----path:/storage/emulated/0/Download/car_manual.pdf ``` 并且使用了 **PDF.js + WebView** 的方式来渲染 PDF(因为有 `file:///android_asset/pdf_js/web/viewer.mjs` 路径),但最终出现了 JavaScript 错误导致页面无法正常显示。 --- ## 🔍 问题分析 ### ❌ 关键错误信息 ```log 2025-12-10 20:01:04.539 4246-4246 chromium com.skycomx.projectframes I [INFO:CONSOLE(1)] "Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')", source: (1) ``` > 意思是:尝试对 `null` 对象调用 `.addEventListener` —— 说明某个 DOM 元素没找到。 --- ```log 2025-12-10 20:01:04.939 4246-4246 chromium com.skycomx.projectframes I [INFO:CONSOLE(16168)] "Uncaught TypeError: Promise.withResolvers is not a function", source: file:///android_asset/pdf_js/web/viewer.mjs (16168) ``` > ⚠️ 这是最关键的错误! ### 📌 `Promise.withResolvers is not a function` 这是 **现代 JavaScript 新增 API**(ES2024),但在很多 Android 系统 WebView 中不支持! - `Promise.withResolvers()` 是 Chrome 121+ 才支持的新语法。 - 大多数 Android 设备上的系统 WebView 版本较旧(尤其是低端机或未更新系统者),**不支持该语法** → 导致 JS 崩溃 → PDF 页面白屏或卡住。 --- ## ✅ 解决方案:降级 PDF.js 或兼容处理 你目前使用的 `pdf.js` 版本太新,依赖了 **新版 V8 引擎特性**,而 Android WebView 不支持。 --- ## ✅ 方案一:【推荐】使用兼容性更好的 PDF.js 版本(v3.x) ### 步骤 1:下载稳定兼容版 PDF.js 前往 GitHub Release 页面: 👉 https://github.com/mozilla/pdf.js/releases 选择一个 **兼容 Android 低版本 WebView** 的版本,例如: - ✅ 推荐使用:**[pdf.js v3.11.174](https://github.com/mozilla/pdf.js/releases/tag/v3.11.174)** (发布于 2023 年底,无 ES2024 依赖) 点击: ``` Source code (zip) ``` 解压后进入 `/web/` 目录,将整个 `viewer.html` 和 `viewer.js`、`pdf.js` 放入项目 assets: ``` app/src/main/assets/pdf_js/ ├── viewer.html ├── viewer.js └── pdf.js ``` ### 步骤 2:修改 HTML 加载逻辑(可选) 确保 `viewer.html` 中没有引用外部资源(如 CDN),全部本地化。 --- ### 步骤 3:在 Activity 中通过 WebView 加载 ```java WebView webView = findViewById(R.id.webview); WebSettings settings = webView.getSettings(); // 启用 JavaScript(必须) settings.setJavaScriptEnabled(true); // 设置文件访问 settings.setAllowFileAccess(true); settings.setAllowContentAccess(true); settings.setDomStorageEnabled(true); // 非常重要:启用 DOM Storage // 加载本地 PDF.js 查看器,并传入 PDF 路径 String pdfUrl = "file:///storage/emulated/0/Download/car_manual.pdf"; String htmlPath = "file:///android_asset/pdf_js/viewer.html?file=" + Uri.encode(pdfUrl); webView.loadUrl(htmlPath); ``` --- ## ✅ 方案二:【备用】手动 polyfill `Promise.withResolvers` 如果你坚持要用新版 PDF.js(比如需要 WebAssembly 渲染加速等),可以注入一段 JS 来模拟这个函数。 ### 在加载前注入 Polyfill: ```java webView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { if (url.contains("viewer.html")) { String js = "(function() {" + " if (!Promise.withResolvers) {" + " Promise.withResolvers = function() {" + " let resolve, reject;" + " const promise = new Promise((res, rej) => {" + " resolve = res;" + " reject = rej;" + " });" + " return { promise, resolve, reject };" + " };" + " }" + "})();"; view.evaluateJavascript(js, null); } } }); ``` > ⚠️ 注意:有些设备仍可能因其他语法问题崩溃(如 `const {} = await import()`),所以不如直接降级更稳妥。 --- ## ✅ 方案三:改用原生库(避免 WebView 兼容问题) 如果 WebView 方案总是遇到兼容性问题,建议切换到 **原生 PDF 渲染方案**,例如: ### 使用 `AndroidPdfViewer`(基于 Pdfium) #### 添加依赖: ```gradle implementation 'com.github.TalbotGooday:AndroidPdfViewer:3.2.0-beta.2' ``` #### XML 布局: ```xml <com.github.barteksc.pdfviewer.PDFView android:id="@+id/pdfView" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` #### Java 加载文件: ```java PDFView pdfView = findViewById(R.id.pdfView); String path = "/storage/emulated/0/Download/car_manual.pdf"; if (new File(path).exists()) { pdfView.fromFile(new File(path)) .enableSwipe(true) .swipeHorizontal(false) .enableDoubletap(true) .defaultPage(0) .enableAnnotationRendering(false) .password(null) .scrollHandle(new DefaultScrollHandle(this)) .load(); } else { Toast.makeText(this, "文件不存在", Toast.LENGTH_SHORT).show(); } ``` ✅ 优点: - 不依赖 WebView - 支持缩放、滑动、双击放大 - 渲染清晰、性能好 - 完全离线可用 --- ## 🧰 总结对比 | 方案 | 是否推荐 | 说明 | |------|---------|------| | ✅ 使用 PDF.js v3.x | 推荐 | 兼容性强,跨平台,适合已有 Web 架构 | | ⚠️ 使用最新 PDF.js + Polyfill | 一般 | 可能还有其他语法不兼容 | | 💡 改用 `AndroidPdfViewer` | 强烈推荐 | 原生高效,专为 Android 设计,无 JS 风险 | | ❌ 使用新版 PDF.js 直接运行 | 不推荐 | `Promise.withResolvers` 导致崩溃 | --- ## ✅ 如何验证? 你可以先用以下方法快速测试: 1. 把 `car_manual.pdf` 拖进电脑浏览器打开 [https://mozilla.github.io/pdf.js/web/viewer.html](https://mozilla.github.io/pdf.js/web/viewer.html) - 如果能打开 → 说明 PDF 没问题 2. 再在手机上用 WPS 或 Adobe Acrobat 打开此文件 - 如果也能打开 → 说明路径和权限没问题 3. 最后决定是否换引擎 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值