Why doesn’t ID2D1PathGeometry release resources? SafeRelease not working

  2d, c++, direct2d, rendering, winapi

Each frame is created and some kind of texture is destroyed.
All this happens if you use it once
ID2D1RenderTarget-> FillGeometry

Example experiment:

#include "windows.h"
#include <d2d1.h>
#include <wrl.h>
using Microsoft::WRL::ComPtr;
template <class T> void SafeRelease(T **ppT){
    if (*ppT){
        (*ppT)->Release();
        *ppT = NULL;
    }
}

HWND windowHandle;
ID2D1Factory *d2Factory;
ID2D1HwndRenderTarget *renderTarget;

ID2D1Bitmap* geometryCache = nullptr;

ID2D1Bitmap* createBitmapImage(ID2D1BitmapRenderTarget* render);

void createScene(){
    D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, &d2Factory);
    d2Factory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(),D2D1::HwndRenderTargetProperties(windowHandle, D2D1::SizeU(640, 480)),&renderTarget);

    ID2D1BitmapRenderTarget* cacheRender = nullptr;

    renderTarget->CreateCompatibleRenderTarget(D2D1::SizeF(200, 200),&cacheRender);
    geometryCache = createBitmapImage(cacheRender);
}

ID2D1Bitmap* createBitmapImage(ID2D1BitmapRenderTarget* render){
    ID2D1Bitmap* result = nullptr;
    ID2D1PathGeometry* geometry;
    ID2D1GeometrySink* sink;
    ID2D1SolidColorBrush* fillColor = nullptr;
    render->CreateSolidColorBrush(D2D1_COLOR_F(0.0f,0.0f,0.0f,1.0f),&fillColor);
    d2Factory->CreatePathGeometry(&geometry);

    geometry->Open(&sink);
    sink->SetFillMode(D2D1_FILL_MODE_WINDING);

    sink->BeginFigure(D2D1::Point2F(22, 22),D2D1_FIGURE_BEGIN_FILLED);
    sink->AddArc(
        D2D1::ArcSegment(
            D2D1::Point2F(100,100),
            D2D1::SizeF(42, 42),
            0.0f, 
            D2D1_SWEEP_DIRECTION_CLOCKWISE,
            D2D1_ARC_SIZE_SMALL
        )
    );            
    sink->EndFigure(D2D1_FIGURE_END_CLOSED);
    sink->Close();
    SafeRelease(&sink);

    render->BeginDraw();
    render->FillGeometry(geometry,fillColor);
    render->EndDraw();
    render->GetBitmap(&result);
    

    SafeRelease(&render);
    SafeRelease(&geometry);
    SafeRelease(&fillColor);

    return result;
}
LRESULT CALLBACK MessageRouter(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_PAINT:{
            renderTarget->BeginDraw();
            renderTarget->Clear(D2D1_COLOR_F(1.0f,1.0f,1.0f,1.0f));
            renderTarget->DrawBitmap(geometryCache,D2D1_RECT_F(0,0,200,200), 1.0f, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,D2D1_RECT_F(0,0,200,200));
            renderTarget->EndDraw();
            break;
        }
        case WM_SIZE: {
            if (renderTarget){
                renderTarget->Resize(D2D1_SIZE_U( LOWORD(lParam),HIWORD(lParam)));
            }
            break;
        }
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, msg, wParam, lParam);
        }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}

int main(int x, char *y[]) {
    WNDCLASSEXW windowClass = {0};
    windowClass.cbSize = sizeof(WNDCLASSEX);
    windowClass.hbrBackground = NULL;
    windowClass.hInstance = NULL;
    windowClass.hCursor = LoadCursor(nullptr, IDC_ARROW);
    windowClass.lpfnWndProc = MessageRouter;
    windowClass.lpszClassName = L"hw";
    windowClass.lpszMenuName  = NULL;
    windowClass.style = CS_HREDRAW | CS_VREDRAW;
    RegisterClassExW(&windowClass);

    windowHandle = CreateWindowExA(
        WS_EX_LEFT,
        "HW",NULL,
        WS_OVERLAPPEDWINDOW,
        300,300,
        640,480,
        NULL,NULL,NULL,NULL);

    ShowWindow(windowHandle, SW_RESTORE);
    createScene();
    UpdateWindow(windowHandle);
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
    }
    return 0;
}

Even after I cached the geometry and freed up resources.
ID3D11DeviceContext1 :: DiscardResource is called all subsequent frames

RenderDoc frame events

Can I avoid this?

Source: Windows Questions C++

LEAVE A COMMENT