2017-03-09 12 views
1

상당히 복잡한 (메모리가 많은) 많은 항목이 있는데 제한된 RAM에 맞추기 위해 일부를 텍스처에 캐시하고 실제 복잡한 항목을 메모리에 보관하지 않습니다. 특히 내가하고 싶은 항목은 현재 애니메이션을 적용 할 필요가없는 모든 항목 (내 복잡한 항목 중에서)입니다 (그리고 대부분의 항목을 의미 함). 이 질문의 목적을 위해이 항목을 "비활성"이라고합니다.복잡한 항목을 텍스처에 캐시하고 실제 복잡한 항목의 메모리를 해제하는 방법은 무엇입니까?

내 계획이었다 : live: false; source: foo으로 (더 ShaderEffect를 관련과)

  • foo에 의해 점유 된 것과 동일한 사각형에 동적으로 ShaderEffectSource를 작성하지 :

    • 항목 "푸"비활성화 될 때 . ShaderEffectSource 업데이트가되는 ShaderEffectSource
    • 전화 scheduleUpdate(),이 계획의 문제점 foo

destroy()를 호출하면 "를 ShaderEffectSource가 업데이트된다"일 함께 : 없음이 일어날 때 알려주는 신호. scheduleUpdate()이 다음 프레임에 대한 업데이트 을 예약한다는 사실 (the docs)을 사용할 수 있습니다. 그래서 아마 이런 식으로 뭔가를 보이는 Timer을 시작할 것 :

== 2 체크 우리는 (예약 된 업데이트가 이미 일어난 것을 보장하지 않는) 다음 프레임에 도달하지했는지 확인하는 것입니다
Timer { 
    interval: 1 // 1ms interval meaning "fire every frame" 
    property int timesTriggered: 0 
    repeat: true 
    running: false 

    onTriggered: { 
     timesTriggered++; 
     if(timesTriggered == 2) { 
      complexItem.destroy(); 
      running = false; 
     } 
    } 
} 

그러나 그 후 프레임에 도달했습니다.

하지만 그 방법은 해킹입니다. 해킹이 아닌 접근 방법이 있습니까? 당신이 QQuickRenderControl를 사용할 필요가 같은

+0

프레임 당 60fps ~ 16.67ms가 맞지 않습니까? 그래서 나는'간격 : 1'이 꽤 하드 코어라고 생각합니다. – derM

+0

실제 프레임 속도와 동기화하거나 다음 렌더링 루프에서 호출을 예약하는 좋은 방법이 있습니다. – dtech

+0

@derM : QML 타이머 트리거가 렌더 루프와 "동기화"되어 있으므로 높은 빈도를 요청하더라도 장면 새로 고침 속도보다 빠르게 발생하지 않습니다. 그래서 내가 먼저 가서 "1ms"를 선택했습니다. –

답변

0

어쩌면 당신은 grabToImage

import QtQuick 2.7 
import QtQuick.Controls 2.0 

import QtQuick 2.7 
import QtQuick.Controls 2.0 

ApplicationWindow { 
    id: appWindow 
    width: 1024 
    height: 800 
    visible: true 
    Button { 
     y: 410 
     text: 'run ' + counter 
     onClicked: foo() 
    } 
    property int counter: 0 

    function foo() { 
     counter++ 
     gc() 
     var c = test.createObject(appWindow) 
     c.grabToImage(function(result) { 
      if (image.result) {    // <-- Delete what is possible 
       image.result.image.destroy() 
       image.result.destroy() 
      } 
      image.result = result 
     }, Qt.size(400, 400)) 
     c.destroy() 
    } 

    Image { 
     id: image 
     width: 400 
     height: 400 
     x: 100 
     property var result 
     source: result ? result.url : '' 
     onSourceChanged: foo() 
    } 

    Component { 
     id: test 
     Grid { 
      width: 400 
      height: 400 
      columns: 40 
      rows: 40 
      Repeater { 
       model: 40 * 40 
       delegate: Rectangle { 
        width: 10 
        height: 10 
        color: 'green' // <--- don't always create a new color 
       } 
      } 
      Component.onCompleted: console.log('Created') 
      Component.onDestruction: console.log('Destroyed') 
     } 
    } 
} 
+0

고맙지 만 grabToImage 문서에서이 정보를 고려하십시오. "이 함수는 항목을 오프 스크린 표면에 렌더링하고 그 표면을 GPU의 메모리에서 CPU의 메모리로 복사하므로 비용이 많이 듭니다." 가능하다면이 비용을 피하고 싶습니다. OTOH 항목이 "활성"을 멈추었을 때 스냅 샷을 작성하고 즉시 삭제하는 것이 시급한 일이 아니므로'grabToImage'가 나를 위해 작동 할 수 있습니다. 특히 비동기로 보일 수 있습니다. 시도해 볼게. –

+0

메모리를 지우는 해결책을 찾지 못했기 때문에 매우 나쁜 솔루션 일 수 있음을 인정해야합니다. * 복잡한 객체 *의 메모리는 해제되지만'grabToImage'의 결과는 내 puring gc() 또는 다른 어떤 것에서도 빠져 나간다. 그래서 주어진 예에서, 나는 앱이 실행될 때까지 7-8 실행을 관리한다. of memory ' – derM

+0

네, 빠른 테스트를 위해 200x200 격자를 20x20으로 변경했습니다. 반복적으로 "실행"버튼을 클릭하면 일반적으로 메모리 사용량이 증가했습니다. 종종 동일하게 머무르거나 내려 갔지만 전반적인 경향이 나타났습니다. 'c.destroy();'뒤에'gc()'를 추가했을 때조차도. 기묘한. 이 미묘한 덫에 대해 알려 줘서 고마워. –

1

와 함께 할 수있는 소리. 나는 아직 내 시간이 없었어요,하지만 문서에서 그것은 당신이 필요로 정확히 같은 소리 :

QQuickRenderControl 클래스는 렌더 타겟, 오프 스크린 위에 Qt는 빠른 장면 그래프 렌더링 하는 메커니즘을 제공합니다 완전히 응용 프로그램 제어 방식으로.

QQuickWindow와 QQuickView 및 관련 내부 렌더링 루프 Qt 빠른 장면을 기본 창에 렌더링합니다. 경우에 따라 타사 OpenGL 렌더러와 통합 할 때 예제의 경우 외부 렌더링 엔진에 의한 임의의 방법으로 에서 사용할 수있는 텍스처로 장면을 가져 오는 것이 유용 할 수 있습니다 ( ).QQuickRenderControl 는 QQuickWindow를 사용 심하고 한정 대안 달리 하드웨어 가속 방식으로 가능이 만드는 :: grabWindow을 QQuickRenderControl 사용시()

상기 QQuickWindow가 도시 또는 심지어 수없는 전혀 만들어 .. 컨텍스트와 프레임 버퍼 오브젝트의

관리가 응용 프로그램까지 입니다 ...

QQuickRenderControl의 도입 이전에 비슷한 것을 달성하는 몇 가지 방법이 있었지만 프로세스에 많은 편의를 제공합니다. 텍스처는 RAM에서 VRAM으로 VRAM을 가로 지르지 않아도되며, 유효 기간을 완전히 제어 할 수 있으므로 QQuickItem을 구현할 수 있으므로 기본적으로 효율적인 SG API를 사용하여 텍스처를 그립니다.

+0

나는 그것이 좋은 에스컬레이션 사다리를 만든다고 생각한다 : 1) 귀찮게하지 마라. 2) grabToImage (더 단순 해 보인다.), 3) 아무것도 도움이되지 않으면 QQuickRenderControl. 그것은 내가 세계를 끝내기 위해 반드시 뛰어 들어야 할 무언가입니다! 감사. – derM