نسيج 512 × 512 يسبب ضغطًا كبيرًا على وحدة معالجة الرسومات على iPhone، على الرغم من التبليط

StackOverflow https://stackoverflow.com/questions/872560

سؤال

أقوم باختبار تطبيق OpenGL ES البسيط (لعبة ثنائية الأبعاد) على iPhone و لقد لاحظت استخدامًا عاليًا للعرض أثناء استخدام ملف التعريف.هذه هي الحقائق:

  • أنا أعرض نسيج كبير واحد فقط تم تحميله مسبقًا (512 × 512 بكسل) بمعدل 60 إطارًا في الثانية ويبلغ استخدام العرض حوالي 40%.
  • تم مزج قوامي باستخدام GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, وظيفة GL الوحيدة التي أستخدمها.
  • لقد حاولت أن أجعل الملمس أصغر وتبليط ذلك، الذي لم يحدث فرق.
  • أنا أستخدم أطلس نسيج PNG بحجم 1024 × 1024 بكسل

أجد أنه من الغريب جدا أن هذا يتسبب نسيج واحد في مثل هذا الاستخدام المكثف لوحدة معالجة الرسومات.

هل هذا متوقع؟ ما الخطأ الذي افعله؟

يحرر: رمز بلدي:

// OpenGL setup is identical to OpenGL ES template
// initState is called to setup
// timer is initialized, drawView is called by the timer

- (void) initState
{
    //usual init declarations have been omitted here        
    glEnable(GL_BLEND); 
    glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);     
    glEnableClientState (GL_VERTEX_ARRAY);
    glVertexPointer     (2,GL_FLOAT,sizeof(Vertex),&allVertices[0].x);          
    glEnableClientState (GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer   (2,GL_FLOAT,sizeof(Vertex),&allVertices[0].tx);     
    glEnableClientState (GL_COLOR_ARRAY);
    glColorPointer      (4,GL_UNSIGNED_BYTE,sizeof(Vertex),&allVertices[0].r);    
}    
- (void) drawView
{       
    [EAGLContext setCurrentContext:context];
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity();

    GLfloat width  = backingWidth /2.f; 
    GLfloat height = backingHeight/2.f; 

    glOrthof(-width, width, -height, height, -1.f, 1.f);
    glMatrixMode(GL_MODELVIEW);
    glClearColor(0.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT);       
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);       
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];      
    [self checkGLError];        
}

يحرر: لقد قمت بإجراء بعض التحسينات، لكن لم ينجح أي منها في تقليل استخدام العرض.لقد قمت بتقسيم النسيج إلى أجزاء 32x32، وغيرت نوع الإحداثيات وإحداثيات النسيج من GLfloat إلى GLshort وأضفت رؤوسًا إضافية للمثلثات التنكسية.

التحديثات هي:

الحالة الأولية:(أصبح مؤشر الرأس والملمس الآن GL_SHORT)

glMatrixMode(GL_TEXTURE);
glScalef(1.f / 1024.f, 1.f / 1024.f, 1.f / 1024.f);
glMatrixMode(GL_MODELVIEW);
glScalef(1.f / 16.f, 1.f/ 16.f, 1.f/ 16.f);

رسم العرض:

glDrawArrays(GL_TRIANGLE_STRIP, 0, 1536); //(16*16 parts * 6 vertices)  
هل كانت مفيدة؟

المحلول

قراءة هذا المنصب.

من المحتمل أن يكون 512x512 أكثر تفاؤلاً بقليل بالنسبة لجهاز iPhone للتعامل معه.

يحرر:

أفترض أنك قد قرأت هذا بالفعل، ولكن إذا لم يكن كذلك تحقق من دليل Apple لأداء OpenGl ES الأمثل على iPhone.

نصائح أخرى

أنا أكتب تطبيقًا يعرض خمسة أنسجة مقاس 512 × 512 فوق بعضها البعض في بيئة ثنائية الأبعاد باستخدام GL_SRC_ALPHA، GL_ONE_MINUS_SRC_ALPHA، ويمكنني الحصول على حوالي 14 إطارًا في الثانية.هل تحتاج حقًا إلى 60 إطارًا في الثانية؟بالنسبة للمباراة، أعتقد أن 24-30 سيكون جيدًا.استخدم أيضًا ضغط نسيج PVR إذا كان ذلك ممكنًا.هناك مثال يتم تضمينه في SDK.

  1. أتمنى أنك لم تنسى التعطيل GL_BLEND عندما لا تحتاج إليها بالفعل.
  2. يمكنك محاولة تحسين النطاق الترددي للذاكرة - استخدم تنسيقات 16 bpp أو PVRTC.IMHO مع ذاكرة التخزين المؤقت لحجم النسيج الخاص بك لا يساعد على الإطلاق.
  3. لا تنس أنه يتم استخدام مخزن الإطارات المؤقت الخاص بك كنسيج بواسطة iPhone UI.إذا تم إنشاؤه كـ 32 بت RGBA، فسيتم مزجه ألفا مرة أخرى.للحصول على الأداء الأمثل، تعد المخازن المؤقتة للإطارات 16 بت 565 هي الأفضل (لكن جودة الرسومات تتأثر).

لا أعرف كل التفاصيل، مثل حجم ذاكرة التخزين المؤقت، ولكن أعتقد أن وحدات البكسل الخاصة بالأنسجة يتم تحريكها بالفعل عند تحميلها إلى ذاكرة الفيديو ويتم تقسيم المثلثات بواسطة محرك بلاط PVR.لذلك يبدو أن التقسيم الخاص بك لا لزوم له.

وأخيرا.هذه مجرد وحدة معالجة رسومات متنقلة منخفضة الطاقة، وليست مصممة للشاشات الضخمة ومعدلات التعبئة العالية.يعد مزج ألفا مكلفًا، وربما يكون الفرق 3-4 مرات على شرائح PowerVR.

ما هي المشكلة بالضبط؟
أنت تحصل على 60 إطارًا في الثانية، وهو أمر سلس كالحرير.

من يهتم إذا كان استخدام العرض هو 40٪؟

قد تكون المشكلة بسبب حجم ذاكرة التخزين المؤقت لنسيج iPhone.قد يتعلق الأمر ببساطة بكمية النسيج الموجود على كل مثلث فردي أو رباعي أو ثلاثي، اعتمادًا على كيفية ضبط الحالة.

جرب هذا:قم بتقسيم رباعيتك وكرر اختباراتك.لذا، إذا كنت رباعيًا واحدًا، فاجعله 4.ثم 16.وما إلى ذلك، ومعرفة ما إذا كان ذلك يساعد.المفتاح هو تقليل العدد الفعلي للبكسلات التي تشير إليها كل نقطة بدائية.

عندما يتم تفجير ذاكرة التخزين المؤقت للنسيج، سيقوم الجهاز بإجراء عمليات البحث عن النسيج من الذاكرة الرئيسية إلى أي vram يتم تخصيصه للمخزن المؤقت للنسيج من أجل كل بكسل.هذا يمكن أن يقتل الأداء بسرعة كبيرة.

أو - أنا مخطئ تمامًا لأنني لا أعرف حقًا أجهزة iPhone، وأعلم أيضًا أن شريحة PVR هي وحش غريب مقارنة بما اعتدت عليه (PS2، PSP).لا يزال هذا اختبارًا سهلاً للمحاولة وأنا أشعر بالفضول إذا كان مفيدًا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top