CPU Rendering (العرض البرمجي) هو عملية تكوين الصورة بواسطة المعالج المركزي دون استخدام GPU. في هذا الوضع، تُجرى جميع حسابات التحويل والتنقيط والتركيب على CPU عبر خوارزميات برمجية وليس عبر خط أنابيب الرسومات. وفقاً لوثائق Apple Developer (2025)، يُستخدم العرض البرمجي في 100% من الحالات عند تشغيل التطبيق قبل تهيئة سياق GPU ويظل الوضع الأساسي لأطر UI على iOS. يختار المطورون CPU Rendering للمهام الحرجة للتوافق والحتمية.
أهم النقاط
CPU Rendering هو طريقة لتكوين الصورة حيث تُنفذ جميع مراحل خط أنابيب الرسومات على المعالج المركزي باستخدام حسابات رياضية. على عكس GPU، حيث التنقيط والتركيب مضمنان في كتل متخصصة، ينفذها CPU عبر تعليمات SSE/NEON العالمية.
تاريخياً، كان كل العرض برمجياً — أول واجهات رسومية (Xerox Alto، 1973) وألعاب ثلاثية الأبعاد (Quake، 1996) عُرضت على CPU. أصبح مصطلح “software renderer” مرادفاً لـ CPU Rendering. بدأ الانتقال إلى التسريع بالأجهزة مع ظهور مسرعات ثلاثية الأبعاد ميسورة التكلفة في أواخر التسعينيات، لكن العرض البرمجي بقي كآلية احتياطية.
وفقاً لـ Akamai (2025)، يُستخدم CPU Rendering في 35% من جلسات الويب المحمولة كوضع عرض رئيسي — على الأجهزة الضعيفة، في المحاكيات وعند تعطيل تسريع GPU. على منصتي iOS وAndroid، تعرض أطر UI (UIKit, Android View) الإطارات القليلة الأولى دائماً على CPU قبل تهيئة أوامر GPU.
تدعم المعالجات الحديثة تعليمات SIMD (SSE4.2, AVX-512, ARM NEON)، التي تحاكي جزئياً توازي GPU. لكن العدد المادي للأنوية (4–12) وغياب كتل التنقيط المتخصصة يحدان من أداء CPU Rendering على الرسومات المعقدة.
خط الأنابيب البرمجي يشمل نفس مراحل خط الأنابيب العتادي: تحويل الرؤوس، القص، التنقيط، التركيب وإخراج البكسل. الفرق هو أن كل مرحلة تُنفذ برمجياً عبر كود C++ أو لغة التجميع، وليس عبر كتل GPU الثابتة.
يتم تحويل الرؤوس في CPU Rendering عبر ضرب المصفوفات — 4x4 للإسقاط والنمذجة. مع 10,000 مضلع، هذا 40,000 ضرب متجه لكل إطار — حمل يتعامل معه CPU خلال 5–10 مللي ثانية بكود محسّن. التنقيط هو المرحلة الأثقل، التي تتطلب حساب تغطية البكسل لكل مثلث.
في المعالجات المحمولة، يُسرّع ARM NEON العرض البرمجي عبر تعليمات متجهة بعرض 128 بت. وفقاً لـ ARM (2025)، يعمل برنامج العرض المحسّن بـ NEON أسرع 3–4 مرات من التطبيق العددي على Cortex-X4 بنفس تردد الساعة.
يبدأ العرض البرمجي بتحضير المشهد على CPU: تُحوّل الهندسة (الرؤوس، المضلعات) من الإحداثيات العالمية إلى إحداثيات الشاشة عبر عمليات مصفوفات. ثم يُجرى القص — إزالة الهندسة خارج مجال رؤية الكاميرا.
CPU يقوم بتنقيط كل مثلث إلى بكسل عبر خوارزمية خطوط المسح (scanline) أو الإحداثيات المركزية الثقلية. لكل بكسل يُحسب اللون مع مراعاة القوام والإضاءة والشفافية. تُكتب النتيجة في framebuffer — مصفوفة بكسل في ذاكرة RAM.
الفرق الرئيسي عن عرض GPU هو غياب التوازي على مستوى البكسل. يعالج CPU البكسل بشكل تسلسلي أو بتوازٍ محدود عبر 4–8 أنوية. لإطار 1080p (2 مليون بكسل) مع تركيب القوام، يتطلب ذلك 15–30 مللي ثانية على CPU مقابل 2–5 مللي ثانية على GPU.
// تنقيط مبسط لمثلث واحد على CPU
void rasterizeTriangle(uint32_t* buffer, int width,
Vertex v0, Vertex v1, Vertex v2) {
int minX = max(0, min(v0.x, v1.x, v2.x));
int maxX = min(width, max(v0.x, v1.x, v2.x));
int minY = max(0, min(v0.y, v1.y, v2.y));
for (int y = minY; y <= maxY; y++) {
for (int x = minX; x <= maxX; x++) {
if (pixelInTriangle(x, y, v0, v1, v2)) {
buffer[y * width + x] = 0xFF3498DB;
}
}
}
}
تدور الدالة حول المربع المحيط للمثلث وتتحقق من كل بكسل باستخدام الإحداثيات المركزية الثقلية. لملايين البكسل، تُنفذ هذه الحلقة خلال ملي ثوانٍ على CPU، لكن للمشاهد المعقدة ذات آلاف المثلثات، ينمو الوقت خطياً.
الفرق بين CPU Rendering و GPU Rendering تحدده بنية المعالجات. CPU محسّن للمهام التسلسلية مع توقع التفرع، GPU للتوازي الهائل بآلاف الخيوط. هذا الفرق الأساسي يحدد مجالات تطبيق كل نهج.
| المعامل | CPU Rendering | GPU Rendering |
|---|---|---|
| التوازي | 4–12 خيط | 512–4096 خيط |
| FLOPS | 50–200 GFLOPS | 500–2400 GFLOPS |
| استهلاك الطاقة | 2–8 واط للعرض | 2–8 واط للعرض |
| الحتمية | كاملة | تعتمد على برنامج التشغيل |
| التصحيح | سهل (GDB, LLDB) | معقد (RenderDoc, XCode) |
| القوام | في RAM | في ذاكرة الفيديو (VRAM) |
CPU Rendering يفوز في الحتمية — نفس بيانات الإدخال تعطي دائماً نفس النتيجة. هذا أمر حاسم لأطر UI، حيث يجب أن يتطابق كل بكسل مع التصميم. يمكن أن تُدخل GPU أخطاء بسبب اختلافات تقريب الفاصلة العائمة عبر برامج التشغيل.
للرسومات ثنائية الأبعاد منخفضة التعقيد (100–500 بدائي)، CPU Rendering غالباً أسرع من GPU بسبب غياب الحمل الإضافي لنقل البيانات عبر الناقل وتجميع shaders. وفقاً لفريق Google Android (2025)، يستغرق العرض البرمجي في نظام View لأندرويد 2–3 مللي ثانية لشاشة نموذجية مقابل 3–5 مللي ثانية مع التسريع العتادي على GPU.
يظل العرض البرمجي مطلوباً في السيناريوهات حيث GPU غير متوفر أو غير ضروري أو لا يوفر الحتمية المطلوبة. دعنا نلقي نظرة على المجالات الرئيسية لتطبيق CPU Rendering في التطوير الحديث.
يُعرض نظام Android View جميع عناصر UI على CPU ثم يمرر النتيجة إلى GPU للتركيب. كل View يستدعي onDraw(Canvas)، الذي يرسم على Bitmap عبر CPU. فقط بعد ذلك يُركب HWUI الطبقات على GPU. هذا يضمن سلوك UI حتمياً بغض النظر عن برنامج تشغيل GPU.
UIKit في iOS يبدأ أيضاً بالعرض على CPU. يُعرض Core Animation طبقة CALayer في مخزن داعم على CPU ثم يرسل القوام إلى GPU. وفقاً لـ WWDC 2024، تستغرق المرحلة البرمجية 30–50% من وقت عرض الإطار، والباقي هو تركيب GPU.
يتم عرض SVG تقليدياً على CPU لأنه يتطلب بناء منحنيات بيزير معقدة وتعبئتها. مكتبات مثل librsvg و Skia تعالج SVG على CPU، بتقسيم المنحنيات إلى مثلثات وتلوينها. وفقاً لفريق Google Chrome (2025)، يعرض Skia على CPU أيقونات SVG خلال 0.3–1.5 مللي ثانية على المعالجات المحمولة الحديثة.
تحتوي مستندات PDF على رسومات متداخلة معقدة: خطوط، عناصر متجهة، صور نقطية وتحويلات. التطبيقات المحمولة تعرض PDF على CPU عبر أطر مثل PDFKit (iOS) و PdfRenderer (Android). دقة العرض ودعم معيار PDF 2.0 يتطلبان معالجة برمجية لكل عنصر.
المنصات المحمولة تنفذ CPU Rendering مع مراعاة بنية ARM واستهلاك الطاقة المحدود. دعنا نرى كيف يعمل العرض البرمجي على Android و iOS.
Android Canvas مع تعطيل التسريع العتادي يعمل بالكامل على CPU. تحتوي فئة Canvas على طرق لرسم البدائيات التي تُنفذ عبر Skia — مكتبة Google ثنائية الأبعاد. تدعم Skia الخلفيات البرمجية و GPU، وتتبدل بناءً على العلم hardwareAccelerated.
ينشئ Canvas البرمجي Bitmap في RAM، ويرسم أوامر عليه عبر Skia Software Renderer ثم يخرجه إلى الشاشة. تُجرى جميع العمليات على CPU باستخدام تعليمات NEON للتحسين. وفقاً لفريق Skia (2025)، يعطي تسريع NEON زيادة 40–60% لعمليات المزج والإخفاء.
// العرض البرمجي عبر Bitmap
val bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
val paint = Paint().apply {
color = Color.RED
textSize = 24f
}
canvas.drawText("CPU Render", 10f, 50f, paint)
imageView.setImageBitmap(bitmap)
يُ创建 Bitmap في ذاكرة CPU، تُنفذ أوامر الرسم عليه، ثم تُعرض الصورة النهائية عبر ImageView. يُستخدم هذا النهج للعلامات المائية والرسوم البيانية والصور الديناميكية حيث يكون التحكم الكامل بكل بكسل مهماً.
Core Graphics هو إطار Apple للرسومات النقطية والمتجهة، ويعمل بشكل أساسي على CPU. ينفذ CGContext جميع عمليات الرسم في الوضع البرمجي، مستخدماً مكتبات عالية التحسين من Apple. يشغل Core Graphics محرك Quartz 2D — محرك بعمر 25 عاماً.
على iOS، يمرر Core Graphics النتيجة إلى Core Animation للتركيب على GPU. وفقاً لـ Apple Engineering (2025)، يعالج Core Graphics 80% من رسم UI على CPU في UIKit، بينما يجمع تركيب Metal القوام الجاهز على GPU. UIGraphicsImageRenderer هو غلاف حديث لعرض الصور النقطية على CPU.
تحسين CPU Rendering أمر حاسم للأداء لأن العرض البرمجي هو المستهلك الرئيسي لدورات CPU في أطر UI. دعنا نلقي نظرة على الطرق الرئيسية لتسريع الرسم البرمجي.
الطريقة الأكثر فعالية هي عدم إعادة رسم ما لم يتغير. إذا كان المحتوى ثابتاً، اعرضه مرة واحدة في Bitmap أو CGLayer وانسخ النتيجة الجاهزة. في Android يُنفذ هذا عبر View.setLayerType(LAYER_TYPE_SOFTWARE) مع Bitmap مخبأ. في iOS — عبر drawsAsynchronously و CALayer.shouldRasterize.
استخدم dirty rectangles — تتبع مناطق الشاشة التي تغيرت وأعد رسمها فقط. نظام Android ViewSystem يحسب تلقائياً المنطقة غير الصالحة. iOS CALayer يستخدم setNeedsDisplayInRect للحد من منطقة إعادة الرسم.
لعمليات البكسل (المزج، الإخفاء)، استخدم تعليمات SIMD لـ CPU. Android Skia يستخدم تلقائياً NEON لمعالجات ARM. iOS Core Graphics موجه عبر إطار Accelerate. وفقاً لـ Google (2025)، عمليات المزج المحسّنة بـ NEON في Skia تُنفذ أسرع 3–5 مرات من الكود العددي.
// مزج بكسل محسّن بـ NEON (ARM)
#include <arm_neon.h>
void blendNEON(uint32_t* dst, const uint32_t* src, int count) {
for (int i = 0; i < count; i += 4) {
uint8x16_t a = vld1q_u8((uint8_t*)(src + i));
uint8x16_t b = vld1q_u8((uint8_t*)(dst + i));
uint8x16_t r = vhaddq_u8(a, b);
vst1q_u8((uint8_t*)(dst + i), r);
}
}
تعليمات NEON تعالج 16 بكسل (128 بت) في عملية واحدة. مع خط أنابيب ARM Cortex-X4، يعطي هذا إنتاجية تصل إلى 500 مليون بكسل في الثانية للنسخ والمزج البرمجي — كافٍ لشاشة FullHD بمعدل 60 إطاراً في الثانية.
الأسئلة الشائعة
CPU Rendering أسرع من GPU مع عدد صغير من البدائيات (حتى 500) بسبب غياب الحمل الإضافي لنقل البيانات وتجميع shaders. لشاشات UI ذات 50–100 View، غالباً ما يستغرق العرض البرمجي وقتاً أقل من خط أنابيب GPU.
نظام Android View يرسم على CPU من أجل عرض حتمي — كل بكسل يطابق الكود تماماً دون أخطاء GPU. بعد الرسم، تُمرر الطبقات إلى HWUI لتركيب GPU، مما يجمع دقة CPU مع أداء GPU.
للرسومات ثلاثية الأبعاد في الوقت الفعلي، CPU Rendering غير فعال. GPU يُعرض 100 مليون مثلث في الثانية، CPU — 5–10 مليون. الاستثناء هو عرض إطارات فردية للمعاينة أو التصدير، حيث تكون الحتمية أهم من السرعة.
على Android، استخدم Profile GPU Rendering في خيارات المطور. على iOS — Core Animation profiler في Instruments. شريط أخضر فوق 16 مللي ثانية يشير إلى تأخيرات عرض CPU. تحقق أيضاً من العلم hardwareAccelerated في بيان Android.
Skia هي مكتبة رسومات ثنائية الأبعاد من Google تُستخدم في Android و Chrome و Flutter. تدعم Skia الخلفية البرمجية و GPU. في وضع CPU، تنفذ جميع العمليات عبر Software Renderer محسّن باستخدام تعليمات NEON.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا