Understanding poor blending performance

Hi, we had a performance issue with our new game on certain devices.
I've posted about it here:
http://developer.anscamobile.com/forum/2012/01/23/slow-performance-android-30

But as our own investigation progressed we actually found the root cause but we're not sure how to solve it.

The problem is with the number of transparent overlapping images in our game which probably loads the GPU on the device (btw, our texture memory consumption is quite low, less than 10mb)

I've isolated out of our code a small sample that exhibits this issue. Basically this is the theme of our main menu on which you have the play button and also some other buttons that bring up verious popups (options, settings, highscores, etc).

These popups have a semi transparent black background so you can still see the main menu theme through them.

The then is just 50 flakes that are dropping and are moved by an enterFrame event.

Here is the same code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
display.setStatusBar( display.HiddenStatusBar )
 
real_world_width = display.contentWidth - 2*display.screenOriginX
real_world_height = display.contentHeight - 2*display.screenOriginY
local centerX, centerY = display.contentWidth * 0.5, display.contentHeight * 0.5
 
local flakes = {} --array for all the flakes
 
local back = display.newImage("small_back.jpg")
back.x, back.y = centerX, centerY
back.xScale, back.yScale = 2 * real_world_width / display.contentWidth, 2 * real_world_height / display.contentHeight
 
 
--FPS bar stuff
local prevTime = 0
local curTime = 0
local dt = 0       
local fps = 50
local mem = 0
 
local underlay = display.newRoundedRect(0, 0, 300, 20, 12)   
underlay.x = 240
underlay.y = 11
underlay:setFillColor(0, 0, 0, 128)             
local displayInfo = display.newText("FPS: " .. fps .. " - Memory: ".. mem .. "mb", 120, 2, native.systemFontBold, 16)
        
local function updateText()
        curTime = system.getTimer()
        dt = curTime - prevTime
        prevTime = curTime
        fps = math.floor(1000 / dt)
        mem = system.getInfo("textureMemoryUsed") / 1000000
        
        --Limit fps range to avoid the "fake" reports
        if fps > 60 then
                fps = 60
        end
        
        displayInfo.text = "FPS: " .. fps .. " - Memory: ".. string.sub(mem, 1, string.len(mem) - 4) .. "mb"
        underlay:toFront()
        displayInfo:toFront()
end
 
 
--generate one flake.
local function generateFlake()
        local f = display.newGroup()
 
        local randX = math.random(0,display.contentWidth - 40) + display.screenOriginX
        local dist = math.abs(randX - centerX)
        local size = 15 + (dist/160) * 25
        f.stepSize = size * 0.05
 
        local flakeWhite = display.newImageRect("shiny_white.png", size, size)
        flakeWhite.alpha = 0.5
        f:insert( flakeWhite )
 
        local flakeLightGreen = display.newImageRect("shiny_green_soft.png", size, size)
        flakeLightGreen.isVisible = false
        flakeLightGreen.alpha = 0.6
        f:insert( flakeLightGreen )
 
        local flakeHardGreen = display.newImageRect("shiny_green_hard.png", size, size)
        flakeHardGreen.isVisible = false
        flakeHardGreen.alpha = 0.75
        f:insert( flakeHardGreen )
 
        local flakeShinyWhiteOut = display.newImageRect("shiny_white_out.png", size, size)
        flakeShinyWhiteOut.isVisible = false
        flakeShinyWhiteOut.alpha = 1
 
        f:insert( flakeShinyWhiteOut )
 
 
        f.stages = {}
        f.stages[1]= flakeWhite
        f.stages[2] = flakeLightGreen
        f.stages[3] = flakeHardGreen
        f.stages[4] = flakeShinyWhiteOut
 
        f.currStage = 1
 
        f:setReferencePoint( display.TopLeftReferencePoint )
        f.x, f.y = randX, 10
 
 
 
        function f:toggleStage(idx)
                for i=1, #f.stages do
                        if i == idx then
                                f.stages[i].isVisible = true
                        else
                                f.stages[i].isVisible = false
                        end
                end
        end
 
        flakes[#flakes + 1] = f
end
 
 
local function enterFrame( event )
        for i=1, #flakes do
                local f = flakes[i]
                f.y = f.y + f.stepSize
 
                if f.y < 40 then
                        f:toggleStage(1)
                elseif f.y < 80 then
                        f:toggleStage(2)
                elseif f.y < 250 then
                        f:toggleStage(3)
                elseif f.y > 340 then
                        f:toggleStage(4)
                end
 
                if f.y > display.contentHeight then
                        f.y = 10
                end
        end
        
        updateText()
end
 
--generate the flakes
local function startTheme()
 
        for x=1, 50 do
                local dly = math.random(1500, 1600) + 350*x
        timer.performWithDelay(dly, generateFlake)
        end
 
        Runtime:addEventListener("enterFrame", enterFrame)
end
startTheme()
 
--generate a new semi transparent rect every 10 seconds
local iteration = 1
local function addRect()
        local rect = display.newRect( 0, 0, real_world_width, real_world_height )
        rect:setFillColor( 0, 0, 0, 127 )
        rect:setReferencePoint( display.CenterReferencePoint )
        rect.x, rect.y = centerX, centerY
        if iteration <= 10 then
                timer.performWithDelay( 10000, addRect )
        end
        iteration = iteration + 1
end
timer.performWithDelay( 10000, addRect )

I'm having exactly the same problem. My game works using Galaxy S2 and Xperia Ray, but it doesn't on Galaxy Tab 10.1.

Did you try it with the build 635? Maybe it's something related with that topic:

developer.anscamobile.com/forum/2011/12/12/performance-degradation-new-public-release

I'm using build 730. giving the older version a try now.

Tried 635 might be a little faster nothing meaningful.. this problem persists in 16bit so its a different thing

views:1873 update:2012/2/7 8:40:54
corona forums © 2003-2011