비트맵 캐싱

적절한 경우 복잡한 벡터 내용에 대해 비트맵 캐싱 기능을 사용합니다.

비트맵 캐싱 기능을 사용해야 최적화 작업을 효과적으로 수행할 수 있습니다. 이 기능은 벡터 객체를 캐시하고 내부적으로 비트맵으로 렌더링하며 이 비트맵을 렌더링에 사용합니다. 그 결과 렌더링 성능이 크게 향상될 수 있지만 상당한 양의 메모리가 필요할 수 있습니다. 복잡한 그래디언트 또는 텍스트와 같은 복잡한 벡터 내용에 비트맵 캐싱 기능을 사용합니다.

복잡한 벡터 그래픽(예: 텍스트 또는 그래디언트)이 포함된, 애니메이션이 적용된 객체에 대해 비트맵 캐싱을 설정하면 성능이 향상됩니다. 그러나 자체 타임라인 재생이 포함된 동영상 클립과 같은 표시 객체에 비트맵 캐싱이 활성화되어 있는 경우 반대의 결과가 나타납니다. 런타임이 각 프레임에서 캐시된 비트맵을 업데이트한 다음 화면에 다시 그려야 하는데, 이 작업에는 CPU 주기가 많이 필요합니다. 비트맵 캐싱 기능은 캐시된 비트맵을 한 번 생성한 다음 업데이트할 필요 없이 사용할 수 있는 경우에만 도움이 됩니다.

Sprite 객체에 대해 비트맵 캐싱을 설정하는 경우 런타임에서 캐시된 비트맵을 다시 생성하지 않고도 객체를 이동할 수 있습니다. 객체의 x y 속성을 변경해도 다시 생성되지 않습니다. 그러나 객체를 회전하거나, 객체 크기를 조절하거나, 객체의 알파 값을 변경하면 런타임에서 캐시된 비트맵을 다시 생성하므로 성능이 저하됩니다.

참고: AIR 및 Packager for iPhone에 사용 가능한 DisplayObject.cacheAsBitmapMatrix 속성에는 이러한 제한이 없습니다. cacheAsBitmapMatrix 속성을 사용하면 비트맵을 다시 생성하지 않고도 표시 객체의 알파 값을 회전하고 크기 조절하고 기울이고 변경할 수 있습니다.

캐시된 비트맵은 일반 동영상 클립 인스턴스보다 더 많은 메모리를 소비할 수도 있습니다. 예를 들어 스테이지의 동영상 클립이 250 x 250 픽셀인 경우 캐시하지 않으면 1KB를 사용하지만 캐시하면 약 250KB를 사용합니다.

다음 예제에는 사과 이미지를 포함하는 Sprite 객체가 관련됩니다. 다음 클래스는 사과 기호에 연결됩니다.

package org.bytearray.bitmap 
{     
    import flash.display.Sprite; 
    import flash.events.Event; 
     
    public class Apple extends Sprite 
    { 
        private var destinationX:Number; 
        private var destinationY:Number; 
         
        public function Apple () 
        { 
            addEventListener(Event.ADDED_TO_STAGE,activation); 
            addEventListener(Event.REMOVED_FROM_STAGE,deactivation);     
        } 
         
        private function activation(e:Event):void  
        { 
            initPos();     
            addEventListener (Event.ENTER_FRAME,handleMovement);     
        } 
         
        private function deactivation(e:Event):void  
        { 
            removeEventListener(Event.ENTER_FRAME,handleMovement);     
        } 
         
        private function initPos():void 
        { 
            destinationX = Math.random()*(stage.stageWidth - (width>>1)); 
            destinationY = Math.random()*(stage.stageHeight - (height>>1)); 
        } 
         
        private function handleMovement(e:Event):void  
        { 
            x -= (x - destinationX)*.5; 
            y -= (y - destinationY)*.5; 
             
            if (Math.abs(x - destinationX) < 1 && Math.abs(y - destinationY) < 1) 
                initPos(); 
        } 
    } 
}

코드에서는 각 사과에 타임라인이 필요하지 않기 때문에 MovieClip 클래스 대신 Sprite 클래스를 사용합니다. 최상의 성능을 위해 가능하면 가장 리소스 소모가 적은 객체를 사용합니다. 다음으로 클래스는 아래 코드를 사용하여 인스턴스화됩니다.

import org.bytearray.bitmap.Apple; 
 
stage.addEventListener(MouseEvent.CLICK,createApples); 
stage.addEventListener(KeyboardEvent.KEY_DOWN,cacheApples); 
 
const MAX_NUM:int = 100; 
var apple:Apple; 
var holder:Sprite = new Sprite(); 
 
addChild(holder); 
 
function createApples(e:MouseEvent):void 
{ 
    for (var i:int = 0; i< MAX_NUM; i++) 
    { 
        apple = new Apple(); 
         
        holder.addChild(apple); 
    } 
} 
 
function cacheApples(e:KeyboardEvent):void 
{ 
    if (e.keyCode == 67) 
    { 
        var lng:int = holder.numChildren; 
         
        for (var i:int = 0; i < lng; i++) 
        { 
            apple = holder.getChildAt (i) as Apple; 
             
            apple.cacheAsBitmap = Boolean(!apple.cacheAsBitmap); 
        } 
    } 
}

사용자가 마우스를 클릭하면 사과가 캐시되지 않고 만들어집니다. 사용자가 C키(키 코드 67)를 누르면 사과 벡터가 비트맵으로 캐시되어 화면에 표시됩니다. 이 기술은 CPU가 느릴 경우 데스크톱 및 휴대 장치 모두에서 렌더링 성능을 크게 향상시킵니다.

하지만 비트맵 캐싱 기능을 사용하여 렌더링 성능이 향상되긴 해도 많은 양의 메모리가 빠르게 소모될 수 있습니다. 다음 다이어그램과 같이 객체가 캐시되는 즉시 객체의 표면이 투명 비트맵으로 캡처되어 메모리에 저장됩니다.

객체와 메모리에 저장된 객체의 표면 비트맵

Flash Player 10.1 및 AIR 2.5에서는 필터 및 동적 비트맵 언로드 에 설명된 것과 동일한 방식으로 메모리 사용을 최적화합니다. 캐시된 표시 객체가 숨겨지거나 화면에 표시되지 않는 경우 잠시 사용되지 않는 동안 메모리의 비트맵이 해제됩니다.

참고: 표시 객체의 opaqueBackground 속성이 특정 색상으로 설정되면 런타임은 표시 객체가 불투명한 것으로 간주하고, cacheAsBitmap 속성과 함께 사용되는 경우 런타임에서는 메모리에 투명하지 않은 32비트 비트맵을 만듭니다. 비트맵을 화면에 그리는 데 투명도가 필요하지 않으므로 성능 향상을 위해 알파 채널이 0xFF로 설정됩니다. 알파 블렌딩을 사용하지 않으면 렌더링이 훨씬 빨라집니다. 현재 화면 깊이가 16비트로 제한된 경우 메모리의 비트맵이 16비트 이미지로 저장됩니다. opaqueBackground 속성을 사용하더라도 비트맵 캐싱이 암시적으로 활성화되지는 않습니다.

메모리를 절약하려면 컨테이너가 아닌 각 표시 객체에서 cacheAsBitmap 속성을 사용하고 활성화합니다. 컨테이너에서 비트맵 캐싱을 활성화하면 메모리에서 최종 비트맵의 크기가 훨씬 더 커져 211 x 279 픽셀 크기의 투명 비트맵이 만들어집니다. 이미지에 약 229KB의 메모리가 사용됩니다.

전체 화면으로 그래픽 보기
컨테이너에서 비트맵 캐싱 활성화

또한 컨테이너를 캐싱하면 프레임에서 이동하는 사과가 있을 경우 메모리에서 전체 비트맵이 업데이트될 위험이 있습니다. 개별 인스턴스에서 비트맵 캐싱을 활성화하면 메모리에 7KB 표면 6개가 캐시되며 42KB의 메모리만 사용됩니다.

전체 화면으로 그래픽 보기
인스턴스에서 비트맵 캐싱 활성화

표시 목록을 통해 각 사과 인스턴스에 액세스하고 getChildAt() 메서드를 호출하면 참조가 Vector 객체에 저장되어 더 쉽게 액세스할 수 있습니다.

import org.bytearray.bitmap.Apple; 
 
stage.addEventListener(KeyboardEvent.KEY_DOWN, cacheApples); 
 
const MAX_NUM:int = 200; 
var apple:Apple; 
var holder:Sprite = new Sprite(); 
 
addChild(holder); 
 
var holderVector:Vector.<Apple> = new Vector.<Apple>(MAX_NUM, true); 
 
for (var i:int = 0; i< MAX_NUM; i++) 
{ 
    apple = new Apple(); 
     
    holder.addChild(apple); 
     
    holderVector[i] = apple; 
} 
 
function cacheApples(e:KeyboardEvent):void 
{ 
    if (e.keyCode == 67) 
    { 
        var lng:int = holderVector.length 
         
        for (var i:int = 0; i < lng; i++) 
        { 
            apple = holderVector[i]; 
             
            apple.cacheAsBitmap = Boolean(!apple.cacheAsBitmap); 
        } 
    } 
}

비트맵 캐싱은 캐시된 내용이 각 프레임에서 회전, 크기 조절 또는 변경되지 않는 경우에 렌더링을 향상시킵니다. 하지만 x축 및 y축 평행 이동이 아닌 변환의 경우 렌더링이 향상되지 않습니다. 이러한 경우 Flash Player에서는 표시 객체에서 발생하는 모든 변형의 캐시된 비트맵 복사본을 업데이트합니다. 캐시된 복사본을 업데이트하면 CPU 사용이 증가되고 성능이 저하되며 배터리 사용이 늘어날 수 있습니다. 다시 한 번 말하지만 AIR 또는 Packager for iPhone의 cacheAsBitmapMatrix 속성에는 이러한 제한이 없습니다.

다음 코드에서는 이동 메서드의 알파 값을 변경하며 이로 인해 모든 프레임에서 사과의 불투명도가 변경됩니다.

private function handleMovement(e:Event):void  
{ 
        alpha = Math.random(); 
        x -= (x - destinationX)*.5; 
        y -= (y - destinationY)*.5; 
             
        if (Math.abs(x - destinationX) < 1 && Math.abs(y - destinationY) < 1) 
            initPos(); 
}

비트맵 캐싱을 사용하면 성능이 저하될 수 있습니다. 알파 값을 변경하면 알파 값이 수정될 때마다 메모리에서 캐시된 비트맵이 강제로 업데이트됩니다.

캐시된 동영상 클립의 재생 헤드가 이동할 때마다 업데이트되는 비트맵이 필터에 사용됩니다. 따라서 필터를 사용하면 cacheAsBitmap 속성이 true 로 자동 설정됩니다. 다음 그림에서는 애니메이션이 적용된 동영상 클립을 보여 줍니다.

애니메이션이 적용된 동영상 클립

필터를 사용하면 성능 문제가 발생할 수 있으므로 애니메이션이 적용된 내용에는 필터를 사용하지 않습니다. 다음 그림에서 디자이너는 그림자 필터를 추가합니다.

그림자 필터로 애니메이션이 적용된 동영상 클립

따라서 동영상 클립 내의 타임라인이 재생 중인 경우 비트맵이 다시 생성되어야 합니다. 또한 단순 x 또는 y 변형 이외의 방식으로 내용이 수정되는 경우에도 비트맵이 다시 생성되어야 합니다. 각 프레임에서는 비트맵이 강제로 다시 그려지는데, 이로 인해 필요한 CPU 리소스가 늘어나고 성능이 저하되며 배터리가 더 많이 소모됩니다.

다음 교육 비디오에서는 Paul Trani가 Flash Professional 및 ActionScript를 통해 비트맵이 사용된 그래픽을 최적화하는 예를 보여 줍니다.